Internalized VisualFactory::InitializeVisual templates
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / video-view / video-view-impl.cpp
1 /*
2  * Copyright (c) 2016 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 // CLASS HEADER
19 #include "video-view-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <cstring>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/public-api/object/type-registry-helper.h>
25 #include <dali/public-api/common/stage.h>
26 #include <dali/devel-api/scripting/scripting.h>
27 #include <dali/public-api/adaptor-framework/native-image-source.h>
28 #include <dali/integration-api/adaptors/adaptor.h>
29
30 // INTERNAL INCLUDES
31 #include <dali-toolkit/public-api/controls/video-view/video-view.h>
32 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
33
34 namespace Dali
35 {
36
37 namespace Toolkit
38 {
39
40 namespace Internal
41 {
42
43 namespace
44 {
45
46 BaseHandle Create()
47 {
48   return Toolkit::VideoView::New();
49 }
50
51 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::VideoView, Toolkit::Control, Create );
52
53 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "video", MAP, VIDEO )
54 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "looping", BOOLEAN, LOOPING )
55 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "muted", BOOLEAN, MUTED )
56 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "volume", MAP, VOLUME )
57
58 DALI_SIGNAL_REGISTRATION( Toolkit, VideoView, "finished", FINISHED_SIGNAL )
59
60 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "play", ACTION_VIDEOVIEW_PLAY )
61 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "pause", ACTION_VIDEOVIEW_PAUSE )
62 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "stop", ACTION_VIDEOVIEW_STOP )
63 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "forward", ACTION_VIDEOVIEW_FORWARD )
64 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "backward", ACTION_VIDEOVIEW_BACKWARD )
65
66 DALI_TYPE_REGISTRATION_END()
67
68 const char* const VOLUME_LEFT( "volumeLeft" );
69 const char* const VOLUME_RIGHT( "volumeRight" );
70 const char* const RENDERING_TARGET( "RENDERING_TARGET" );
71 const char* const WINDOW_SURFACE_TARGET( "windowSurfaceTarget" );
72 const char* const NATIVE_IMAGE_TARGET( "nativeImageTarget" );
73
74 } // anonymous namepsace
75
76 VideoView::VideoView()
77 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS ) ),
78   mCurrentVideoPlayPosition( 0 ),
79   mSetRenderingTarget( false ),
80   mIsPlay( false ),
81   mIsPause( false )
82 {
83   mVideoPlayer = Dali::VideoPlayer::New();
84 }
85
86 VideoView::~VideoView()
87 {
88 }
89
90 Toolkit::VideoView VideoView::New()
91 {
92   VideoView* impl = new VideoView();
93   Toolkit::VideoView handle = Toolkit::VideoView( *impl );
94
95   impl->Initialize();
96
97   return handle;
98 }
99
100 void VideoView::SetUrl( const std::string& url )
101 {
102   if( mUrl != url || !mPropertyMap.Empty() )
103   {
104     mPropertyMap.Clear();
105
106     mUrl = url;
107   }
108
109   if( mSetRenderingTarget )
110   {
111     mVideoPlayer.SetUrl( mUrl );
112   }
113   else
114   {
115     SetNativeImageTarget();
116   }
117 }
118
119 void VideoView::SetPropertyMap( Property::Map map )
120 {
121   mPropertyMap = map;
122
123   Actor self( Self() );
124   Internal::InitializeVisual( self, mVisual, mPropertyMap );
125
126   Property::Value* widthValue = mPropertyMap.Find( "width" );
127   if( widthValue )
128   {
129     int width;
130     if( widthValue->Get( width ) )
131     {
132       mVideoSize = ImageDimensions( width, mVideoSize.GetHeight() );
133     }
134   }
135
136   Property::Value* heightValue = mPropertyMap.Find( "height" );
137   if( heightValue )
138   {
139     int height;
140     if( heightValue->Get( height ) )
141     {
142       mVideoSize = ImageDimensions( mVideoSize.GetWidth(), height );
143     }
144   }
145
146   RelayoutRequest();
147 }
148
149 std::string VideoView::GetUrl()
150 {
151   return mUrl;
152 }
153
154 void VideoView::SetLooping(bool looping)
155 {
156   mVideoPlayer.SetLooping( looping );
157 }
158
159 bool VideoView::IsLooping()
160 {
161   return mVideoPlayer.IsLooping();
162 }
163
164 void VideoView::Play()
165 {
166   mVideoPlayer.Play();
167   mIsPlay = true;
168   mIsPause = false;
169 }
170
171 void VideoView::Pause()
172 {
173   mVideoPlayer.Pause();
174   mIsPlay = false;
175   mIsPause = true;
176 }
177
178 void VideoView::Stop()
179 {
180   mVideoPlayer.Stop();
181   mIsPlay = false;
182   mIsPause = false;
183 }
184
185 void VideoView::Forward( int millisecond )
186 {
187   int curPos = mVideoPlayer.GetPlayPosition();
188
189   int nextPos = curPos + millisecond;
190
191   mVideoPlayer.SetPlayPosition( nextPos );
192 }
193
194 void VideoView::Backward( int millisecond )
195 {
196   int curPos = mVideoPlayer.GetPlayPosition();
197
198   int nextPos = curPos - millisecond;
199   nextPos = ( nextPos < 0 )? 0: nextPos;
200
201   mVideoPlayer.SetPlayPosition( nextPos );
202 }
203
204 void VideoView::SetMute( bool mute )
205 {
206   mVideoPlayer.SetMute( mute );
207 }
208
209 bool VideoView::IsMuted()
210 {
211   return mVideoPlayer.IsMuted();
212 }
213
214 void VideoView::SetVolume( float left, float right )
215 {
216   mVideoPlayer.SetVolume( left, right );
217 }
218
219 void VideoView::GetVolume( float& left, float& right )
220 {
221   mVideoPlayer.GetVolume( left, right );
222 }
223
224 Dali::Toolkit::VideoView::VideoViewSignalType& VideoView::FinishedSignal()
225 {
226   return mFinishedSignal;
227 }
228
229 void VideoView::EmitSignalFinish()
230 {
231   if ( !mFinishedSignal.Empty() )
232   {
233     Dali::Toolkit::VideoView handle( GetOwner() );
234     mFinishedSignal.Emit( handle );
235   }
236 }
237
238 bool VideoView::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
239 {
240   bool ret = false;
241
242   Dali::BaseHandle handle( object );
243   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle );
244
245   if( !videoView )
246   {
247     return ret;
248   }
249
250   VideoView& impl = GetImpl( videoView );
251
252   if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PLAY ) == 0 )
253   {
254     impl.Play();
255     ret = true;
256   }
257   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PAUSE ) == 0 )
258   {
259     impl.Pause();
260     ret = true;
261   }
262   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_STOP ) == 0 )
263   {
264     impl.Stop();
265     ret = true;
266   }
267   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_FORWARD ) == 0 )
268   {
269     int millisecond = 0;
270     if( attributes["videoForward"].Get( millisecond ) )
271     {
272       impl.Forward( millisecond );
273       ret = true;
274     }
275   }
276   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_BACKWARD ) == 0 )
277   {
278     int millisecond = 0;
279     if( attributes["videoBackward"].Get( millisecond ) )
280     {
281       impl.Backward( millisecond );
282       ret = true;
283     }
284   }
285
286   return ret;
287 }
288
289 bool VideoView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
290 {
291   Dali::BaseHandle handle( object );
292
293   bool connected( true );
294   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle );
295
296   if( 0 == strcmp( signalName.c_str(), FINISHED_SIGNAL ) )
297   {
298     videoView.FinishedSignal().Connect( tracker, functor );
299   }
300   else
301   {
302     // signalName does not match any signal
303     connected = false;
304   }
305
306   return connected;
307 }
308
309 void VideoView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
310 {
311   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) );
312
313   if( videoView )
314   {
315     VideoView& impl = GetImpl( videoView );
316
317     switch( index )
318     {
319       case Toolkit::VideoView::Property::VIDEO:
320       {
321         std::string videoUrl;
322         if( value.Get( videoUrl ) )
323         {
324           impl.SetUrl( videoUrl );
325         }
326
327         Property::Map map;
328         if( value.Get( map ) )
329         {
330           impl.SetPropertyMap( map );
331
332           Property::Value* target = map.Find( RENDERING_TARGET );
333           std::string targetType;
334           if( target && target->Get( targetType ) && targetType == WINDOW_SURFACE_TARGET )
335           {
336             impl.SetWindowSurfaceTarget();
337           }
338           else if( target && target->Get( targetType ) && targetType == NATIVE_IMAGE_TARGET )
339           {
340             impl.SetNativeImageTarget();
341           }
342         }
343         break;
344       }
345       case Toolkit::VideoView::Property::LOOPING:
346       {
347         bool looping;
348         if( value.Get( looping ) )
349         {
350           impl.SetLooping( looping );
351         }
352         break;
353       }
354       case Toolkit::VideoView::Property::MUTED:
355       {
356         bool mute;
357         if( value.Get( mute ) )
358         {
359           impl.SetMute( mute );
360         }
361         break;
362       }
363       case Toolkit::VideoView::Property::VOLUME:
364       {
365         Property::Map map;
366         float left, right;
367         if( value.Get( map ) )
368         {
369           Property::Value* volumeLeft = map.Find( VOLUME_LEFT );
370           Property::Value* volumeRight = map.Find( VOLUME_RIGHT );
371           if( volumeLeft && volumeLeft->Get( left ) && volumeRight && volumeRight->Get( right ) )
372           {
373             impl.SetVolume( left, right );
374           }
375         }
376         break;
377       }
378     }
379   }
380 }
381
382 Property::Value VideoView::GetProperty( BaseObject* object, Property::Index propertyIndex )
383 {
384   Property::Value value;
385   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) );
386
387   if( videoView )
388   {
389     VideoView& impl = GetImpl( videoView );
390
391     switch( propertyIndex )
392     {
393       case Toolkit::VideoView::Property::VIDEO:
394       {
395         if( !impl.mUrl.empty() )
396         {
397           value = impl.mUrl;
398         }
399         else if( !impl.mPropertyMap.Empty() )
400         {
401           value = impl.mPropertyMap;
402         }
403         break;
404       }
405       case Toolkit::VideoView::Property::LOOPING:
406       {
407         value = impl.IsLooping();
408         break;
409       }
410       case Toolkit::VideoView::Property::MUTED:
411       {
412         value = impl.IsMuted();
413         break;
414       }
415       case Toolkit::VideoView::Property::VOLUME:
416       {
417         Property::Map map;
418         float left, right;
419
420         impl.GetVolume( left, right );
421         map.Insert( VOLUME_LEFT, left );
422         map.Insert( VOLUME_RIGHT, right );
423         value = map;
424         break;
425       }
426     }
427   }
428
429   return value;
430 }
431
432 void VideoView::SetDepthIndex( int depthIndex )
433 {
434   if( mVisual )
435   {
436     mVisual.SetDepthIndex( depthIndex );
437   }
438 }
439
440 void VideoView::OnStageConnection( int depth )
441 {
442   Control::OnStageConnection( depth );
443
444   if( mVisual )
445   {
446     CustomActor self = Self();
447     mVisual.SetOnStage( self );
448   }
449 }
450
451 void VideoView::OnStageDisconnection()
452 {
453   if( mVisual )
454   {
455     CustomActor self = Self();
456     mVisual.SetOffStage( self );
457   }
458
459   Control::OnStageDisconnection();
460 }
461
462 Vector3 VideoView::GetNaturalSize()
463 {
464   Vector3 size;
465   size.x = mVideoSize.GetWidth();
466   size.y = mVideoSize.GetHeight();
467
468   if( size.x > 0 && size.y > 0 )
469   {
470     size.z = std::min( size.x, size.y );
471     return size;
472   }
473   else
474   {
475     return Control::GetNaturalSize();
476   }
477 }
478
479 float VideoView::GetHeightForWidth( float width )
480 {
481   if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 )
482   {
483     return GetHeightForWidthBase( width );
484   }
485   else
486   {
487     return Control::GetHeightForWidthBase( width );
488   }
489 }
490
491 float VideoView::GetWidthForHeight( float height )
492 {
493   if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 )
494   {
495     return GetWidthForHeightBase( height );
496   }
497   else
498   {
499     return Control::GetWidthForHeightBase( height );
500   }
501 }
502
503 void VideoView::SetWindowSurfaceTarget()
504 {
505   Actor self = Self();
506   int curPos = mVideoPlayer.GetPlayPosition();
507
508   mSetRenderingTarget = true;
509   mVisual.RemoveAndReset( self );
510
511   mVideoPlayer.SetRenderingTarget( Dali::Adaptor::Get().GetNativeWindowHandle() );
512   mVideoPlayer.SetUrl( mUrl );
513   mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
514
515   if( mIsPlay )
516   {
517     mVideoPlayer.Play();
518   }
519   if( mIsPause )
520   {
521     mVideoPlayer.Play();
522     mVideoPlayer.Pause();
523   }
524   mVideoPlayer.SetPlayPosition( curPos );
525 }
526
527 void VideoView::SetNativeImageTarget()
528 {
529   Actor self( Self() );
530   int curPos = mVideoPlayer.GetPlayPosition();
531
532   mSetRenderingTarget = true;
533
534   Any source;
535   Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New( source );
536   mNativeImage = Dali::NativeImage::New( *nativeImageSourcePtr );
537
538   mVideoPlayer.SetRenderingTarget( nativeImageSourcePtr );
539   mVideoPlayer.SetUrl( mUrl );
540   mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
541
542   Internal::InitializeVisual( self, mVisual, mNativeImage );
543
544   if( mIsPlay )
545   {
546     mVideoPlayer.Play();
547   }
548
549   if( mIsPause )
550   {
551     mVideoPlayer.Play();
552     mVideoPlayer.Pause();
553   }
554   mVideoPlayer.SetPlayPosition( curPos );
555 }
556
557 } // namespace Internal
558
559 } // namespace Toolkit
560
561 } // namespace Dali