8c46b8a38c01177ca70453b29cb0564768e73431
[platform/core/uifw/dali-demo.git] / examples / video-view / video-view-example.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <dali/dali.h>
19 #include <dali-toolkit/dali-toolkit.h>
20
21 using namespace Dali;
22 using namespace Toolkit;
23
24 namespace
25 {
26   const int SEEK_POS( 5000 );
27   const int INIT_WIDTH( 600 );
28   const int INIT_HEIGHT( 400 );
29   const int BUTTON_SIZE( 80 );
30
31   const char* const PLAY_FILE = DEMO_VIDEO_DIR "big_buck_bunny.mp4";
32   const char* const PLAY_IMAGE = DEMO_IMAGE_DIR "icon-play.png";
33   const char* const PAUSE_IMAGE = DEMO_IMAGE_DIR "Pause.png";
34   const char* const STOP_IMAGE = DEMO_IMAGE_DIR "icon-stop.png";
35   const char* const RESET_IMAGE = DEMO_IMAGE_DIR "icon-reset.png";
36   const char* const FORWARD_IMAGE = DEMO_IMAGE_DIR "Forward.png";
37   const char* const BACKWARD_IMAGE = DEMO_IMAGE_DIR "Backward.png";
38
39 const char* DEFAULT_FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
40   varying mediump vec2 vTexCoord;\n
41   uniform sampler2D sTexture;\n
42   uniform lowp vec4 uColor;\n
43   \n
44   void main()\n
45   {\n
46     gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
47   }\n
48 );
49
50 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
51   precision mediump float;
52   varying mediump vec2 vTexCoord;\n
53   uniform sampler2D sTexture;\n
54   uniform lowp vec4 uColor;\n
55   \n
56   void main()\n
57   {\n
58     vec2 st = vTexCoord.st;\n
59     vec3 irgb = texture2D( sTexture, st ).rgb;\n
60     vec3 negative = vec3( 1., 1., 1. ) - irgb;\n
61     gl_FragColor = vec4( mix( irgb, negative, 1.0), 1. ) * uColor;\n
62   }\n
63 );
64
65 }  // namespace
66
67 class VideoViewController: public ConnectionTracker
68 {
69  public:
70
71   VideoViewController( Application& application )
72     : mApplication( application ),
73       mIsPlay( false ),
74       mIsStop( false ),
75       mIsFullScreen( false ),
76       mSetCustomShader( false ),
77       mScale( 1.f )
78   {
79     // Connect to the Application's Init signal
80     mApplication.InitSignal().Connect( this, &VideoViewController::Create );
81   }
82
83   ~VideoViewController()
84   {
85     mVideoView.Stop();
86   }
87
88   void Create( Application& application )
89   {
90     mStageSize = Stage::GetCurrent().GetSize();
91
92     mVideoView = Toolkit::VideoView::New();
93     Stage::GetCurrent().Add( mVideoView );
94     mVideoView.SetParentOrigin( ParentOrigin::CENTER );
95     mVideoView.SetAnchorPoint( AnchorPoint::CENTER );
96     mVideoView.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
97     mVideoView.SetSize( INIT_WIDTH, INIT_HEIGHT );
98     mVideoView.SetProperty( VideoView::Property::LOOPING, true );
99     mVideoView.SetProperty( VideoView::Property::MUTED, false );
100     mVideoView.SetProperty( VideoView::Property::VIDEO, PLAY_FILE );
101
102     mMenu = Layer::New();
103     mMenu.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
104     mMenu.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
105     mMenu.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
106     mMenu.SetSize( INIT_WIDTH, 120 );
107     mVideoView.Add( mMenu );
108
109     mPlayButton = PushButton::New();
110     mPlayButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
111     mPlayButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
112     mPlayButton.SetName( "Play" );
113     mPlayButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
114     mPlayButton.SetSize( BUTTON_SIZE, BUTTON_SIZE );
115     mPlayButton.SetPosition( 40, 10 );
116     mPlayButton.ClickedSignal().Connect( this, &VideoViewController::OnButtonClicked );
117
118     mPauseButton = PushButton::New();
119     mPauseButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
120     mPauseButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
121     mPauseButton.SetName( "Pause" );
122     mPauseButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
123     mPauseButton.SetSize( BUTTON_SIZE, BUTTON_SIZE );
124     mPauseButton.SetPosition( 40, 10 );
125     mPauseButton.ClickedSignal().Connect( this, &VideoViewController::OnButtonClicked );
126
127     mStopButton = PushButton::New();
128     mStopButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
129     mStopButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
130     mStopButton.SetName( "Stop" );
131     mStopButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
132     mStopButton.SetSize( BUTTON_SIZE, BUTTON_SIZE );
133     mStopButton.SetPosition( 140, 10 );
134     mStopButton.ClickedSignal().Connect( this, &VideoViewController::OnButtonClicked );
135
136     mResetButton = PushButton::New();
137     mResetButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
138     mResetButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
139     mResetButton.SetName( "Reset" );
140     mResetButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
141     mResetButton.SetSize( BUTTON_SIZE, BUTTON_SIZE );
142     mResetButton.SetPosition( 140, 10 );
143     mResetButton.ClickedSignal().Connect( this, &VideoViewController::OnButtonClicked );
144
145     mBackwardButton = PushButton::New();
146     mBackwardButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
147     mBackwardButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
148     mBackwardButton.SetName( "Backward" );
149     mBackwardButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
150     mBackwardButton.SetSize( BUTTON_SIZE, BUTTON_SIZE );
151     mBackwardButton.SetPosition( 240, 10 );
152     mBackwardButton.ClickedSignal().Connect( this, &VideoViewController::OnButtonClicked );
153
154     mForwardButton = PushButton::New();
155     mForwardButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
156     mForwardButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
157     mForwardButton.SetName( "Forward" );
158     mForwardButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
159     mForwardButton.SetSize( BUTTON_SIZE, BUTTON_SIZE );
160     mForwardButton.SetPosition( 340, 10 );
161     mForwardButton.ClickedSignal().Connect( this, &VideoViewController::OnButtonClicked );
162
163     mMenu.Add( mPlayButton );
164     mMenu.Add( mPauseButton );
165     mMenu.Add( mStopButton );
166     mMenu.Add( mResetButton );
167     mMenu.Add( mBackwardButton );
168     mMenu.Add( mForwardButton );
169
170     mPauseButton.SetVisible( false );
171     mPauseButton.SetDisabled( true );
172     mPlayButton.SetVisible( true );
173     mPlayButton.SetDisabled( false );
174     mStopButton.SetVisible( true );
175     mStopButton.SetDisabled( false );
176     mResetButton.SetVisible( false );
177     mResetButton.SetDisabled( true );
178
179     mPlayButton.SetUnselectedImage( PLAY_IMAGE );
180     mPlayButton.SetSelectedImage( PLAY_IMAGE );
181     mPauseButton.SetUnselectedImage( PAUSE_IMAGE );
182     mPauseButton.SetSelectedImage( PAUSE_IMAGE );
183
184     mStopButton.SetUnselectedImage( STOP_IMAGE );
185     mStopButton.SetSelectedImage( STOP_IMAGE );
186     mResetButton.SetUnselectedImage( RESET_IMAGE );
187     mResetButton.SetSelectedImage( RESET_IMAGE );
188
189     mBackwardButton.SetUnselectedImage( BACKWARD_IMAGE );
190     mBackwardButton.SetSelectedImage( BACKWARD_IMAGE );
191     mForwardButton.SetUnselectedImage( FORWARD_IMAGE );
192     mForwardButton.SetSelectedImage( FORWARD_IMAGE );
193
194     mPanGestureDetector = PanGestureDetector::New();
195     mPanGestureDetector.Attach( mVideoView );
196     mPanGestureDetector.DetectedSignal().Connect( this, &VideoViewController::OnPan );
197
198     mPinchGestureDetector = PinchGestureDetector::New();
199     mPinchGestureDetector.Attach( mVideoView );
200     mPinchGestureDetector.DetectedSignal().Connect( this, &VideoViewController::OnPinch );
201
202     mTapGestureDetector = TapGestureDetector::New();
203     mTapGestureDetector.Attach( mVideoView );
204     mTapGestureDetector.DetectedSignal().Connect( this, &VideoViewController::OnTap );
205
206     mRotationAnimation = Animation::New(2.f);
207     mRotationAnimation.AnimateBy( Property(mVideoView, Actor::Property::ORIENTATION), Quaternion(Degree(0.f), Degree(360.f), Degree(0.f)) );
208     mRotationAnimation.SetLooping(false);
209
210     Stage::GetCurrent().KeyEventSignal().Connect( this, &VideoViewController::OnKeyEvent );
211
212     Property::Map customShader;
213     customShader.Insert( "fragmentShader", FRAGMENT_SHADER );
214     mCustomShader.Insert( "rendererType", "IMAGE" );
215     mCustomShader.Insert( "shader", customShader );
216
217     Property::Map defaultShader;
218     customShader.Insert( "fragmentShader", DEFAULT_FRAGMENT_SHADER );
219     mDefaultShader.Insert( "rendererType", "IMAGE" );
220     mDefaultShader.Insert( "shader", defaultShader );
221
222     mWindowSurfaceTarget.Insert( "RENDERING_TARGET", "windowSurfaceTarget" );
223     mNativeImageTarget.Insert( "RENDERING_TARGET", "nativeImageTarget" );
224
225     mVideoView.FinishedSignal().Connect( this, &VideoViewController::OnFinished );
226   }
227
228   bool OnButtonClicked( Button button )
229   {
230
231     if( mPauseButton.GetId() == button.GetId())
232     {
233        if( mIsPlay )
234       {
235         mPauseButton.SetVisible( false );
236         mPauseButton.SetDisabled( true );
237         mPlayButton.SetVisible( true );
238         mPlayButton.SetDisabled( false );
239
240         mIsPlay = false;
241         mVideoView.Pause();
242       }
243     }
244     else if( mPlayButton.GetId() == button.GetId())
245     {
246       if( mIsStop )
247       {
248         return false;
249       }
250
251       mPauseButton.SetVisible( true );
252       mPauseButton.SetDisabled( false );
253       mPlayButton.SetVisible( false );
254       mPlayButton.SetDisabled( true );
255
256       mIsPlay = true;
257       mVideoView.Play();
258     }
259     else if( mResetButton.GetId() == button.GetId())
260     {
261       if( mIsStop )
262       {
263         mPauseButton.SetVisible( true );
264         mPauseButton.SetDisabled( false );
265         mPlayButton.SetVisible( false );
266         mPlayButton.SetDisabled( true );
267         mResetButton.SetVisible( false );
268         mResetButton.SetDisabled( true );
269         mStopButton.SetVisible( true );
270         mStopButton.SetDisabled( false );
271
272         mIsStop = false;
273         mIsPlay = true;
274         mVideoView.SetProperty( VideoView::Property::VIDEO, PLAY_FILE );
275         mVideoView.Play();
276       }
277     }
278     else if( mStopButton.GetId() == button.GetId())
279     {
280       mPauseButton.SetVisible( false );
281       mPauseButton.SetDisabled( true );
282       mPlayButton.SetVisible( true );
283       mPlayButton.SetDisabled( false );
284       mResetButton.SetVisible( true );
285       mResetButton.SetDisabled( false );
286       mStopButton.SetVisible( false );
287       mStopButton.SetDisabled( true );
288
289       mIsStop = true;
290       mVideoView.Stop();
291     }
292     else if( mBackwardButton.GetId() == button.GetId())
293     {
294       mVideoView.Backward( SEEK_POS );
295     }
296     else if( mForwardButton.GetId() == button.GetId())
297     {
298       mVideoView.Forward( SEEK_POS );
299     }
300
301     return true;
302   }
303
304   void OnFinished( VideoView& view )
305   {
306     if( !mIsFullScreen )
307     {
308       mRotationAnimation.Play();
309       mIsStop = true;
310     }
311   }
312
313   void OnPan( Actor actor, const PanGesture& gesture )
314   {
315     if( !mIsFullScreen && gesture.state == Gesture::Continuing )
316     {
317       mVideoView.TranslateBy( Vector3( gesture.displacement ) );
318     }
319   }
320
321   void OnPinch( Actor actor, const PinchGesture& gesture )
322   {
323     if( gesture.state == Gesture::Started )
324     {
325       mPinchStartScale = mScale;
326     }
327
328     if( gesture.state == Gesture::Finished )
329     {
330       mScale = mPinchStartScale * gesture.scale;
331       if( mScale > 1.f )
332       {
333         mVideoView.SetSize( mStageSize.x, mStageSize.y );
334         mVideoView.SetProperty( VideoView::Property::VIDEO, mWindowSurfaceTarget );
335         mMenu.SetSize( mStageSize.x, 120 );
336         mIsFullScreen = true;
337       }
338       else
339       {
340         mVideoView.SetSize( INIT_WIDTH, INIT_HEIGHT );
341         mVideoView.SetProperty( VideoView::Property::VIDEO, mNativeImageTarget );
342         mMenu.SetSize( INIT_WIDTH, 120 );
343         mIsFullScreen = false;
344       }
345     }
346   }
347
348   void OnTap( Actor actor, const TapGesture& tapGesture )
349   {
350     if( !mIsFullScreen )
351     {
352       mRotationAnimation.Play();
353
354       if( mSetCustomShader )
355       {
356         mSetCustomShader = false;
357         mVideoView.SetProperty( VideoView::Property::VIDEO, mDefaultShader );
358       }
359       else
360       {
361         mSetCustomShader = true;
362         mVideoView.SetProperty( VideoView::Property::VIDEO, mCustomShader );
363       }
364     }
365   }
366
367 private:
368
369   /**
370    * Main key event handler
371    */
372   void OnKeyEvent(const KeyEvent& event)
373   {
374     if(event.state == KeyEvent::Down)
375     {
376       if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
377       {
378         mApplication.Quit();
379       }
380     }
381   }
382
383 private:
384   Application&  mApplication;
385   VideoView mVideoView;
386   Layer mMenu;
387   Vector2 mStageSize;
388
389   bool mIsPlay;
390   bool mIsStop;
391   bool mIsFullScreen;
392   bool mSetCustomShader;
393
394   PushButton mPlayButton;
395   PushButton mPauseButton;
396   PushButton mStopButton;
397   PushButton mResetButton;
398   PushButton mBackwardButton;
399   PushButton mForwardButton;
400
401   PanGestureDetector mPanGestureDetector;
402   PinchGestureDetector mPinchGestureDetector;
403   TapGestureDetector mTapGestureDetector;
404   float mScale;
405   float mPinchStartScale;
406
407   Animation mRotationAnimation;
408   Property::Map mCustomShader;
409   Property::Map mDefaultShader;
410   Property::Map mWindowSurfaceTarget;
411   Property::Map mNativeImageTarget;
412 };
413
414 void RunTest( Application& application )
415 {
416   VideoViewController test( application );
417
418   application.MainLoop();
419 }
420
421 // Entry point for Linux & Tizen applications
422 //
423 int DALI_EXPORT_API main( int argc, char **argv )
424 {
425   Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
426
427   RunTest( application );
428
429   return 0;
430 }