Merge "remove (unnecessarily) exported signal and action names" into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / common / stage-impl.cpp
1 /*
2  * Copyright (c) 2014 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 <dali/internal/event/common/stage-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <cmath>
24
25 // INTERNAL INCLUDES
26 #include <dali/integration-api/system-overlay.h>
27 #include <dali/internal/event/actors/layer-impl.h>
28 #include <dali/internal/event/actors/layer-list.h>
29 #include <dali/internal/event/actors/camera-actor-impl.h>
30 #include <dali/internal/event/actor-attachments/camera-attachment-impl.h>
31 #include <dali/internal/event/common/system-overlay-impl.h>
32 #include <dali/internal/event/common/thread-local-storage.h>
33 #include <dali/internal/event/common/property-notification-manager.h>
34 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
35 #include <dali/internal/update/nodes/node.h>
36 #include <dali/internal/event/common/object-registry-impl.h>
37 #include <dali/integration-api/platform-abstraction.h>
38 #include <dali/public-api/common/constants.h>
39 #include <dali/public-api/object/type-registry.h>
40 #include <dali/public-api/render-tasks/render-task-list.h>
41
42 #ifdef DYNAMICS_SUPPORT
43 #include <dali/internal/event/dynamics/dynamics-world-config-impl.h>
44 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
45 #include <dali/integration-api/dynamics/dynamics-factory-intf.h>
46 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
47 #endif
48
49 using Dali::Internal::SceneGraph::Node;
50
51 namespace Dali
52 {
53
54 namespace Internal
55 {
56
57 namespace
58 {
59
60 const float DEFAULT_STEREO_BASE( 65.0f );
61
62 // Signals
63
64 const char* const SIGNAL_KEY_EVENT =                 "key-event";
65 const char* const SIGNAL_EVENT_PROCESSING_FINISHED = "event-processing-finished";
66 const char* const SIGNAL_TOUCHED =                   "touched";
67 const char* const SIGNAL_CONTEXT_LOST =              "context-lost";
68 const char* const SIGNAL_CONTEXT_REGAINED =          "context-regained";
69 const char* const SIGNAL_SCENE_CREATED =             "scene-created";
70
71 TypeRegistration mType( typeid(Dali::Stage), typeid(Dali::BaseHandle), NULL );
72
73 SignalConnectorType signalConnector1( mType, SIGNAL_KEY_EVENT,                 &Stage::DoConnectSignal );
74 SignalConnectorType signalConnector2( mType, SIGNAL_EVENT_PROCESSING_FINISHED, &Stage::DoConnectSignal );
75 SignalConnectorType signalConnector3( mType, SIGNAL_TOUCHED,                   &Stage::DoConnectSignal );
76 SignalConnectorType signalConnector4( mType, SIGNAL_CONTEXT_LOST,              &Stage::DoConnectSignal );
77 SignalConnectorType signalConnector5( mType, SIGNAL_CONTEXT_REGAINED,          &Stage::DoConnectSignal );
78 SignalConnectorType signalConnector6( mType, SIGNAL_SCENE_CREATED,             &Stage::DoConnectSignal );
79
80 } // unnamed namespace
81
82 StagePtr Stage::New( AnimationPlaylist& playlist,
83                      PropertyNotificationManager& propertyNotificationManager,
84                      SceneGraph::UpdateManager& updateManager,
85                      NotificationManager& notificationManager )
86 {
87   return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager ) );
88 }
89
90 void Stage::Initialize()
91 {
92   mObjectRegistry = ObjectRegistry::New();
93
94   // Create the ordered list of layers
95   mLayerList = LayerList::New( *this, false/*not system-level*/ );
96
97   // The stage owns the default layer
98   mRootLayer = Layer::NewRoot( *this, *mLayerList, mUpdateManager, false/*not system-level*/ );
99   mRootLayer->SetName("RootLayer");
100
101   // Create the default camera actor first; this is needed by the RenderTaskList
102   CreateDefaultCameraActor();
103
104   // Create the list of render-tasks
105   mRenderTaskList = RenderTaskList::New( mUpdateManager, *this, false/*not system-level*/ );
106
107   // Create the default render-task
108   Dali::RenderTask defaultRenderTask = mRenderTaskList->CreateTask();
109 }
110
111 void Stage::Uninitialize()
112 {
113   // Remove actors added to SystemOverlay
114   delete mSystemOverlay;
115   mSystemOverlay = NULL;
116
117   if( mDefaultCamera )
118   {
119     Remove(*(mDefaultCamera.Get()));
120   }
121
122   if( mRootLayer )
123   {
124     // we are closing down so just delete the root, no point emit disconnect
125     // signals or send messages to update
126     mRootLayer.Reset();
127   }
128 }
129
130 StagePtr Stage::GetCurrent()
131 {
132   StagePtr stage( NULL );
133   // no checking in this version
134   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
135   if( tls )
136   {
137     stage = tls->GetCurrentStage();
138   }
139   return stage;
140 }
141
142 bool Stage::IsInstalled()
143 {
144   return ThreadLocalStorage::Created();
145 }
146
147 ObjectRegistry& Stage::GetObjectRegistry()
148 {
149   return *mObjectRegistry;
150 }
151
152 void Stage::RegisterObject( Dali::BaseObject* object )
153 {
154   mObjectRegistry->RegisterObject( object );
155 }
156
157 void Stage::UnregisterObject( Dali::BaseObject* object )
158 {
159   mObjectRegistry->UnregisterObject( object );
160 }
161
162 Layer& Stage::GetRootActor()
163 {
164   return *mRootLayer;
165 }
166
167 SceneGraph::UpdateManager& Stage::GetUpdateManager()
168 {
169   return mUpdateManager;
170 }
171
172 EventToUpdate& Stage::GetUpdateInterface()
173 {
174   return mUpdateManager.GetEventToUpdate();
175 }
176
177 AnimationPlaylist& Stage::GetAnimationPlaylist()
178 {
179   return mAnimationPlaylist;
180 }
181
182 PropertyNotificationManager& Stage::GetPropertyNotificationManager()
183 {
184   return mPropertyNotificationManager;
185 }
186
187 void Stage::Add( Actor& actor )
188 {
189   mRootLayer->Add( actor );
190 }
191
192 void Stage::Remove( Actor& actor )
193 {
194   mRootLayer->Remove( actor );
195 }
196
197 void Stage::SetSize(float width, float height)
198 {
199   // Internally we want to report the actual size of the stage.
200   mSize.width  = width;
201   mSize.height = height;
202
203   // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
204   mDefaultCamera->SetPerspectiveProjection( mSize );
205
206   // The depth of the stage gets set to the maximun of these values
207   mRootLayer->SetSize( mSize );
208
209   // Repeat for SystemOverlay actors
210   if( mSystemOverlay )
211   {
212     mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
213   }
214
215   SetDefaultSurfaceRectMessage( mUpdateManager, Rect<int>( 0, 0, width, height ) );
216 }
217
218 Vector2 Stage::GetSize() const
219 {
220   return mSize;
221 }
222
223 RenderTaskList& Stage::GetRenderTaskList() const
224 {
225   return *mRenderTaskList;
226 }
227
228 void Stage::CreateDefaultCameraActor()
229 {
230   // The default camera attributes and position is such that
231   // children of the default layer, can be positioned at (0,0) and
232   // be at the top-left of the viewport.
233   mDefaultCamera = CameraActor::New( Size::ZERO );
234   mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER);
235   Add(*(mDefaultCamera.Get()));
236 }
237
238 Actor& Stage::GetDefaultRootActor()
239 {
240   return *mRootLayer;
241 }
242
243 CameraActor& Stage::GetDefaultCameraActor()
244 {
245   return *mDefaultCamera;
246 }
247
248 unsigned int Stage::GetLayerCount() const
249 {
250   return mLayerList->GetLayerCount();
251 }
252
253 Dali::Layer Stage::GetLayer( unsigned int depth ) const
254 {
255   return Dali::Layer(mLayerList->GetLayer( depth ));
256 }
257
258 Dali::Layer Stage::GetRootLayer() const
259 {
260   return Dali::Layer( mRootLayer.Get() );
261 }
262
263 LayerList& Stage::GetLayerList()
264 {
265   return *mLayerList;
266 }
267
268 Integration::SystemOverlay& Stage::GetSystemOverlay()
269 {
270   // Lazily create system-level if requested
271   if( !mSystemOverlay )
272   {
273     mSystemOverlay = new Integration::SystemOverlay( SystemOverlay::New( *this ) );
274     DALI_ASSERT_ALWAYS( NULL != mSystemOverlay && "Failed to create system overlay" );
275
276     mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
277   }
278
279   return *mSystemOverlay;
280 }
281
282 SystemOverlay* Stage::GetSystemOverlayInternal()
283 {
284   SystemOverlay* overlay( NULL );
285
286   if( mSystemOverlay )
287   {
288     overlay = mSystemOverlay->GetImpl();
289   }
290
291   return overlay;
292 }
293
294 void Stage::SetViewMode( ViewMode viewMode )
295 {
296   if( mViewMode != viewMode )
297   {
298     DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "View mode changed from %d to %d\n", mViewMode, viewMode);
299
300     if( mViewMode == MONO )
301     {
302       mDefaultCamera->SetRotation( Degree( 180.0f ), Vector3::YAXIS );
303       mRenderTaskList->GetTask(0).SetSourceActor( Dali::Actor() );
304
305       //Create camera and RenderTask for left eye
306       mLeftCamera = CameraActor::New( Size::ZERO );
307       mLeftCamera->SetParentOrigin( ParentOrigin::CENTER );
308       mDefaultCamera->Add( *mLeftCamera.Get() );
309       mLeftRenderTask = mRenderTaskList->CreateTask();
310       mLeftRenderTask.SetCameraActor( Dali::CameraActor( mLeftCamera.Get() ) );
311       mLeftCamera->SetType( Dali::Camera::FREE_LOOK );
312
313       //Create camera and RenderTask for right eye
314       mRightCamera = CameraActor::New( Size::ZERO );
315       mRightCamera->SetParentOrigin( ParentOrigin::CENTER );
316       mDefaultCamera->Add( *mRightCamera.Get() );
317       mRightRenderTask = mRenderTaskList->CreateTask();
318       mRightRenderTask.SetClearColor( Vector4( 1.0f,0.0f,0.0f,1.0f));
319
320       mRightRenderTask.SetCameraActor( Dali::CameraActor( mRightCamera.Get() ) );
321       mRightCamera->SetType( Dali::Camera::FREE_LOOK );
322     }
323
324     // save new mode
325     mViewMode = viewMode;
326
327     switch( viewMode )
328     {
329       case MONO:
330       {
331         // delete extra stereoscopic render tasks and cameras
332         mRenderTaskList->RemoveTask( mLeftRenderTask );
333         mDefaultCamera->Remove( *mLeftCamera.Get() );
334         mLeftRenderTask.Reset();
335         mLeftCamera.Reset();
336         mRenderTaskList->RemoveTask( mRightRenderTask );
337         mDefaultCamera->Remove( *mRightCamera.Get() );
338         mRightRenderTask.Reset();
339         mRightCamera.Reset();
340
341         mDefaultCamera->SetRotation( Degree( 0.0f ), Vector3::YAXIS );
342         mDefaultCamera->SetType( Dali::Camera::LOOK_AT_TARGET );
343         mRenderTaskList->GetTask(0).SetSourceActor( Dali::Layer(mRootLayer.Get()) );
344
345         break;
346       }
347       case STEREO_HORIZONTAL:
348       {
349         //Stereo mode with horizontal split is for landscape mode. That's the reason for the cameras being rotated
350         //Top camera renders the scene as seen from the right eye and bottom camera as seen from left.
351
352         //Calculate separation in pixels along vertical axis ( mStereoBase is defined in millimetres )
353         const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().y ) * 0.5f );
354
355         //Calculate aspect ratio
356         float aspect = mSize.width / (mSize.height * 0.5f);
357
358         mLeftCamera->SetPerspectiveProjection( mSize, Vector2( 0.0f,stereoBase) );
359         mLeftCamera->SetAspectRatio( aspect );
360         mLeftCamera->SetRotation( Degree(-90.0f), Vector3::ZAXIS );
361         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
362         mLeftRenderTask.SetViewport( Viewport(0, mSize.height * 0.5f, mSize.width, mSize.height * 0.5f) );
363
364         mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0,  -stereoBase) );
365         mRightCamera->SetAspectRatio( aspect );
366         mRightCamera->SetRotation( Degree(-90.0f), Vector3::ZAXIS );
367         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
368         mRightRenderTask.SetViewport( Viewport(0, 0, mSize.width, mSize.height * 0.5f ) );
369
370         break;
371       }
372       case STEREO_VERTICAL:
373       {
374         //Calculate separation in pixels along horizontal axis
375         const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().x ) * 0.5f );
376
377         //Recalculate fov based on viewport size
378         const float fov = 2.0f * std::atan(  mSize.y / (2.0f * std::max( mSize.x*0.5f, mSize.y )) );
379
380         mLeftCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(stereoBase,0.0f) );
381         mLeftCamera->SetFieldOfView( fov );
382         mLeftCamera->SetRotation( Degree(0.0f), Vector3::ZAXIS );
383         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
384         mLeftRenderTask.SetViewport( Viewport(0, 0, mSize.width * 0.5f, mSize.height ) );
385
386         mRightCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(-stereoBase,0.0f) );
387         mRightCamera->SetFieldOfView( fov );
388         mRightCamera->SetRotation( Degree(0.0f), Vector3::ZAXIS );
389         mRightCamera->SetPosition( Vector3( -stereoBase, 0.0f, 0.0f ) );
390         mRightRenderTask.SetViewport( Viewport(mSize.width * 0.5f, 0, mSize.width * 0.5f, mSize.height ) );
391
392         break;
393       }
394       case STEREO_INTERLACED:
395       {
396         break;
397       }
398     }
399   }
400 }
401
402 ViewMode Stage::GetViewMode() const
403 {
404   return mViewMode;
405 }
406
407 void Stage::SetStereoBase( float stereoBase )
408 {
409   if( ! Equals( mStereoBase, stereoBase ) )
410   {
411     DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "old( %.2f) new(%.2f)", mStereoBase, stereoBase );
412     mStereoBase = stereoBase;
413
414     switch( mViewMode  )
415     {
416       case STEREO_HORIZONTAL:
417       {
418         stereoBase = mStereoBase / 25.4f * GetDpi().y * 0.5f;
419         float aspect = mSize.width / (mSize.height * 0.5f);
420
421         mLeftCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, stereoBase) );
422         mLeftCamera->SetAspectRatio( aspect );
423         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
424
425         mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, -stereoBase) );
426         mRightCamera->SetAspectRatio( aspect );
427         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
428
429         break;
430       }
431       case STEREO_VERTICAL:
432       {
433         stereoBase = mStereoBase / 25.4f * GetDpi().x * 0.5f;
434         const float fov = 2.0f * std::atan(  mSize.y / (2.0f * std::max( mSize.x*0.5f, mSize.y )) );
435
436         mLeftCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(stereoBase,0.0f) );
437         mLeftCamera->SetFieldOfView( fov );
438         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
439
440         mRightCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(-stereoBase,0.0f) );
441         mRightCamera->SetFieldOfView( fov );
442         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
443
444         break;
445       }
446       default:
447         break;
448     }
449   }
450 }
451
452 float Stage::GetStereoBase() const
453 {
454   return mStereoBase;
455 }
456
457 void Stage::SetBackgroundColor(Vector4 color)
458 {
459   // Cache for public GetBackgroundColor()
460   mBackgroundColor = color;
461
462   // Send message to change color in next frame
463   SetBackgroundColorMessage( mUpdateManager, color );
464 }
465
466 Vector4 Stage::GetBackgroundColor() const
467 {
468   return mBackgroundColor;
469 }
470
471 Vector2 Stage::GetDpi() const
472 {
473   return mDpi;
474 }
475
476 void Stage::SetDpi(Vector2 dpi)
477 {
478   mDpi = dpi;
479 }
480
481 #ifdef DYNAMICS_SUPPORT
482
483 DynamicsNotifier& Stage::GetDynamicsNotifier()
484 {
485   return mDynamicsNotifier;
486 }
487
488 DynamicsWorldPtr Stage::InitializeDynamics(DynamicsWorldConfigPtr config)
489 {
490   if( !mDynamicsFactory )
491   {
492     mDynamicsFactory = ThreadLocalStorage::Get().GetPlatformAbstraction().GetDynamicsFactory();
493   }
494
495   if( mDynamicsFactory && !mDynamicsWorld )
496   {
497     if( mDynamicsFactory->InitializeDynamics( *(config->GetSettings()) ) )
498     {
499       mDynamicsWorld = DynamicsWorld::New();
500       mDynamicsWorld->Initialize( *this, *mDynamicsFactory, config );
501     }
502   }
503   return mDynamicsWorld;
504 }
505
506 DynamicsWorldPtr Stage::GetDynamicsWorld()
507 {
508   return mDynamicsWorld;
509 }
510
511 void Stage::TerminateDynamics()
512 {
513   if( mDynamicsWorld )
514   {
515     mDynamicsWorld->Terminate(*this);
516     mDynamicsWorld = NULL;
517   }
518 }
519
520 #endif // DYNAMICS_SUPPORT
521
522 void Stage::KeepRendering( float durationSeconds )
523 {
524   // Send message to keep rendering
525   KeepRenderingMessage( mUpdateManager, durationSeconds );
526 }
527
528 bool Stage::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
529 {
530   bool connected( true );
531   Stage* stage = dynamic_cast<Stage*>(object);
532
533   if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_EVENT ) )
534   {
535     stage->KeyEventSignal().Connect( tracker, functor );
536   }
537   else if( 0 == strcmp( signalName.c_str(), SIGNAL_EVENT_PROCESSING_FINISHED ) )
538   {
539     stage->EventProcessingFinishedSignal().Connect( tracker, functor );
540   }
541   else if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) )
542   {
543     stage->TouchedSignal().Connect( tracker, functor );
544   }
545   else if( 0 == strcmp( signalName.c_str(), SIGNAL_CONTEXT_LOST ) )
546   {
547     stage->ContextLostSignal().Connect( tracker, functor );
548   }
549   else if( 0 == strcmp( signalName.c_str(), SIGNAL_CONTEXT_REGAINED ) )
550   {
551     stage->ContextRegainedSignal().Connect( tracker, functor );
552   }
553   else if( 0 == strcmp( signalName.c_str(), SIGNAL_SCENE_CREATED ) )
554   {
555     stage->SceneCreatedSignal().Connect( tracker, functor );
556   }
557   else
558   {
559     // signalName does not match any signal
560     connected = false;
561   }
562
563   return connected;
564 }
565
566 void Stage::EmitKeyEventSignal(const KeyEvent& event)
567 {
568   // Emit the key event signal when no actor in the stage has gained the key input focus
569
570   mKeyEventSignal.Emit( event );
571 }
572
573 void Stage::EmitEventProcessingFinishedSignal()
574 {
575    mEventProcessingFinishedSignal.Emit();
576 }
577
578 void Stage::EmitTouchedSignal( const TouchEvent& touch )
579 {
580   mTouchedSignal.Emit( touch );
581 }
582
583
584 void Stage::EmitSceneCreatedSignal()
585 {
586   mSceneCreatedSignal.Emit();
587 }
588
589 Dali::Stage::KeyEventSignalType& Stage::KeyEventSignal()
590 {
591   return mKeyEventSignal;
592 }
593
594 Dali::Stage::EventProcessingFinishedSignalType& Stage::EventProcessingFinishedSignal()
595 {
596   return mEventProcessingFinishedSignal;
597 }
598
599 Dali::Stage::TouchedSignalType& Stage::TouchedSignal()
600 {
601   return mTouchedSignal;
602 }
603
604 Dali::Stage::ContextStatusSignal& Stage::ContextLostSignal()
605 {
606   return mContextLostSignal;
607 }
608
609 Dali::Stage::ContextStatusSignal& Stage::ContextRegainedSignal()
610 {
611   return mContextRegainedSignal;
612 }
613
614 Dali::Stage::SceneCreatedSignalType& Stage::SceneCreatedSignal()
615 {
616   return mSceneCreatedSignal;
617 }
618
619 void Stage::NotifyContextLost()
620 {
621   mContextLostSignal.Emit();
622 }
623
624 void Stage::NotifyContextRegained()
625 {
626   mContextRegainedSignal.Emit();
627 }
628
629 Stage::Stage( AnimationPlaylist& playlist,
630               PropertyNotificationManager& propertyNotificationManager,
631               SceneGraph::UpdateManager& updateManager,
632               NotificationManager& notificationManager )
633 : mAnimationPlaylist( playlist ),
634   mPropertyNotificationManager(propertyNotificationManager),
635   mUpdateManager(updateManager),
636   mNotificationManager(notificationManager),
637   mSize(Vector2::ZERO),
638   mBackgroundColor(Dali::Stage::DEFAULT_BACKGROUND_COLOR),
639   mViewMode( MONO ),
640   mStereoBase( DEFAULT_STEREO_BASE ),
641 #ifdef DYNAMICS_SUPPORT
642   mDynamicsFactory(NULL),
643 #endif
644   mSystemOverlay(NULL)
645 {
646 }
647
648 Stage::~Stage()
649 {
650   delete mSystemOverlay;
651
652   mObjectRegistry.Reset();
653 }
654
655 } // namespace Internal
656
657 } // namespace Dali