(Gestures) Each actor is now aware of what gestures it requires which is used when...
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali/internal/event/actors/actor-impl.h>
19
20 // EXTERNAL INCLUDES
21 #include <cmath>
22 #include <algorithm>
23
24 // INTERNAL INCLUDES
25
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/constants.h>
28 #include <dali/public-api/math/vector2.h>
29 #include <dali/public-api/math/vector3.h>
30 #include <dali/public-api/math/radian.h>
31 #include <dali/public-api/object/type-registry.h>
32 #include <dali/public-api/scripting/scripting.h>
33
34 #include <dali/internal/common/internal-constants.h>
35 #include <dali/internal/event/render-tasks/render-task-impl.h>
36 #include <dali/internal/event/actors/camera-actor-impl.h>
37 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
38 #include <dali/internal/event/common/property-index-ranges.h>
39 #include <dali/internal/event/common/stage-impl.h>
40 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
41 #include <dali/internal/event/animation/constraint-impl.h>
42 #include <dali/internal/event/common/projection.h>
43 #include <dali/internal/update/common/animatable-property.h>
44 #include <dali/internal/update/common/property-owner-messages.h>
45 #include <dali/internal/update/nodes/node-messages.h>
46 #include <dali/internal/update/nodes/node-declarations.h>
47 #include <dali/internal/update/animation/scene-graph-constraint.h>
48 #include <dali/internal/event/effects/shader-effect-impl.h>
49 #include <dali/internal/common/message.h>
50 #include <dali/integration-api/debug.h>
51
52 #ifdef DYNAMICS_SUPPORT
53 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
54 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
57 #endif
58
59 #include <dali/internal/event/events/pan-gesture-detector-impl.h>
60 #include <dali/internal/event/events/pinch-gesture-detector-impl.h>
61 #include <dali/internal/event/events/long-press-gesture-detector-impl.h>
62 #include <dali/internal/event/events/tap-gesture-detector-impl.h>
63
64 using Dali::Internal::SceneGraph::Node;
65 using Dali::Internal::SceneGraph::AnimatableProperty;
66 using Dali::Internal::SceneGraph::PropertyBase;
67 using Dali::Internal::SceneGraph::Shader;
68
69 using namespace std;
70
71 namespace Dali
72 {
73
74 const Property::Index Actor::PARENT_ORIGIN              = 0;
75 const Property::Index Actor::PARENT_ORIGIN_X            = 1;
76 const Property::Index Actor::PARENT_ORIGIN_Y            = 2;
77 const Property::Index Actor::PARENT_ORIGIN_Z            = 3;
78 const Property::Index Actor::ANCHOR_POINT               = 4;
79 const Property::Index Actor::ANCHOR_POINT_X             = 5;
80 const Property::Index Actor::ANCHOR_POINT_Y             = 6;
81 const Property::Index Actor::ANCHOR_POINT_Z             = 7;
82 const Property::Index Actor::SIZE                       = 8;
83 const Property::Index Actor::SIZE_WIDTH                 = 9;
84 const Property::Index Actor::SIZE_HEIGHT                = 10;
85 const Property::Index Actor::SIZE_DEPTH                 = 11;
86 const Property::Index Actor::POSITION                   = 12;
87 const Property::Index Actor::POSITION_X                 = 13;
88 const Property::Index Actor::POSITION_Y                 = 14;
89 const Property::Index Actor::POSITION_Z                 = 15;
90 const Property::Index Actor::WORLD_POSITION             = 16;
91 const Property::Index Actor::WORLD_POSITION_X           = 17;
92 const Property::Index Actor::WORLD_POSITION_Y           = 18;
93 const Property::Index Actor::WORLD_POSITION_Z           = 19;
94 const Property::Index Actor::ROTATION                   = 20;
95 const Property::Index Actor::WORLD_ROTATION             = 21;
96 const Property::Index Actor::SCALE                      = 22;
97 const Property::Index Actor::SCALE_X                    = 23;
98 const Property::Index Actor::SCALE_Y                    = 24;
99 const Property::Index Actor::SCALE_Z                    = 25;
100 const Property::Index Actor::WORLD_SCALE                = 26;
101 const Property::Index Actor::VISIBLE                    = 27;
102 const Property::Index Actor::COLOR                      = 28;
103 const Property::Index Actor::COLOR_RED                  = 29;
104 const Property::Index Actor::COLOR_GREEN                = 30;
105 const Property::Index Actor::COLOR_BLUE                 = 31;
106 const Property::Index Actor::COLOR_ALPHA                = 32;
107 const Property::Index Actor::WORLD_COLOR                = 33;
108 const Property::Index Actor::WORLD_MATRIX               = 34;
109 const Property::Index Actor::NAME                       = 35;
110 const Property::Index Actor::SENSITIVE                  = 36;
111 const Property::Index Actor::LEAVE_REQUIRED             = 37;
112 const Property::Index Actor::INHERIT_SHADER_EFFECT      = 38;
113 const Property::Index Actor::INHERIT_ROTATION           = 39;
114 const Property::Index Actor::INHERIT_SCALE              = 40;
115 const Property::Index Actor::COLOR_MODE                 = 41;
116 const Property::Index Actor::POSITION_INHERITANCE       = 42;
117 const Property::Index Actor::DRAW_MODE                  = 43;
118
119 namespace // unnamed namespace
120 {
121
122 /**
123  * We want to discourage the use of property strings (minimize string comparisons),
124  * particularly for the default properties.
125  */
126 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
127 {
128   // Name                     Type              writable animatable constraint-input
129   { "parent-origin",          Property::VECTOR3,  true,    false,   true  },  // PARENT_ORIGIN
130   { "parent-origin-x",        Property::FLOAT,    true,    false,   true  },  // PARENT_ORIGIN_X
131   { "parent-origin-y",        Property::FLOAT,    true,    false,   true  },  // PARENT_ORIGIN_Y
132   { "parent-origin-z",        Property::FLOAT,    true,    false,   true  },  // PARENT_ORIGIN_Z
133   { "anchor-point",           Property::VECTOR3,  true,    false,   true  },  // ANCHOR_POINT
134   { "anchor-point-x",         Property::FLOAT,    true,    false,   true  },  // ANCHOR_POINT_X
135   { "anchor-point-y",         Property::FLOAT,    true,    false,   true  },  // ANCHOR_POINT_Y
136   { "anchor-point-z",         Property::FLOAT,    true,    false,   true  },  // ANCHOR_POINT_Z
137   { "size",                   Property::VECTOR3,  true,    true,    true  },  // SIZE
138   { "size-width",             Property::FLOAT,    true,    true,    true  },  // SIZE_WIDTH
139   { "size-height",            Property::FLOAT,    true,    true,    true  },  // SIZE_HEIGHT
140   { "size-depth",             Property::FLOAT,    true,    true,    true  },  // SIZE_DEPTH
141   { "position",               Property::VECTOR3,  true,    true,    true  },  // POSITION
142   { "position-x",             Property::FLOAT,    true,    true,    true  },  // POSITION_X
143   { "position-y",             Property::FLOAT,    true,    true,    true  },  // POSITION_Y
144   { "position-z",             Property::FLOAT,    true,    true,    true  },  // POSITION_Z
145   { "world-position",         Property::VECTOR3,  false,   false,   true  },  // WORLD_POSITION
146   { "world-position-x",       Property::FLOAT,    false,   false,   true  },  // WORLD_POSITION_X
147   { "world-position-y",       Property::FLOAT,    false,   false,   true  },  // WORLD_POSITION_Y
148   { "world-position-z",       Property::FLOAT,    false,   false,   true  },  // WORLD_POSITION_Z
149   { "rotation",               Property::ROTATION, true,    true,    true  },  // ROTATION
150   { "world-rotation",         Property::ROTATION, false,   false,   true  },  // WORLD_ROTATION
151   { "scale",                  Property::VECTOR3,  true,    true,    true  },  // SCALE
152   { "scale-x",                Property::FLOAT,    true,    true,    true  },  // SCALE_X
153   { "scale-y",                Property::FLOAT,    true,    true,    true  },  // SCALE_Y
154   { "scale-z",                Property::FLOAT,    true,    true,    true  },  // SCALE_Z
155   { "world-scale",            Property::VECTOR3,  false,   false,   true  },  // WORLD_SCALE
156   { "visible",                Property::BOOLEAN,  true,    true,    true  },  // VISIBLE
157   { "color",                  Property::VECTOR4,  true,    true,    true  },  // COLOR
158   { "color-red",              Property::FLOAT,    true,    true,    true  },  // COLOR_RED
159   { "color-green",            Property::FLOAT,    true,    true,    true  },  // COLOR_GREEN
160   { "color-blue",             Property::FLOAT,    true,    true,    true  },  // COLOR_BLUE
161   { "color-alpha",            Property::FLOAT,    true,    true,    true  },  // COLOR_ALPHA
162   { "world-color",            Property::VECTOR4,  false,   false,   true  },  // WORLD_COLOR
163   { "world-matrix",           Property::MATRIX,   false,   false,   true  },  // WORLD_MATRIX
164   { "name",                   Property::STRING,   true,    false,   false },  // NAME
165   { "sensitive",              Property::BOOLEAN,  true,    false,   false },  // SENSITIVE
166   { "leave-required",         Property::BOOLEAN,  true,    false,   false },  // LEAVE_REQUIRED
167   { "inherit-shader-effect",  Property::BOOLEAN,  true,    false,   false },  // INHERIT_SHADER_EFFECT
168   { "inherit-rotation",       Property::BOOLEAN,  true,    false,   false },  // INHERIT_ROTATION
169   { "inherit-scale",          Property::BOOLEAN,  true,    false,   false },  // INHERIT_SCALE
170   { "color-mode",             Property::STRING,   true,    false,   false },  // COLOR_MODE
171   { "position-inheritance",   Property::STRING,   true,    false,   false },  // POSITION_INHERITANCE
172   { "draw-mode",              Property::STRING,   true,    false,   false },  // DRAW_MODE
173 };
174 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
175
176 } // unnamed namespace
177
178 namespace Internal
179 {
180
181 unsigned int Actor::mActorCounter = 0;
182 ActorContainer Actor::mNullChildren;
183
184 // Encapsulate actor related gesture information
185 struct GestureData
186 {
187   /**
188    * Constructor
189    */
190   GestureData()
191   : gesturesRequired( Gesture::Type( 0 ) ),
192     panDetectors( NULL ),
193     pinchDetectors( NULL ),
194     longPressDetectors( NULL ),
195     tapDetectors( NULL )
196   {
197   }
198
199   /**
200    * Destructor
201    */
202   ~GestureData()
203   {
204     delete panDetectors;
205     delete pinchDetectors;
206     delete longPressDetectors;
207     delete tapDetectors;
208   }
209
210   /**
211    * Checks if the containers in GestureData are empty
212    */
213   bool Empty() const
214   {
215     return !panDetectors       &&
216            !pinchDetectors     &&
217            !longPressDetectors &&
218            !tapDetectors;
219   }
220
221   /**
222    * Template to add a detector to the appropriate container. Dynamically allocates the container
223    * only if it is used.
224    */
225   template< typename DetectorType, typename ContainerType >
226   void AddDetector( ContainerType*& containerPtr, GestureDetector* detector )
227   {
228     if ( NULL == containerPtr )
229     {
230       containerPtr = new ContainerType;
231     }
232
233     containerPtr->push_back( static_cast< DetectorType* >( detector ) );
234     gesturesRequired = Gesture::Type( gesturesRequired | detector->GetType() );
235   }
236
237   /**
238    * Template to remove a detector from the appropriate container. Deletes the container if it is
239    * no longer required.
240    */
241   template< typename ContainerType >
242   void RemoveDetector( ContainerType*& containerPtr, GestureDetector* detector )
243   {
244     if ( NULL != containerPtr )
245     {
246       ContainerType& container( *containerPtr );
247       typename ContainerType::iterator match( std::remove( container.begin(), container.end(), detector ) );
248       DALI_ASSERT_DEBUG( match != container.end() && "Actor does not have the detector" );
249       container.erase( match, container.end() );
250
251       if ( container.empty() )
252       {
253         gesturesRequired = Gesture::Type( gesturesRequired & ~detector->GetType() );
254         delete containerPtr;
255         containerPtr = NULL;
256       }
257     }
258   }
259
260   Gesture::Type gesturesRequired;
261
262   PanGestureDetectorContainer*       panDetectors;
263   PinchGestureDetectorContainer*     pinchDetectors;
264   LongPressGestureDetectorContainer* longPressDetectors;
265   TapGestureDetectorContainer*       tapDetectors;
266 };
267
268 #ifdef DYNAMICS_SUPPORT
269
270 // Encapsulate actor related dynamics data
271 struct DynamicsData
272 {
273   DynamicsData( Actor* slotOwner )
274   : slotDelegate( slotOwner )
275   {
276   }
277
278   typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
279   typedef std::vector<DynamicsJointPtr>      ReferencedJointContainer;
280
281   DynamicsBodyPtr          body;
282   JointContainer           joints;
283   ReferencedJointContainer referencedJoints;
284
285   SlotDelegate< Actor > slotDelegate;
286 };
287
288 #endif // DYNAMICS_SUPPORT
289
290 namespace
291 {
292
293 using namespace Dali;
294
295 BaseHandle CreateActor()
296 {
297   return Dali::Actor::New();
298 }
299
300 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
301
302 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED,    &Actor::DoConnectSignal);
303 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE,   &Actor::DoConnectSignal);
304 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE,   &Actor::DoConnectSignal);
305 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE,  &Actor::DoConnectSignal);
306
307 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
308 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
309
310 }
311
312 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
313
314 ActorPtr Actor::New()
315 {
316   ActorPtr actor( new Actor( BASIC ) );
317
318   // Second-phase construction
319   actor->Initialize();
320
321   return actor;
322 }
323
324 const std::string& Actor::GetName() const
325 {
326   return mName;
327 }
328
329 void Actor::SetName(const std::string& name)
330 {
331   mName = name;
332
333   if( NULL != mNode )
334   {
335     // ATTENTION: string for debug purposes is not thread safe.
336     DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
337   }
338 }
339
340 unsigned int Actor::GetId() const
341 {
342   return mId;
343 }
344
345 void Actor::Attach( ActorAttachment& attachment )
346 {
347   DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
348
349   if( OnStage() )
350   {
351     attachment.Connect();
352   }
353
354   mAttachment = ActorAttachmentPtr(&attachment);
355 }
356
357 ActorAttachmentPtr Actor::GetAttachment()
358 {
359   return mAttachment;
360 }
361
362 bool Actor::OnStage() const
363 {
364   return mIsOnStage;
365 }
366
367 Dali::Layer Actor::GetLayer()
368 {
369   Dali::Layer layer;
370
371   // Short-circuit for Layer derived actors
372   if( mIsLayer )
373   {
374     layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
375   }
376
377   // Find the immediate Layer parent
378   for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
379   {
380     if( parent->IsLayer() )
381     {
382       layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
383     }
384   }
385
386   return layer;
387 }
388
389 void Actor::Add(Actor& child)
390 {
391   DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
392   DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
393
394   if( !mChildren )
395   {
396     mChildren = new ActorContainer;
397   }
398
399   Actor* const oldParent( child.mParent );
400
401   // child might already be ours
402   if( this != oldParent )
403   {
404     // if we already have parent, unparent us first
405     if( oldParent )
406     {
407       oldParent->Remove( child ); // This causes OnChildRemove callback
408     }
409
410     // Guard against Add() during previous OnChildRemove callback
411     if ( !child.mParent )
412     {
413       // Do this first, since user callbacks from within SetParent() may need to remove child
414       mChildren->push_back(Dali::Actor(&child));
415
416       // SetParent asserts that child can be added
417       child.SetParent(this);
418
419       // Notification for derived classes
420       OnChildAdd(child);
421     }
422   }
423 }
424
425 void Actor::Remove(Actor& child)
426 {
427   DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
428
429   Dali::Actor removed;
430
431   if( !mChildren )
432   {
433     // no children
434     return;
435   }
436
437   // Find the child in mChildren, and unparent it
438   ActorIter end = mChildren->end();
439   for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
440   {
441     Actor& actor = GetImplementation(*iter);
442
443     if( &actor == &child )
444     {
445       // Keep handle for OnChildRemove notification
446       removed = Dali::Actor( &actor );
447
448       // Do this first, since user callbacks from within SetParent() may need to add the child
449       mChildren->erase(iter);
450
451       DALI_ASSERT_DEBUG( actor.GetParent() == this );
452       actor.SetParent( NULL );
453
454       break;
455     }
456   }
457
458   if ( removed )
459   {
460     // Notification for derived classes
461     OnChildRemove( GetImplementation(removed) );
462   }
463 }
464
465 void Actor::Unparent()
466 {
467   if( mParent )
468   {
469     mParent->Remove( *this );
470   }
471 }
472
473 unsigned int Actor::GetChildCount() const
474 {
475   return ( NULL != mChildren ) ? mChildren->size() : 0;
476 }
477
478 Dali::Actor Actor::GetChildAt(unsigned int index) const
479 {
480   DALI_ASSERT_ALWAYS( index < GetChildCount() );
481
482   return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
483 }
484
485 ActorContainer Actor::GetChildren()
486 {
487   if( NULL != mChildren )
488   {
489     return *mChildren;
490   }
491
492   // return copy of mNullChildren
493   return mNullChildren;
494 }
495
496 const ActorContainer& Actor::GetChildren() const
497 {
498   if( NULL != mChildren )
499   {
500     return *mChildren;
501   }
502
503   // return const reference to mNullChildren
504   return mNullChildren;
505 }
506
507 ActorPtr Actor::FindChildByName(const std::string& actorName)
508 {
509   ActorPtr child=0;
510   if (actorName == mName)
511   {
512     child = this;
513   }
514   else if( mChildren )
515   {
516     ActorIter end = mChildren->end();
517     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
518     {
519       child = GetImplementation(*iter).FindChildByName(actorName);
520
521       if (child)
522       {
523         break;
524       }
525     }
526   }
527   return child;
528 }
529
530 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
531 {
532   Dali::Actor child = DoGetChildByAlias(actorAlias);
533
534   // If not found then search by name.
535   if (!child)
536   {
537     Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
538     if (child_ptr)
539     {
540       child = Dali::Actor(child_ptr.Get());
541     }
542   }
543
544   return child;
545 }
546
547 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
548 {
549   Dali::Actor child = GetChildByAlias(actorAlias);
550
551   if (!child && mChildren )
552   {
553     ActorIter end = mChildren->end();
554     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
555     {
556       child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
557
558       if (child)
559       {
560         break;
561       }
562     }
563   }
564
565   return child;
566 }
567
568 ActorPtr Actor::FindChildById(const unsigned int id)
569 {
570   ActorPtr child = 0;
571   if (id == mId)
572   {
573     child = this;
574   }
575   else if( mChildren )
576   {
577     ActorIter end = mChildren->end();
578     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
579     {
580       child = GetImplementation(*iter).FindChildById(id);
581
582       if (child)
583       {
584         break;
585       }
586     }
587   }
588   return child;
589 }
590
591 void Actor::SetParentOrigin( const Vector3& origin )
592 {
593   if( NULL != mNode )
594   {
595     // mNode is being used in a separate thread; queue a message to set the value & base value
596     SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
597   }
598
599   // Cache for event-thread access
600   if( !mParentOrigin )
601   {
602     // not allocated, check if different from default
603     if( ParentOrigin::DEFAULT != origin )
604     {
605       mParentOrigin = new Vector3( origin );
606     }
607   }
608   else
609   {
610     // check if different from current costs more than just set
611     *mParentOrigin = origin;
612   }
613 }
614
615 void Actor::SetParentOriginX( float x )
616 {
617   const Vector3& current = GetCurrentParentOrigin();
618
619   SetParentOrigin( Vector3( x, current.y, current.z ) );
620 }
621
622 void Actor::SetParentOriginY( float y )
623 {
624   const Vector3& current = GetCurrentParentOrigin();
625
626   SetParentOrigin( Vector3( current.x, y, current.z ) );
627 }
628
629 void Actor::SetParentOriginZ( float z )
630 {
631   const Vector3& current = GetCurrentParentOrigin();
632
633   SetParentOrigin( Vector3( current.x, current.y, z ) );
634 }
635
636 const Vector3& Actor::GetCurrentParentOrigin() const
637 {
638   // Cached for event-thread access
639   return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
640 }
641
642 void Actor::SetAnchorPoint(const Vector3& anchor)
643 {
644   if( NULL != mNode )
645   {
646     // mNode is being used in a separate thread; queue a message to set the value & base value
647     SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
648   }
649
650   // Cache for event-thread access
651   if( !mAnchorPoint )
652   {
653     // not allocated, check if different from default
654     if( AnchorPoint::DEFAULT != anchor )
655     {
656       mAnchorPoint = new Vector3( anchor );
657     }
658   }
659   else
660   {
661     // check if different from current costs more than just set
662     *mAnchorPoint = anchor;
663   }
664 }
665
666 void Actor::SetAnchorPointX( float x )
667 {
668   const Vector3& current = GetCurrentAnchorPoint();
669
670   SetAnchorPoint( Vector3( x, current.y, current.z ) );
671 }
672
673 void Actor::SetAnchorPointY( float y )
674 {
675   const Vector3& current = GetCurrentAnchorPoint();
676
677   SetAnchorPoint( Vector3( current.x, y, current.z ) );
678 }
679
680 void Actor::SetAnchorPointZ( float z )
681 {
682   const Vector3& current = GetCurrentAnchorPoint();
683
684   SetAnchorPoint( Vector3( current.x, current.y, z ) );
685 }
686
687 const Vector3& Actor::GetCurrentAnchorPoint() const
688 {
689   // Cached for event-thread access
690   return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
691 }
692
693 void Actor::SetPosition(float x, float y)
694 {
695   SetPosition(Vector3(x, y, 0.0f));
696 }
697
698 void Actor::SetPosition(float x, float y, float z)
699 {
700   SetPosition(Vector3(x, y, z));
701 }
702
703 void Actor::SetPosition(const Vector3& position)
704 {
705   if( NULL != mNode )
706   {
707     // mNode is being used in a separate thread; queue a message to set the value & base value
708     SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
709   }
710 }
711
712 void Actor::SetX(float x)
713 {
714   if( NULL != mNode )
715   {
716     // mNode is being used in a separate thread; queue a message to set the value & base value
717     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
718   }
719 }
720
721 void Actor::SetY(float y)
722 {
723   if( NULL != mNode )
724   {
725     // mNode is being used in a separate thread; queue a message to set the value & base value
726     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
727   }
728 }
729
730 void Actor::SetZ(float z)
731 {
732   if( NULL != mNode )
733   {
734     // mNode is being used in a separate thread; queue a message to set the value & base value
735     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
736   }
737 }
738
739 void Actor::MoveBy(const Vector3& distance)
740 {
741   if( NULL != mNode )
742   {
743     // mNode is being used in a separate thread; queue a message to set the value & base value
744     SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
745   }
746 }
747
748 const Vector3& Actor::GetCurrentPosition() const
749 {
750   if( NULL != mNode )
751   {
752     // mNode is being used in a separate thread; copy the value from the previous update
753     return mNode->GetPosition(mStage->GetEventBufferIndex());
754   }
755
756   return Vector3::ZERO;
757 }
758
759 const Vector3& Actor::GetCurrentWorldPosition() const
760 {
761   if( NULL != mNode )
762   {
763     // mNode is being used in a separate thread; copy the value from the previous update
764     return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
765   }
766
767   return Vector3::ZERO;
768 }
769
770 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
771 {
772   // this flag is not animatable so keep the value
773   mPositionInheritanceMode = mode;
774   if( NULL != mNode )
775   {
776     // mNode is being used in a separate thread; queue a message to set the value
777     SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
778   }
779 }
780
781 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
782 {
783   // Cached for event-thread access
784   return mPositionInheritanceMode;
785 }
786
787 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
788 {
789   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
790   normalizedAxis.Normalize();
791
792   Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
793
794   SetRotation(rotation);
795 }
796
797 void Actor::SetRotation(const Quaternion& rotation)
798 {
799   if( NULL != mNode )
800   {
801     // mNode is being used in a separate thread; queue a message to set the value & base value
802     SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
803   }
804 }
805
806 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
807 {
808   if( NULL != mNode )
809   {
810     // mNode is being used in a separate thread; queue a message to set the value & base value
811     SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
812   }
813 }
814
815 void Actor::RotateBy(const Quaternion& relativeRotation)
816 {
817   if( NULL != mNode )
818   {
819     // mNode is being used in a separate thread; queue a message to set the value & base value
820     SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
821   }
822 }
823
824 const Quaternion& Actor::GetCurrentRotation() const
825 {
826   if( NULL != mNode )
827   {
828     // mNode is being used in a separate thread; copy the value from the previous update
829     return mNode->GetRotation(mStage->GetEventBufferIndex());
830   }
831
832   return Quaternion::IDENTITY;
833 }
834
835 const Quaternion& Actor::GetCurrentWorldRotation() const
836 {
837   if( NULL != mNode )
838   {
839     // mNode is being used in a separate thread; copy the value from the previous update
840     return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
841   }
842
843   return Quaternion::IDENTITY;
844 }
845
846 void Actor::SetScale(float scale)
847 {
848   SetScale(Vector3(scale, scale, scale));
849 }
850
851 void Actor::SetScale(float x, float y, float z)
852 {
853   SetScale(Vector3(x, y, z));
854 }
855
856 void Actor::SetScale(const Vector3& scale)
857 {
858   if( NULL != mNode )
859   {
860     // mNode is being used in a separate thread; queue a message to set the value & base value
861     SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
862   }
863 }
864
865 void Actor::SetScaleX( float x )
866 {
867   if( NULL != mNode )
868   {
869     // mNode is being used in a separate thread; queue a message to set the value & base value
870     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
871   }
872 }
873
874 void Actor::SetScaleY( float y )
875 {
876   if( NULL != mNode )
877   {
878     // mNode is being used in a separate thread; queue a message to set the value & base value
879     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
880   }
881 }
882
883 void Actor::SetScaleZ( float z )
884 {
885   if( NULL != mNode )
886   {
887     // mNode is being used in a separate thread; queue a message to set the value & base value
888     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
889   }
890 }
891
892 void Actor::SetInitialVolume(const Vector3& volume)
893 {
894   if( NULL != mNode )
895   {
896     // mNode is being used in a separate thread; queue a message to set the value
897     SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
898   }
899 }
900
901 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
902 {
903   if( NULL != mNode )
904   {
905     // mNode is being used in a separate thread; queue a message to set the value
906     SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
907   }
908 }
909
910 bool Actor::GetTransmitGeometryScaling() const
911 {
912   if( NULL != mNode )
913   {
914     // mNode is being used in a separate thread; copy the value from the previous update
915     return mNode->GetTransmitGeometryScaling();
916   }
917
918   return false;
919 }
920
921 void Actor::ScaleBy(const Vector3& relativeScale)
922 {
923   if( NULL != mNode )
924   {
925     // mNode is being used in a separate thread; queue a message to set the value & base value
926     SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
927   }
928 }
929
930 const Vector3& Actor::GetCurrentScale() const
931 {
932   if( NULL != mNode )
933   {
934     // mNode is being used in a separate thread; copy the value from the previous update
935     return mNode->GetScale(mStage->GetEventBufferIndex());
936   }
937
938   return Vector3::ONE;
939 }
940
941 const Vector3& Actor::GetCurrentWorldScale() const
942 {
943   if( NULL != mNode )
944   {
945     // mNode is being used in a separate thread; copy the value from the previous update
946     return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
947   }
948
949   return Vector3::ONE;
950 }
951
952 void Actor::SetInheritScale( bool inherit )
953 {
954   // non animateable so keep local copy
955   mInheritScale = inherit;
956   if( NULL != mNode )
957   {
958     // mNode is being used in a separate thread; queue a message to set the value
959     SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
960   }
961 }
962
963 bool Actor::IsScaleInherited() const
964 {
965   return mInheritScale;
966 }
967
968 Matrix Actor::GetCurrentWorldMatrix() const
969 {
970   if( NULL != mNode )
971   {
972     // World matrix is no longer updated unless there is something observing the node.
973     // Need to calculate it from node's world position, rotation and scale:
974     BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
975     Matrix worldMatrix(false);
976     worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
977                                         mNode->GetWorldRotation( updateBufferIndex ),
978                                         mNode->GetWorldPosition( updateBufferIndex ) );
979     return worldMatrix;
980   }
981
982   return Matrix::IDENTITY;
983 }
984
985 void Actor::SetVisible(bool visible)
986 {
987   if( NULL != mNode )
988   {
989     // mNode is being used in a separate thread; queue a message to set the value & base value
990     SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
991   }
992 }
993
994 bool Actor::IsVisible() const
995 {
996   if( NULL != mNode )
997   {
998     // mNode is being used in a separate thread; copy the value from the previous update
999     return mNode->IsVisible( mStage->GetEventBufferIndex() );
1000   }
1001
1002   return true;
1003 }
1004
1005 void Actor::SetOpacity(float opacity)
1006 {
1007   if( NULL != mNode )
1008   {
1009     // mNode is being used in a separate thread; queue a message to set the value & base value
1010     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1011   }
1012 }
1013
1014 void Actor::OpacityBy(float relativeOpacity)
1015 {
1016   if( NULL != mNode )
1017   {
1018     // mNode is being used in a separate thread; queue a message to set the value & base value
1019     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
1020   }
1021 }
1022
1023 float Actor::GetCurrentOpacity() const
1024 {
1025   if( NULL != mNode )
1026   {
1027     // mNode is being used in a separate thread; copy the value from the previous update
1028     return mNode->GetOpacity(mStage->GetEventBufferIndex());
1029   }
1030
1031   return 1.0f;
1032 }
1033
1034 const Vector4& Actor::GetCurrentWorldColor() const
1035 {
1036   if( NULL != mNode )
1037   {
1038     return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
1039   }
1040
1041   return Color::WHITE;
1042 }
1043
1044 void Actor::SetColor(const Vector4& color)
1045 {
1046   if( NULL != mNode )
1047   {
1048     // mNode is being used in a separate thread; queue a message to set the value & base value
1049     SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1050   }
1051 }
1052
1053 void Actor::SetColorRed( float red )
1054 {
1055   if( NULL != mNode )
1056   {
1057     // mNode is being used in a separate thread; queue a message to set the value & base value
1058     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1059   }
1060 }
1061
1062 void Actor::SetColorGreen( float green )
1063 {
1064   if( NULL != mNode )
1065   {
1066     // mNode is being used in a separate thread; queue a message to set the value & base value
1067     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1068   }
1069 }
1070
1071 void Actor::SetColorBlue( float blue )
1072 {
1073   if( NULL != mNode )
1074   {
1075     // mNode is being used in a separate thread; queue a message to set the value & base value
1076     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1077   }
1078 }
1079
1080 void Actor::ColorBy(const Vector4& relativeColor)
1081 {
1082   if( NULL != mNode )
1083   {
1084     // mNode is being used in a separate thread; queue a message to set the value & base value
1085     SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1086   }
1087 }
1088
1089 const Vector4& Actor::GetCurrentColor() const
1090 {
1091   if( NULL != mNode )
1092   {
1093     // mNode is being used in a separate thread; copy the value from the previous update
1094     return mNode->GetColor(mStage->GetEventBufferIndex());
1095   }
1096
1097   return Color::WHITE;
1098 }
1099
1100 void Actor::SetInheritRotation(bool inherit)
1101 {
1102   // non animateable so keep local copy
1103   mInheritRotation = inherit;
1104   if( NULL != mNode )
1105   {
1106     // mNode is being used in a separate thread; queue a message to set the value
1107     SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1108   }
1109 }
1110
1111 bool Actor::IsRotationInherited() const
1112 {
1113   return mInheritRotation;
1114 }
1115
1116 void Actor::SetColorMode(ColorMode colorMode)
1117 {
1118   // non animateable so keep local copy
1119   mColorMode = colorMode;
1120   if( NULL != mNode )
1121   {
1122     // mNode is being used in a separate thread; queue a message to set the value
1123     SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1124   }
1125 }
1126
1127 ColorMode Actor::GetColorMode() const
1128 {
1129   // we have cached copy
1130   return mColorMode;
1131 }
1132
1133 void Actor::SetSize(float width, float height)
1134 {
1135   SetSize( Vector2( width, height ) );
1136 }
1137
1138 void Actor::SetSize(float width, float height, float depth)
1139 {
1140   SetSize( Vector3( width, height, depth ) );
1141 }
1142
1143 void Actor::SetSize(const Vector2& size)
1144 {
1145   Vector3 volume( size );
1146   volume.z = std::min( size.width, size.height );
1147   SetSize( volume );
1148 }
1149
1150 void Actor::SetSize(const Vector3& size)
1151 {
1152   if( NULL != mNode )
1153   {
1154     // mNode is being used in a separate thread; queue a message to set the value & base value
1155     SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1156
1157     // Notification for derived classes
1158     OnSizeSet(size);
1159
1160     // Emit signal for application developer
1161
1162     if( !mSetSizeSignalV2.Empty() )
1163     {
1164       Dali::Actor handle( this );
1165       mSetSizeSignalV2.Emit( handle, size );
1166     }
1167   }
1168 }
1169
1170 void Actor::SetWidth( float width )
1171 {
1172   if( NULL != mNode )
1173   {
1174     // mNode is being used in a separate thread; queue a message to set the value & base value
1175     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1176   }
1177 }
1178
1179 void Actor::SetHeight( float height )
1180 {
1181   if( NULL != mNode )
1182   {
1183     // mNode is being used in a separate thread; queue a message to set the value & base value
1184     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1185   }
1186 }
1187
1188 void Actor::SetDepth( float depth )
1189 {
1190   if( NULL != mNode )
1191   {
1192     // mNode is being used in a separate thread; queue a message to set the value & base value
1193     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1194   }
1195 }
1196
1197 const Vector3& Actor::GetCurrentSize() const
1198 {
1199   if( NULL != mNode )
1200   {
1201     // mNode is being used in a separate thread; copy the value from the previous update
1202     return mNode->GetSize( mStage->GetEventBufferIndex() );
1203   }
1204
1205   return Vector3::ZERO;
1206 }
1207
1208 void Actor::SetInheritShaderEffect(bool inherit)
1209 {
1210   if( NULL != mNode )
1211   {
1212     // mNode is being used in a separate thread; queue a message to set the value
1213     SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1214   }
1215 }
1216
1217 bool Actor::GetInheritShaderEffect() const
1218 {
1219   if( NULL != mNode )
1220   {
1221     // mNode is being used in a separate thread; copy the value from the previous update
1222     return mNode->GetInheritShader();
1223   }
1224
1225   return true;
1226 }
1227
1228 void Actor::SetShaderEffect(ShaderEffect& effect)
1229 {
1230   if ( OnStage() )
1231   {
1232     if (mShaderEffect)
1233     {
1234       mShaderEffect->Disconnect();
1235     }
1236
1237     mShaderEffect = ShaderEffectPtr(&effect);
1238
1239     const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
1240
1241     if( NULL != mNode )
1242     {
1243       // mNode is being used in a separate thread; queue a message to apply shader
1244       ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
1245     }
1246
1247     mShaderEffect->Connect();
1248   }
1249   else
1250   {
1251     mShaderEffect = ShaderEffectPtr(&effect);
1252   }
1253   // Effects can only be applied when the Node is connected to scene-graph
1254 }
1255
1256 ShaderEffectPtr Actor::GetShaderEffect() const
1257 {
1258   return mShaderEffect;
1259 }
1260
1261 void Actor::RemoveShaderEffect()
1262 {
1263   if ( OnStage() )
1264   {
1265     if( NULL != mNode )
1266     {
1267       // mNode is being used in a separate thread; queue a message to remove shader
1268       RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
1269     }
1270
1271     // Notify shader effect
1272     if (mShaderEffect)
1273     {
1274       mShaderEffect->Disconnect();
1275     }
1276   }
1277
1278   mShaderEffect.Reset();
1279 }
1280
1281 #ifdef DYNAMICS_SUPPORT
1282
1283 //--------------- Dynamics ---------------
1284
1285 void Actor::DisableDynamics()
1286 {
1287   if( NULL != mDynamicsData )
1288   {
1289     DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1290
1291     // ensure dynamics object are disconnected from scene
1292     DisconnectDynamics();
1293
1294     // delete joint owned by this actor
1295     while( !mDynamicsData->joints.empty() )
1296     {
1297       RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1298     }
1299
1300     // delete other joints referencing this actor
1301     while( !mDynamicsData->referencedJoints.empty() )
1302     {
1303       DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1304       ActorPtr jointOwner( joint->GetActor( true ) );
1305       if( jointOwner )
1306       {
1307         jointOwner->RemoveDynamicsJoint( joint );
1308       }
1309       else
1310       {
1311         mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1312       }
1313     }
1314     // delete the DynamicsBody object
1315     mDynamicsData->body.Reset();
1316
1317     // Discard Dynamics data structure
1318     delete mDynamicsData;
1319     mDynamicsData = NULL;
1320   }
1321 }
1322
1323 DynamicsBodyPtr Actor::GetDynamicsBody() const
1324 {
1325   DynamicsBodyPtr body;
1326
1327   if( NULL != mDynamicsData )
1328   {
1329     body = mDynamicsData->body;
1330   }
1331
1332   return body;
1333 }
1334
1335 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1336 {
1337   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1338
1339   if( NULL == mDynamicsData )
1340   {
1341     mDynamicsData = new DynamicsData( this );
1342   }
1343
1344   if( !mDynamicsData->body )
1345   {
1346     mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1347
1348     if( OnStage() )
1349     {
1350       DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1351       if( world )
1352       {
1353         if( mParent == world->GetRootActor().Get() )
1354         {
1355           mDynamicsData->body->Connect(*mStage);
1356         }
1357       }
1358     }
1359   }
1360
1361   return mDynamicsData->body;
1362 }
1363
1364 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1365 {
1366   DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1367   return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1368 }
1369
1370 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1371 {
1372   DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1373   DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1374
1375   DynamicsJointPtr joint;
1376
1377   DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1378
1379   if( world )
1380   {
1381     if( NULL != mDynamicsData )
1382     {
1383       DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1384
1385       if( mDynamicsData->joints.end() != it )
1386       {
1387         // use existing joint
1388         joint = it->second;
1389       }
1390
1391       if( !joint )
1392       {
1393         DynamicsBodyPtr bodyA( GetDynamicsBody() );
1394         DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1395
1396         if( !bodyA )
1397         {
1398           bodyA = EnableDynamics( new DynamicsBodyConfig );
1399         }
1400
1401         if( !bodyB )
1402         {
1403           bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1404         }
1405
1406         joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1407         mDynamicsData->joints[ attachedActor.Get() ] = joint;
1408
1409         if( OnStage() && attachedActor->OnStage() )
1410         {
1411           joint->Connect(*mStage);
1412         }
1413
1414         attachedActor->ReferenceJoint( joint );
1415
1416         attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1417         attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1418       }
1419     }
1420   }
1421   return joint;
1422 }
1423
1424 const int Actor::GetNumberOfJoints() const
1425 {
1426   return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1427 }
1428
1429 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1430 {
1431   DynamicsJointPtr joint;
1432
1433   if( NULL != mDynamicsData )
1434   {
1435     if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1436     {
1437       DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1438
1439       for( int i = 0; i < index; ++i  )
1440       {
1441         ++it;
1442       }
1443
1444       joint = it->second;
1445     }
1446   }
1447
1448   return joint;
1449 }
1450
1451 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1452 {
1453   DynamicsJointPtr joint;
1454
1455   if( NULL != mDynamicsData )
1456   {
1457     DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1458
1459     if( mDynamicsData->joints.end() != it )
1460     {
1461       // use existing joint
1462       joint = it->second;
1463     }
1464   }
1465
1466   return joint;
1467 }
1468
1469 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1470 {
1471   if( NULL != mDynamicsData )
1472   {
1473     DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1474     DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1475
1476     for( ; it != endIt; ++it )
1477     {
1478       if( it->second == joint.Get() )
1479       {
1480         ActorPtr attachedActor( it->first );
1481
1482         if( OnStage() && attachedActor && attachedActor->OnStage() )
1483         {
1484           joint->Disconnect(*mStage);
1485         }
1486
1487         if( attachedActor )
1488         {
1489           attachedActor->ReleaseJoint( joint );
1490           attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1491           attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1492         }
1493
1494         mDynamicsData->joints.erase(it);
1495         break;
1496       }
1497     }
1498   }
1499 }
1500
1501 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1502 {
1503   DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1504
1505   if( NULL != mDynamicsData )
1506   {
1507     mDynamicsData->referencedJoints.push_back(joint);
1508   }
1509 }
1510
1511 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1512 {
1513   DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1514
1515   if( NULL != mDynamicsData )
1516   {
1517     DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1518
1519     if( it != mDynamicsData->referencedJoints.end() )
1520     {
1521       mDynamicsData->referencedJoints.erase( it );
1522     }
1523   }
1524 }
1525
1526 void Actor::SetDynamicsRoot(bool flag)
1527 {
1528   if( mIsDynamicsRoot != flag )
1529   {
1530     mIsDynamicsRoot = flag;
1531
1532     if( OnStage() && mChildren )
1533     {
1534       // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1535       ActorIter end = mChildren->end();
1536       for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1537       {
1538         Actor& child = GetImplementation(*iter);
1539
1540         if( child.GetDynamicsBody() )
1541         {
1542           if( mIsDynamicsRoot )
1543           {
1544             child.ConnectDynamics();
1545           }
1546           else
1547           {
1548             child.DisconnectDynamics();
1549           }
1550         }
1551       }
1552     }
1553   }
1554 }
1555
1556 bool Actor::IsDynamicsRoot() const
1557 {
1558   return mIsDynamicsRoot;
1559 }
1560
1561 void Actor::AttachedActorOnStage( Dali::Actor actor )
1562 {
1563   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1564
1565   if( OnStage() )
1566   {
1567     ActorPtr attachedActor( &GetImplementation(actor) );
1568
1569     DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1570     if( NULL != mDynamicsData )
1571     {
1572       DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find(  attachedActor.Get() ) );
1573       if( mDynamicsData->joints.end() != it )
1574       {
1575         DynamicsJointPtr joint( it->second );
1576         joint->Connect(*mStage);
1577       }
1578     }
1579   }
1580 }
1581
1582 void Actor::AttachedActorOffStage( Dali::Actor actor )
1583 {
1584   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1585
1586   if( OnStage() )
1587   {
1588     ActorPtr attachedActor( &GetImplementation(actor) );
1589
1590     DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1591     if( NULL != mDynamicsData )
1592     {
1593       DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find(  attachedActor.Get() ) );
1594       if( mDynamicsData->joints.end() != it )
1595       {
1596         DynamicsJointPtr joint( it->second );
1597         joint->Disconnect(*mStage);
1598       }
1599     }
1600   }
1601 }
1602
1603 void Actor::ConnectDynamics()
1604 {
1605   if( NULL != mDynamicsData && mDynamicsData->body )
1606   {
1607     if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1608     {
1609       mDynamicsData->body->Connect(*mStage);
1610
1611       // Connect all joints where attachedActor is also on stage
1612       if( !mDynamicsData->joints.empty() )
1613       {
1614         DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1615         DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1616
1617         for( ; it != endIt; ++it )
1618         {
1619           Actor* attachedActor( it->first );
1620           if( NULL != attachedActor && attachedActor->OnStage() )
1621           {
1622             DynamicsJointPtr joint( it->second );
1623
1624             joint->Connect(*mStage);
1625           }
1626         }
1627       }
1628     }
1629   }
1630 }
1631
1632 void Actor::DisconnectDynamics()
1633 {
1634   if( NULL != mDynamicsData && mDynamicsData->body )
1635   {
1636     if( OnStage() )
1637     {
1638       mDynamicsData->body->Disconnect(*mStage);
1639
1640       // Disconnect all joints
1641       if( !mDynamicsData->joints.empty() )
1642       {
1643         DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1644         DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1645
1646         for( ; it != endIt; ++it )
1647         {
1648           DynamicsJointPtr joint( it->second );
1649
1650           joint->Disconnect(*mStage);
1651         }
1652       }
1653     }
1654   }
1655 }
1656
1657 #endif // DYNAMICS_SUPPORT
1658
1659 void Actor::SetOverlay(bool enable)
1660 {
1661   // Setting STENCIL will override OVERLAY
1662   if( DrawMode::STENCIL != mDrawMode )
1663   {
1664     SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1665   }
1666 }
1667
1668 bool Actor::IsOverlay() const
1669 {
1670   return ( DrawMode::OVERLAY == mDrawMode );
1671 }
1672
1673 void Actor::SetDrawMode( DrawMode::Type drawMode )
1674 {
1675   // this flag is not animatable so keep the value
1676   mDrawMode = drawMode;
1677   if( NULL != mNode )
1678   {
1679     // mNode is being used in a separate thread; queue a message to set the value
1680     SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1681   }
1682 }
1683
1684 DrawMode::Type Actor::GetDrawMode() const
1685 {
1686   return mDrawMode;
1687 }
1688
1689 bool Actor::ScreenToLocal( float& localX,
1690                            float& localY,
1691                            float screenX,
1692                            float screenY ) const
1693 {
1694   // only valid when on-stage
1695   if ( OnStage() )
1696   {
1697     const RenderTaskList& taskList = mStage->GetRenderTaskList();
1698
1699     Vector2 converted( screenX, screenY );
1700
1701     // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1702     const int taskCount = taskList.GetTaskCount();
1703     for( int i = taskCount - 1; i >= 0; --i )
1704     {
1705       Dali::RenderTask task = taskList.GetTask( i );
1706       if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1707       {
1708         // found a task where this conversion was ok so return
1709         return true;
1710       }
1711     }
1712   }
1713   return false;
1714 }
1715
1716 bool Actor::ScreenToLocal( RenderTask& renderTask,
1717                            float& localX,
1718                            float& localY,
1719                            float screenX,
1720                            float screenY ) const
1721 {
1722   bool retval = false;
1723   // only valid when on-stage
1724   if ( OnStage() )
1725   {
1726     CameraActor* camera = renderTask.GetCameraActor();
1727     if( camera )
1728     {
1729       Viewport viewport;
1730       renderTask.GetViewport( viewport );
1731
1732       // need to translate coordinates to render tasks coordinate space
1733       Vector2 converted( screenX, screenY );
1734       if( renderTask.TranslateCoordinates( converted ) )
1735       {
1736         retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1737       }
1738     }
1739   }
1740   return retval;
1741 }
1742
1743 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1744                            const Matrix& projectionMatrix,
1745                            const Viewport& viewport,
1746                            float& localX,
1747                            float& localY,
1748                            float screenX,
1749                            float screenY ) const
1750 {
1751   // Early-out if mNode is NULL
1752   if( !OnStage() )
1753   {
1754     return false;
1755   }
1756
1757   BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1758
1759   // Calculate the ModelView matrix
1760   Matrix modelView(false/*don't init*/);
1761   // need to use the components as world matrix is only updated for actors that need it
1762   modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1763   Matrix::Multiply(modelView, modelView, viewMatrix);
1764
1765   // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1766   Matrix invertedMvp(false/*don't init*/);
1767   Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1768   bool success = invertedMvp.Invert();
1769
1770   // Convert to GL coordinates
1771   Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1772
1773   Vector4 nearPos;
1774   if (success)
1775   {
1776     success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1777   }
1778
1779   Vector4 farPos;
1780   if (success)
1781   {
1782     screenPos.z = 1.0f;
1783     success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1784   }
1785
1786   if (success)
1787   {
1788     Vector4 local;
1789     if (XyPlaneIntersect(nearPos, farPos, local))
1790     {
1791       Vector3 size = GetCurrentSize();
1792       localX = local.x + size.x * 0.5f;
1793       localY = local.y + size.y * 0.5f;
1794     }
1795     else
1796     {
1797       success = false;
1798     }
1799   }
1800
1801   return success;
1802 }
1803
1804 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1805 {
1806   /*
1807     http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1808
1809     Mathematical Formulation
1810
1811     Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1812
1813     ( p - c ) dot ( p - c ) = r^2
1814
1815     Given a ray with a point of origin 'o', and a direction vector 'd':
1816
1817     ray(t) = o + td, t >= 0
1818
1819     we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1820
1821     (o + td - c ) dot ( o + td - c ) = r^2
1822
1823     To solve for t we first expand the above into a more recognisable quadratic equation form
1824
1825     ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1826
1827     or
1828
1829     At2 + Bt + C = 0
1830
1831     where
1832
1833     A = d dot d
1834     B = 2( o - c ) dot d
1835     C = ( o - c ) dot ( o - c ) - r^2
1836
1837     which can be solved using a standard quadratic formula.
1838
1839     Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1840
1841     Practical Simplification
1842
1843     In a renderer, we often differentiate between world space and object space. In the object space
1844     of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1845     into object space, the mathematical solution presented above can be simplified significantly.
1846
1847     If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1848
1849     p dot p = r^2
1850
1851     and we can find the t at which the (transformed) ray intersects the sphere by
1852
1853     ( o + td ) dot ( o + td ) = r^2
1854
1855     According to the reasoning above, we expand the above quadratic equation into the general form
1856
1857     At2 + Bt + C = 0
1858
1859     which now has coefficients:
1860
1861     A = d dot d
1862     B = 2( d dot o )
1863     C = o dot o - r^2
1864    */
1865
1866   // Early out if mNode is NULL
1867   if( !mNode )
1868   {
1869     return false;
1870   }
1871
1872   BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1873
1874   // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1875   const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1876   Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1877                          rayOrigin.y - translation.y,
1878                          rayOrigin.z - translation.z);
1879
1880   // Compute the radius is not needed, square radius it's enough.
1881   const Vector3& size( mNode->GetSize( bufferIndex ) );
1882
1883   // Scale the sphere.
1884   const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1885
1886   const float width = size.width * scale.width;
1887   const float height = size.height * scale.height;
1888
1889   float squareSphereRadius = 0.5f * ( width * width + height * height );
1890
1891   float a = rayDir.Dot( rayDir );                                       // a
1892   float b2 = rayDir.Dot( rayOriginLocal );                              // b/2
1893   float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius;  // c
1894
1895   return ( b2*b2 - a*c ) >= 0.f;
1896 }
1897
1898 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1899 {
1900   bool hit = false;
1901
1902   if( OnStage() &&
1903       NULL != mNode )
1904   {
1905     BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1906
1907     // Transforms the ray to the local reference system.
1908
1909     // Calculate the inverse of Model matrix
1910     Matrix invModelMatrix(false/*don't init*/);
1911     // need to use the components as world matrix is only updated for actors that need it
1912     invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1913
1914     Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1915     Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1916
1917     // Test with the actor's XY plane (Normal = 0 0 1 1).
1918
1919     float a = -rayOriginLocal.z;
1920     float b = rayDirLocal.z;
1921
1922     if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1923     {
1924       // Ray travels distance * rayDirLocal to intersect with plane.
1925       distance = a / b;
1926
1927       const Vector3& size = mNode->GetSize( bufferIndex );
1928
1929       hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1930       hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1931
1932       // Test with the actor's geometry.
1933       hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1934     }
1935   }
1936
1937   return hit;
1938 }
1939
1940 void Actor::SetLeaveRequired(bool required)
1941 {
1942   mLeaveRequired = required;
1943 }
1944
1945 bool Actor::GetLeaveRequired() const
1946 {
1947   return mLeaveRequired;
1948 }
1949
1950 void Actor::SetKeyboardFocusable( bool focusable )
1951 {
1952   mKeyboardFocusable = focusable;
1953 }
1954
1955 bool Actor::IsKeyboardFocusable() const
1956 {
1957   return mKeyboardFocusable;
1958 }
1959
1960 bool Actor::GetTouchRequired() const
1961 {
1962   return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1963 }
1964
1965 bool Actor::GetMouseWheelEventRequired() const
1966 {
1967   return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1968 }
1969
1970 bool Actor::IsHittable() const
1971 {
1972   return IsSensitive() &&
1973          IsVisible() &&
1974          ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1975          IsNodeConnected();
1976 }
1977
1978 void Actor::AddGestureDetector( GestureDetector& detector )
1979 {
1980   if ( NULL == mGestureData )
1981   {
1982     mGestureData = new GestureData;
1983   }
1984
1985   const Gesture::Type type( detector.GetType() );
1986   switch ( type )
1987   {
1988     case Gesture::Pan:
1989     {
1990       mGestureData->AddDetector< PanGestureDetector, PanGestureDetectorContainer >( mGestureData->panDetectors, &detector );
1991       break;
1992     }
1993
1994     case Gesture::Pinch:
1995     {
1996       mGestureData->AddDetector< PinchGestureDetector, PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector );
1997       break;
1998     }
1999
2000     case Gesture::LongPress:
2001     {
2002       mGestureData->AddDetector< LongPressGestureDetector, LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector );
2003       break;
2004     }
2005
2006     case Gesture::Tap:
2007     {
2008       mGestureData->AddDetector< TapGestureDetector, TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector );
2009       break;
2010     }
2011   }
2012 }
2013
2014 void Actor::RemoveGestureDetector( GestureDetector& detector )
2015 {
2016   if ( NULL != mGestureData )
2017   {
2018     switch ( detector.GetType() )
2019     {
2020       case Gesture::Pan:
2021       {
2022         mGestureData->RemoveDetector< PanGestureDetectorContainer >( mGestureData->panDetectors, &detector );
2023         break;
2024       }
2025
2026       case Gesture::Pinch:
2027       {
2028         mGestureData->RemoveDetector< PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector );
2029         break;
2030       }
2031
2032       case Gesture::LongPress:
2033       {
2034         mGestureData->RemoveDetector< LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector );
2035         break;
2036       }
2037
2038       case Gesture::Tap:
2039       {
2040         mGestureData->RemoveDetector< TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector );
2041         break;
2042       }
2043     }
2044
2045     if ( mGestureData->Empty() )
2046     {
2047       delete mGestureData;
2048       mGestureData = NULL;
2049     }
2050   }
2051 }
2052
2053 bool Actor::IsGestureRequred( Gesture::Type type ) const
2054 {
2055   bool required( false );
2056   if ( NULL != mGestureData )
2057   {
2058     required = type & mGestureData->gesturesRequired;
2059   }
2060   return required;
2061 }
2062
2063 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
2064 {
2065   bool consumed = false;
2066
2067   if ( !mTouchedSignalV2.Empty() )
2068   {
2069     Dali::Actor handle( this );
2070     consumed = mTouchedSignalV2.Emit( handle, event );
2071   }
2072
2073   if (!consumed)
2074   {
2075     // Notification for derived classes
2076     consumed = OnTouchEvent( event );
2077   }
2078
2079   return consumed;
2080 }
2081
2082 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
2083 {
2084   bool consumed = false;
2085
2086   if ( !mMouseWheelEventSignalV2.Empty() )
2087   {
2088     Dali::Actor handle( this );
2089     consumed = mMouseWheelEventSignalV2.Emit( handle, event );
2090   }
2091
2092   if (!consumed)
2093   {
2094     // Notification for derived classes
2095     consumed = OnMouseWheelEvent(event);
2096   }
2097
2098   return consumed;
2099 }
2100
2101 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
2102 {
2103   return mTouchedSignalV2;
2104 }
2105
2106 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
2107 {
2108   return mMouseWheelEventSignalV2;
2109 }
2110
2111 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
2112 {
2113   return mSetSizeSignalV2;
2114 }
2115
2116 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
2117 {
2118   return mOnStageSignalV2;
2119 }
2120
2121 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
2122 {
2123   return mOffStageSignalV2;
2124 }
2125
2126 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2127 {
2128   bool connected( true );
2129   Actor* actor = dynamic_cast<Actor*>(object);
2130
2131   if(Dali::Actor::SIGNAL_TOUCHED == signalName)
2132   {
2133     actor->TouchedSignal().Connect( tracker, functor );
2134   }
2135   else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
2136   {
2137     actor->MouseWheelEventSignal().Connect( tracker, functor );
2138   }
2139   else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
2140   {
2141     actor->SetSizeSignal().Connect( tracker, functor );
2142   }
2143   else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
2144   {
2145     actor->OnStageSignal().Connect( tracker, functor );
2146   }
2147   else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
2148   {
2149     actor->OffStageSignal().Connect( tracker, functor );
2150   }
2151   else
2152   {
2153     // signalName does not match any signal
2154     connected = false;
2155   }
2156
2157   return connected;
2158 }
2159
2160 Actor::Actor( DerivedType derivedType )
2161 : mStage( NULL ),
2162   mParent( NULL ),
2163   mChildren( NULL ),
2164   mNode( NULL ),
2165   mParentOrigin( NULL ),
2166   mAnchorPoint( NULL ),
2167 #ifdef DYNAMICS_SUPPORT
2168   mDynamicsData( NULL ),
2169 #endif
2170   mGestureData( NULL ),
2171   mAttachment(),
2172   mShaderEffect(),
2173   mName(),
2174   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2175   mIsRoot( ROOT_LAYER == derivedType ),
2176   mIsRenderable( RENDERABLE == derivedType ),
2177   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2178   mIsOnStage( false ),
2179   mIsDynamicsRoot(false),
2180   mSensitive( true ),
2181   mLeaveRequired( false ),
2182   mKeyboardFocusable( false ),
2183   mDerivedRequiresTouch( false ),
2184   mDerivedRequiresMouseWheelEvent( false ),
2185   mOnStageSignalled( false ),
2186   mInheritRotation( true ),
2187   mInheritScale( true ),
2188   mDrawMode( DrawMode::NORMAL ),
2189   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2190   mColorMode( Node::DEFAULT_COLOR_MODE )
2191 {
2192 }
2193
2194 void Actor::Initialize()
2195 {
2196   mStage = Stage::GetCurrent();
2197
2198   // Node creation
2199   SceneGraph::Node* node = CreateNode();
2200
2201   AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2202   mNode = node; // Keep raw-pointer to Node
2203
2204   if(!mDefaultPropertyLookup)
2205   {
2206     mDefaultPropertyLookup = new DefaultPropertyLookup();
2207
2208     for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2209     {
2210       (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2211     }
2212   }
2213
2214   OnInitialize();
2215
2216   RegisterObject();
2217 }
2218
2219 Actor::~Actor()
2220 {
2221   // Remove mParent pointers from children even if we're destroying core,
2222   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2223   if( mChildren )
2224   {
2225     ActorConstIter endIter = mChildren->end();
2226     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2227     {
2228       Actor& actor = GetImplementation( *iter );
2229       actor.SetParent( NULL );
2230     }
2231   }
2232   delete mChildren;
2233
2234   // Guard to allow handle destruction after Core has been destroyed
2235   if( Stage::IsInstalled() )
2236   {
2237     if( NULL != mNode )
2238     {
2239       DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2240       mNode = NULL; // Node is about to be destroyed
2241     }
2242
2243     UnregisterObject();
2244   }
2245
2246 #ifdef DYNAMICS_SUPPORT
2247   // Cleanup dynamics
2248   delete mDynamicsData;
2249 #endif
2250
2251   // Cleanup optional gesture data
2252   delete mGestureData;
2253
2254   // Cleanup optional parent origin and anchor
2255   delete mParentOrigin;
2256   delete mAnchorPoint;
2257 }
2258
2259 void Actor::ConnectToStage( Stage& stage )
2260 {
2261   // This container is used instead of walking the Actor hierachy.
2262   // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2263   ActorContainer connectionList;
2264
2265   // This stage is atomic i.e. not interrupted by user callbacks
2266   RecursiveConnectToStage( stage, connectionList );
2267
2268   // Notify applications about the newly connected actors.
2269   const ActorIter endIter = connectionList.end();
2270   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2271   {
2272     Actor& actor = GetImplementation(*iter);
2273     actor.NotifyStageConnection();
2274   }
2275 }
2276
2277 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2278 {
2279   DALI_ASSERT_ALWAYS( !OnStage() );
2280
2281   mIsOnStage = true;
2282
2283   ConnectToSceneGraph();
2284
2285   // Notification for internal derived classes
2286   OnStageConnectionInternal();
2287
2288   // This stage is atomic; avoid emitting callbacks until all Actors are connected
2289   connectionList.push_back( Dali::Actor(this) );
2290
2291   // Recursively connect children
2292   if( mChildren )
2293   {
2294     ActorConstIter endIter = mChildren->end();
2295     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2296     {
2297       Actor& actor = GetImplementation( *iter );
2298       actor.RecursiveConnectToStage( stage, connectionList );
2299     }
2300   }
2301 }
2302
2303 /**
2304  * This method is called when the Actor is connected to the Stage.
2305  * The parent must have added its Node to the scene-graph.
2306  * The child must connect its Node to the parent's Node.
2307  * This is resursive; the child calls ConnectToStage() for its children.
2308  */
2309 void Actor::ConnectToSceneGraph()
2310 {
2311   DALI_ASSERT_DEBUG( mNode != NULL);
2312   DALI_ASSERT_DEBUG( mParent != NULL);
2313   DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2314
2315   if( NULL != mNode )
2316   {
2317     // Reparent Node in next Update
2318     ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2319   }
2320
2321   if (mShaderEffect)
2322   {
2323     const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
2324
2325     if( NULL != mNode )
2326     {
2327       // Effects can only be applied when the node is on-stage
2328       ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
2329     }
2330
2331     // Notify shader effect
2332     mShaderEffect->Connect();
2333   }
2334
2335   // Notify attachment
2336   if (mAttachment)
2337   {
2338     mAttachment->Connect();
2339   }
2340
2341 #ifdef DYNAMICS_SUPPORT
2342   // Notify dynamics
2343   if( NULL != mDynamicsData )
2344   {
2345     ConnectDynamics();
2346   }
2347 #endif
2348
2349   // Notification for ProxyObject::Observers
2350   OnSceneObjectAdd();
2351 }
2352
2353 void Actor::NotifyStageConnection()
2354 {
2355   // Actors can be removed (in a callback), before the on-stage stage is reported.
2356   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2357   if ( OnStage() && !mOnStageSignalled )
2358   {
2359     // Notification for external (CustomActor) derived classes
2360     OnStageConnectionExternal();
2361
2362     if ( !mOnStageSignalV2.Empty() )
2363     {
2364       Dali::Actor handle( this );
2365       mOnStageSignalV2.Emit( handle );
2366     }
2367
2368     // Guard against Remove during callbacks
2369     if ( OnStage()  )
2370     {
2371       mOnStageSignalled = true; // signal required next time Actor is removed
2372     }
2373   }
2374 }
2375
2376 void Actor::DisconnectFromStage()
2377 {
2378   // This container is used instead of walking the Actor hierachy.
2379   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2380   ActorContainer disconnectionList;
2381
2382   // This stage is atomic i.e. not interrupted by user callbacks
2383   RecursiveDisconnectFromStage( disconnectionList );
2384
2385   // Notify applications about the newly disconnected actors.
2386   const ActorIter endIter = disconnectionList.end();
2387   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2388   {
2389     Actor& actor = GetImplementation(*iter);
2390     actor.NotifyStageDisconnection();
2391   }
2392 }
2393
2394 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2395 {
2396   DALI_ASSERT_ALWAYS( OnStage() );
2397
2398   // Recursively disconnect children
2399   if( mChildren )
2400   {
2401     ActorConstIter endIter = mChildren->end();
2402     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2403     {
2404       Actor& actor = GetImplementation( *iter );
2405       actor.RecursiveDisconnectFromStage( disconnectionList );
2406     }
2407   }
2408
2409   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2410   disconnectionList.push_back( Dali::Actor(this) );
2411
2412   // Notification for internal derived classes
2413   OnStageDisconnectionInternal();
2414
2415   DisconnectFromSceneGraph();
2416
2417   mIsOnStage = false;
2418 }
2419
2420 /**
2421  * This method is called by an actor or its parent, before a node removal message is sent.
2422  * This is recursive; the child calls DisconnectFromStage() for its children.
2423  */
2424 void Actor::DisconnectFromSceneGraph()
2425 {
2426   // Notification for ProxyObject::Observers
2427   OnSceneObjectRemove();
2428
2429   // Notify shader effect
2430   if (mShaderEffect)
2431   {
2432     mShaderEffect->Disconnect();
2433   }
2434
2435   // Notify attachment
2436   if (mAttachment)
2437   {
2438     mAttachment->Disconnect();
2439   }
2440
2441 #ifdef DYNAMICS_SUPPORT
2442   // Notify dynamics
2443   if( NULL != mDynamicsData )
2444   {
2445     DisconnectDynamics();
2446   }
2447 #endif
2448 }
2449
2450 void Actor::NotifyStageDisconnection()
2451 {
2452   // Actors can be added (in a callback), before the off-stage state is reported.
2453   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2454   // only do this step if there is a stage, i.e. Core is not being shut down
2455   if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2456   {
2457     // Notification for external (CustomeActor) derived classes
2458     OnStageDisconnectionExternal();
2459
2460     if( !mOffStageSignalV2.Empty() )
2461     {
2462       Dali::Actor handle( this );
2463       mOffStageSignalV2.Emit( handle );
2464     }
2465
2466     // Guard against Add during callbacks
2467     if ( !OnStage()  )
2468     {
2469       mOnStageSignalled = false; // signal required next time Actor is added
2470     }
2471   }
2472 }
2473
2474 bool Actor::IsNodeConnected() const
2475 {
2476   bool connected( false );
2477
2478   if( OnStage() &&
2479       NULL != mNode )
2480   {
2481     if( mNode->IsRoot() || mNode->GetParent() )
2482     {
2483       connected = true;
2484     }
2485   }
2486
2487   return connected;
2488 }
2489
2490 bool Actor::IsSceneObjectRemovable() const
2491 {
2492   return false;
2493 }
2494
2495 unsigned int Actor::GetDefaultPropertyCount() const
2496 {
2497   return DEFAULT_PROPERTY_COUNT;
2498 }
2499
2500 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2501 {
2502   indices.reserve( DEFAULT_PROPERTY_COUNT );
2503
2504   for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2505   {
2506     indices.push_back( i );
2507   }
2508 }
2509
2510 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2511 {
2512   if( index < DEFAULT_PROPERTY_COUNT )
2513   {
2514     return DEFAULT_PROPERTY_DETAILS[index].name;
2515   }
2516   else
2517   {
2518     // index out of range..return empty string
2519     return String::EMPTY;
2520   }
2521 }
2522
2523 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2524 {
2525   Property::Index index = Property::INVALID_INDEX;
2526
2527   DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2528
2529   // Look for name in default properties
2530   DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2531   if ( mDefaultPropertyLookup->end() != result )
2532   {
2533     index = result->second;
2534   }
2535
2536   return index;
2537 }
2538
2539 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2540 {
2541   if( index < DEFAULT_PROPERTY_COUNT )
2542   {
2543     return DEFAULT_PROPERTY_DETAILS[index].writable;
2544   }
2545   else
2546   {
2547     return false;
2548   }
2549 }
2550
2551 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2552 {
2553   if( index < DEFAULT_PROPERTY_COUNT )
2554   {
2555     return DEFAULT_PROPERTY_DETAILS[index].animatable;
2556   }
2557   else
2558   {
2559     return false;
2560   }
2561 }
2562
2563 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2564 {
2565   if( index < DEFAULT_PROPERTY_COUNT )
2566   {
2567     return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2568   }
2569   else
2570   {
2571     return false;
2572   }
2573 }
2574
2575 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2576 {
2577   if( index < DEFAULT_PROPERTY_COUNT )
2578   {
2579     return DEFAULT_PROPERTY_DETAILS[index].type;
2580   }
2581   else
2582   {
2583     // index out of range...return Property::NONE
2584     return Property::NONE;
2585   }
2586 }
2587
2588 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2589 {
2590   switch ( index )
2591   {
2592     case Dali::Actor::PARENT_ORIGIN:
2593     {
2594       SetParentOrigin( property.Get<Vector3>() );
2595       break;
2596     }
2597
2598     case Dali::Actor::PARENT_ORIGIN_X:
2599     {
2600       SetParentOriginX( property.Get<float>() );
2601       break;
2602     }
2603
2604     case Dali::Actor::PARENT_ORIGIN_Y:
2605     {
2606       SetParentOriginY( property.Get<float>() );
2607       break;
2608     }
2609
2610     case Dali::Actor::PARENT_ORIGIN_Z:
2611     {
2612       SetParentOriginZ( property.Get<float>() );
2613       break;
2614     }
2615
2616     case Dali::Actor::ANCHOR_POINT:
2617     {
2618       SetAnchorPoint( property.Get<Vector3>() );
2619       break;
2620     }
2621
2622     case Dali::Actor::ANCHOR_POINT_X:
2623     {
2624       SetAnchorPointX( property.Get<float>() );
2625       break;
2626     }
2627
2628     case Dali::Actor::ANCHOR_POINT_Y:
2629     {
2630       SetAnchorPointY( property.Get<float>() );
2631       break;
2632     }
2633
2634     case Dali::Actor::ANCHOR_POINT_Z:
2635     {
2636       SetAnchorPointZ( property.Get<float>() );
2637       break;
2638     }
2639
2640     case Dali::Actor::SIZE:
2641     {
2642       SetSize( property.Get<Vector3>() );
2643       break;
2644     }
2645
2646     case Dali::Actor::SIZE_WIDTH:
2647     {
2648       SetWidth( property.Get<float>() );
2649       break;
2650     }
2651
2652     case Dali::Actor::SIZE_HEIGHT:
2653     {
2654       SetHeight( property.Get<float>() );
2655       break;
2656     }
2657
2658     case Dali::Actor::SIZE_DEPTH:
2659     {
2660       SetDepth( property.Get<float>() );
2661       break;
2662     }
2663
2664     case Dali::Actor::POSITION:
2665     {
2666       SetPosition( property.Get<Vector3>() );
2667       break;
2668     }
2669
2670     case Dali::Actor::POSITION_X:
2671     {
2672       SetX( property.Get<float>() );
2673       break;
2674     }
2675
2676     case Dali::Actor::POSITION_Y:
2677     {
2678       SetY( property.Get<float>() );
2679       break;
2680     }
2681
2682     case Dali::Actor::POSITION_Z:
2683     {
2684       SetZ( property.Get<float>() );
2685       break;
2686     }
2687
2688     case Dali::Actor::ROTATION:
2689     {
2690       SetRotation( property.Get<Quaternion>() );
2691       break;
2692     }
2693
2694     case Dali::Actor::SCALE:
2695     {
2696       SetScale( property.Get<Vector3>() );
2697       break;
2698     }
2699
2700     case Dali::Actor::SCALE_X:
2701     {
2702       SetScaleX( property.Get<float>() );
2703       break;
2704     }
2705
2706     case Dali::Actor::SCALE_Y:
2707     {
2708       SetScaleY( property.Get<float>() );
2709       break;
2710     }
2711
2712     case Dali::Actor::SCALE_Z:
2713     {
2714       SetScaleZ( property.Get<float>() );
2715       break;
2716     }
2717
2718     case Dali::Actor::VISIBLE:
2719     {
2720       SetVisible( property.Get<bool>() );
2721       break;
2722     }
2723
2724     case Dali::Actor::COLOR:
2725     {
2726       SetColor( property.Get<Vector4>() );
2727       break;
2728     }
2729
2730     case Dali::Actor::COLOR_RED:
2731     {
2732       SetColorRed( property.Get<float>() );
2733       break;
2734     }
2735
2736     case Dali::Actor::COLOR_GREEN:
2737     {
2738       SetColorGreen( property.Get<float>() );
2739       break;
2740     }
2741
2742     case Dali::Actor::COLOR_BLUE:
2743     {
2744       SetColorBlue( property.Get<float>() );
2745       break;
2746     }
2747
2748     case Dali::Actor::COLOR_ALPHA:
2749     {
2750       SetOpacity( property.Get<float>() );
2751       break;
2752     }
2753
2754     case Dali::Actor::NAME:
2755     {
2756       SetName( property.Get<std::string>() );
2757       break;
2758     }
2759
2760     case Dali::Actor::SENSITIVE:
2761     {
2762       SetSensitive( property.Get<bool>() );
2763       break;
2764     }
2765
2766     case Dali::Actor::LEAVE_REQUIRED:
2767     {
2768       SetLeaveRequired( property.Get<bool>() );
2769       break;
2770     }
2771
2772     case Dali::Actor::INHERIT_SHADER_EFFECT:
2773     {
2774       SetInheritShaderEffect( property.Get<bool>() );
2775       break;
2776     }
2777
2778     case Dali::Actor::INHERIT_ROTATION:
2779     {
2780       SetInheritRotation( property.Get<bool>() );
2781       break;
2782     }
2783
2784     case Dali::Actor::INHERIT_SCALE:
2785     {
2786       SetInheritScale( property.Get<bool>() );
2787       break;
2788     }
2789
2790     case Dali::Actor::COLOR_MODE:
2791     {
2792       SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2793       break;
2794     }
2795
2796     case Dali::Actor::POSITION_INHERITANCE:
2797     {
2798       SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2799       break;
2800     }
2801
2802     case Dali::Actor::DRAW_MODE:
2803     {
2804       SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2805       break;
2806     }
2807
2808     default:
2809     {
2810       DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2811       break;
2812     }
2813   }
2814 }
2815
2816 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2817 {
2818   // TODO: This should be deprecated
2819   OnPropertySet(index, value);
2820
2821   if(entry.IsAnimatable())
2822   {
2823     // TODO: ADD MATRIX & MATRIX3 types
2824
2825     switch ( entry.type )
2826     {
2827       case Property::BOOLEAN:
2828       {
2829         AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2830         DALI_ASSERT_DEBUG( NULL != property );
2831
2832         // property is being used in a separate thread; queue a message to set the property
2833         SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2834
2835         break;
2836       }
2837
2838       case Property::FLOAT:
2839       {
2840         AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2841         DALI_ASSERT_DEBUG( NULL != property );
2842
2843         // property is being used in a separate thread; queue a message to set the property
2844         SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2845
2846         break;
2847       }
2848
2849       case Property::VECTOR2:
2850       {
2851         AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2852         DALI_ASSERT_DEBUG( NULL != property );
2853
2854         // property is being used in a separate thread; queue a message to set the property
2855         SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2856
2857         break;
2858       }
2859
2860       case Property::VECTOR3:
2861       {
2862         AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2863         DALI_ASSERT_DEBUG( NULL != property );
2864
2865         // property is being used in a separate thread; queue a message to set the property
2866         SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2867
2868         break;
2869       }
2870
2871       case Property::VECTOR4:
2872       {
2873         AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2874         DALI_ASSERT_DEBUG( NULL != property );
2875
2876         // property is being used in a separate thread; queue a message to set the property
2877         SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2878
2879         break;
2880       }
2881
2882       case Property::ROTATION:
2883       {
2884         AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2885         DALI_ASSERT_DEBUG( NULL != property );
2886
2887         // property is being used in a separate thread; queue a message to set the property
2888         SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
2889
2890         break;
2891       }
2892
2893       default:
2894       {
2895         DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2896         break;
2897       }
2898     }
2899   }
2900 }
2901
2902 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2903 {
2904   Property::Value value;
2905
2906   switch ( index )
2907   {
2908     case Dali::Actor::PARENT_ORIGIN:
2909     {
2910       value = GetCurrentParentOrigin();
2911       break;
2912     }
2913
2914     case Dali::Actor::PARENT_ORIGIN_X:
2915     {
2916       value = GetCurrentParentOrigin().x;
2917       break;
2918     }
2919
2920     case Dali::Actor::PARENT_ORIGIN_Y:
2921     {
2922       value = GetCurrentParentOrigin().y;
2923       break;
2924     }
2925
2926     case Dali::Actor::PARENT_ORIGIN_Z:
2927     {
2928       value = GetCurrentParentOrigin().z;
2929       break;
2930     }
2931
2932     case Dali::Actor::ANCHOR_POINT:
2933     {
2934       value = GetCurrentAnchorPoint();
2935       break;
2936     }
2937
2938     case Dali::Actor::ANCHOR_POINT_X:
2939     {
2940       value = GetCurrentAnchorPoint().x;
2941       break;
2942     }
2943
2944     case Dali::Actor::ANCHOR_POINT_Y:
2945     {
2946       value = GetCurrentAnchorPoint().y;
2947       break;
2948     }
2949
2950     case Dali::Actor::ANCHOR_POINT_Z:
2951     {
2952       value = GetCurrentAnchorPoint().z;
2953       break;
2954     }
2955
2956     case Dali::Actor::SIZE:
2957     {
2958       value = GetCurrentSize();
2959       break;
2960     }
2961
2962     case Dali::Actor::SIZE_WIDTH:
2963     {
2964       value = GetCurrentSize().width;
2965       break;
2966     }
2967
2968     case Dali::Actor::SIZE_HEIGHT:
2969     {
2970       value = GetCurrentSize().height;
2971       break;
2972     }
2973
2974     case Dali::Actor::SIZE_DEPTH:
2975     {
2976       value = GetCurrentSize().depth;
2977       break;
2978     }
2979
2980     case Dali::Actor::POSITION:
2981     {
2982       value = GetCurrentPosition();
2983       break;
2984     }
2985
2986     case Dali::Actor::POSITION_X:
2987     {
2988       value = GetCurrentPosition().x;
2989       break;
2990     }
2991
2992     case Dali::Actor::POSITION_Y:
2993     {
2994       value = GetCurrentPosition().y;
2995       break;
2996     }
2997
2998     case Dali::Actor::POSITION_Z:
2999     {
3000       value = GetCurrentPosition().z;
3001       break;
3002     }
3003
3004     case Dali::Actor::WORLD_POSITION:
3005     {
3006       value = GetCurrentWorldPosition();
3007       break;
3008     }
3009
3010     case Dali::Actor::WORLD_POSITION_X:
3011     {
3012       value = GetCurrentWorldPosition().x;
3013       break;
3014     }
3015
3016     case Dali::Actor::WORLD_POSITION_Y:
3017     {
3018       value = GetCurrentWorldPosition().y;
3019       break;
3020     }
3021
3022     case Dali::Actor::WORLD_POSITION_Z:
3023     {
3024       value = GetCurrentWorldPosition().z;
3025       break;
3026     }
3027
3028     case Dali::Actor::ROTATION:
3029     {
3030       value = GetCurrentRotation();
3031       break;
3032     }
3033
3034     case Dali::Actor::WORLD_ROTATION:
3035     {
3036       value = GetCurrentWorldRotation();
3037       break;
3038     }
3039
3040     case Dali::Actor::SCALE:
3041     {
3042       value = GetCurrentScale();
3043       break;
3044     }
3045
3046     case Dali::Actor::SCALE_X:
3047     {
3048       value = GetCurrentScale().x;
3049       break;
3050     }
3051
3052     case Dali::Actor::SCALE_Y:
3053     {
3054       value = GetCurrentScale().y;
3055       break;
3056     }
3057
3058     case Dali::Actor::SCALE_Z:
3059     {
3060       value = GetCurrentScale().z;
3061       break;
3062     }
3063
3064     case Dali::Actor::WORLD_SCALE:
3065     {
3066       value = GetCurrentWorldScale();
3067       break;
3068     }
3069
3070     case Dali::Actor::VISIBLE:
3071     {
3072       value = IsVisible();
3073       break;
3074     }
3075
3076     case Dali::Actor::COLOR:
3077     {
3078       value = GetCurrentColor();
3079       break;
3080     }
3081
3082     case Dali::Actor::COLOR_RED:
3083     {
3084       value = GetCurrentColor().r;
3085       break;
3086     }
3087
3088     case Dali::Actor::COLOR_GREEN:
3089     {
3090       value = GetCurrentColor().g;
3091       break;
3092     }
3093
3094     case Dali::Actor::COLOR_BLUE:
3095     {
3096       value = GetCurrentColor().b;
3097       break;
3098     }
3099
3100     case Dali::Actor::COLOR_ALPHA:
3101     {
3102       value = GetCurrentColor().a;
3103       break;
3104     }
3105
3106     case Dali::Actor::WORLD_COLOR:
3107     {
3108       value = GetCurrentWorldColor();
3109       break;
3110     }
3111
3112     case Dali::Actor::WORLD_MATRIX:
3113     {
3114       value = GetCurrentWorldMatrix();
3115       break;
3116     }
3117
3118     case Dali::Actor::NAME:
3119     {
3120       value = GetName();
3121       break;
3122     }
3123
3124     case Dali::Actor::SENSITIVE:
3125     {
3126       value = IsSensitive();
3127       break;
3128     }
3129
3130     case Dali::Actor::LEAVE_REQUIRED:
3131     {
3132       value = GetLeaveRequired();
3133       break;
3134     }
3135
3136     case Dali::Actor::INHERIT_SHADER_EFFECT:
3137     {
3138       value = GetInheritShaderEffect();
3139       break;
3140     }
3141
3142     case Dali::Actor::INHERIT_ROTATION:
3143     {
3144       value = IsRotationInherited();
3145       break;
3146     }
3147
3148     case Dali::Actor::INHERIT_SCALE:
3149     {
3150       value = IsScaleInherited();
3151       break;
3152     }
3153
3154     case Dali::Actor::COLOR_MODE:
3155     {
3156       value = Scripting::GetColorMode( GetColorMode() );
3157       break;
3158     }
3159
3160     case Dali::Actor::POSITION_INHERITANCE:
3161     {
3162       value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3163       break;
3164     }
3165
3166     case Dali::Actor::DRAW_MODE:
3167     {
3168       value = Scripting::GetDrawMode( GetDrawMode() );
3169       break;
3170     }
3171
3172     default:
3173     {
3174       DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3175       break;
3176     }
3177   }
3178
3179   return value;
3180 }
3181
3182 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
3183 {
3184   if( NULL != mNode )
3185   {
3186     // mNode is being used in a separate thread; queue a message to add the property
3187     InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
3188   }
3189 }
3190
3191 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3192 {
3193   // This method should only return an object connected to the scene-graph
3194   return OnStage() ? mNode : NULL;
3195 }
3196
3197 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3198 {
3199   DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3200
3201   const PropertyBase* property( NULL );
3202
3203   // This method should only return a property of an object connected to the scene-graph
3204   if ( !OnStage() )
3205   {
3206     return property;
3207   }
3208
3209   if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3210   {
3211     CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3212
3213     DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3214
3215     property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3216   }
3217   else if( NULL != mNode )
3218   {
3219     switch ( index )
3220     {
3221       case Dali::Actor::SIZE:
3222         property = &mNode->mSize;
3223         break;
3224
3225       case Dali::Actor::SIZE_WIDTH:
3226         property = &mNode->mSize;
3227         break;
3228
3229       case Dali::Actor::SIZE_HEIGHT:
3230         property = &mNode->mSize;
3231         break;
3232
3233       case Dali::Actor::SIZE_DEPTH:
3234         property = &mNode->mSize;
3235         break;
3236
3237       case Dali::Actor::POSITION:
3238         property = &mNode->mPosition;
3239         break;
3240
3241       case Dali::Actor::POSITION_X:
3242         property = &mNode->mPosition;
3243         break;
3244
3245       case Dali::Actor::POSITION_Y:
3246         property = &mNode->mPosition;
3247         break;
3248
3249       case Dali::Actor::POSITION_Z:
3250         property = &mNode->mPosition;
3251         break;
3252
3253       case Dali::Actor::ROTATION:
3254         property = &mNode->mRotation;
3255         break;
3256
3257       case Dali::Actor::SCALE:
3258         property = &mNode->mScale;
3259         break;
3260
3261       case Dali::Actor::SCALE_X:
3262         property = &mNode->mScale;
3263         break;
3264
3265       case Dali::Actor::SCALE_Y:
3266         property = &mNode->mScale;
3267         break;
3268
3269       case Dali::Actor::SCALE_Z:
3270         property = &mNode->mScale;
3271         break;
3272
3273       case Dali::Actor::VISIBLE:
3274         property = &mNode->mVisible;
3275         break;
3276
3277       case Dali::Actor::COLOR:
3278         property = &mNode->mColor;
3279         break;
3280
3281       case Dali::Actor::COLOR_RED:
3282         property = &mNode->mColor;
3283         break;
3284
3285       case Dali::Actor::COLOR_GREEN:
3286         property = &mNode->mColor;
3287         break;
3288
3289       case Dali::Actor::COLOR_BLUE:
3290         property = &mNode->mColor;
3291         break;
3292
3293       case Dali::Actor::COLOR_ALPHA:
3294         property = &mNode->mColor;
3295         break;
3296
3297       default:
3298         break;
3299     }
3300   }
3301
3302   return property;
3303 }
3304
3305 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3306 {
3307   const PropertyInputImpl* property( NULL );
3308
3309   // This method should only return a property of an object connected to the scene-graph
3310   if ( !OnStage() )
3311   {
3312     return property;
3313   }
3314
3315   if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3316   {
3317     CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3318
3319     DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3320
3321     property = entry->second.GetSceneGraphProperty();
3322   }
3323   else if( NULL != mNode )
3324   {
3325     switch ( index )
3326     {
3327       case Dali::Actor::PARENT_ORIGIN:
3328         property = &mNode->mParentOrigin;
3329         break;
3330
3331       case Dali::Actor::PARENT_ORIGIN_X:
3332         property = &mNode->mParentOrigin;
3333         break;
3334
3335       case Dali::Actor::PARENT_ORIGIN_Y:
3336         property = &mNode->mParentOrigin;
3337         break;
3338
3339       case Dali::Actor::PARENT_ORIGIN_Z:
3340         property = &mNode->mParentOrigin;
3341         break;
3342
3343       case Dali::Actor::ANCHOR_POINT:
3344         property = &mNode->mAnchorPoint;
3345         break;
3346
3347       case Dali::Actor::ANCHOR_POINT_X:
3348         property = &mNode->mAnchorPoint;
3349         break;
3350
3351       case Dali::Actor::ANCHOR_POINT_Y:
3352         property = &mNode->mAnchorPoint;
3353         break;
3354
3355       case Dali::Actor::ANCHOR_POINT_Z:
3356         property = &mNode->mAnchorPoint;
3357         break;
3358
3359       case Dali::Actor::SIZE:
3360         property = &mNode->mSize;
3361         break;
3362
3363       case Dali::Actor::SIZE_WIDTH:
3364         property = &mNode->mSize;
3365         break;
3366
3367       case Dali::Actor::SIZE_HEIGHT:
3368         property = &mNode->mSize;
3369         break;
3370
3371       case Dali::Actor::SIZE_DEPTH:
3372         property = &mNode->mSize;
3373         break;
3374
3375       case Dali::Actor::POSITION:
3376         property = &mNode->mPosition;
3377         break;
3378
3379       case Dali::Actor::POSITION_X:
3380         property = &mNode->mPosition;
3381         break;
3382
3383       case Dali::Actor::POSITION_Y:
3384         property = &mNode->mPosition;
3385         break;
3386
3387       case Dali::Actor::POSITION_Z:
3388         property = &mNode->mPosition;
3389         break;
3390
3391       case Dali::Actor::WORLD_POSITION:
3392         property = &mNode->mWorldPosition;
3393         break;
3394
3395       case Dali::Actor::WORLD_POSITION_X:
3396         property = &mNode->mWorldPosition;
3397         break;
3398
3399       case Dali::Actor::WORLD_POSITION_Y:
3400         property = &mNode->mWorldPosition;
3401         break;
3402
3403       case Dali::Actor::WORLD_POSITION_Z:
3404         property = &mNode->mWorldPosition;
3405         break;
3406
3407       case Dali::Actor::ROTATION:
3408         property = &mNode->mRotation;
3409         break;
3410
3411       case Dali::Actor::WORLD_ROTATION:
3412         property = &mNode->mWorldRotation;
3413         break;
3414
3415       case Dali::Actor::SCALE:
3416         property = &mNode->mScale;
3417         break;
3418
3419       case Dali::Actor::SCALE_X:
3420         property = &mNode->mScale;
3421         break;
3422
3423       case Dali::Actor::SCALE_Y:
3424         property = &mNode->mScale;
3425         break;
3426
3427       case Dali::Actor::SCALE_Z:
3428         property = &mNode->mScale;
3429         break;
3430
3431       case Dali::Actor::WORLD_SCALE:
3432         property = &mNode->mWorldScale;
3433         break;
3434
3435       case Dali::Actor::VISIBLE:
3436         property = &mNode->mVisible;
3437         break;
3438
3439       case Dali::Actor::COLOR:
3440         property = &mNode->mColor;
3441         break;
3442
3443       case Dali::Actor::COLOR_RED:
3444         property = &mNode->mColor;
3445         break;
3446
3447       case Dali::Actor::COLOR_GREEN:
3448         property = &mNode->mColor;
3449         break;
3450
3451       case Dali::Actor::COLOR_BLUE:
3452         property = &mNode->mColor;
3453         break;
3454
3455       case Dali::Actor::COLOR_ALPHA:
3456         property = &mNode->mColor;
3457         break;
3458
3459       case Dali::Actor::WORLD_COLOR:
3460         property = &mNode->mWorldColor;
3461         break;
3462
3463       case Dali::Actor::WORLD_MATRIX:
3464         property = &mNode->mWorldMatrix;
3465         break;
3466
3467       default:
3468         break;
3469     }
3470   }
3471
3472   return property;
3473 }
3474
3475 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3476 {
3477   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3478
3479   switch ( index )
3480   {
3481     case Dali::Actor::PARENT_ORIGIN_X:
3482     case Dali::Actor::ANCHOR_POINT_X:
3483     case Dali::Actor::SIZE_WIDTH:
3484     case Dali::Actor::POSITION_X:
3485     case Dali::Actor::SCALE_X:
3486     case Dali::Actor::COLOR_RED:
3487     case Dali::Actor::WORLD_POSITION_X:
3488     {
3489       componentIndex = 0;
3490       break;
3491     }
3492
3493     case Dali::Actor::PARENT_ORIGIN_Y:
3494     case Dali::Actor::ANCHOR_POINT_Y:
3495     case Dali::Actor::SIZE_HEIGHT:
3496     case Dali::Actor::POSITION_Y:
3497     case Dali::Actor::SCALE_Y:
3498     case Dali::Actor::COLOR_GREEN:
3499     case Dali::Actor::WORLD_POSITION_Y:
3500     {
3501       componentIndex = 1;
3502       break;
3503     }
3504
3505     case Dali::Actor::PARENT_ORIGIN_Z:
3506     case Dali::Actor::ANCHOR_POINT_Z:
3507     case Dali::Actor::SIZE_DEPTH:
3508     case Dali::Actor::POSITION_Z:
3509     case Dali::Actor::SCALE_Z:
3510     case Dali::Actor::COLOR_BLUE:
3511     case Dali::Actor::WORLD_POSITION_Z:
3512     {
3513       componentIndex = 2;
3514       break;
3515     }
3516
3517     case Dali::Actor::COLOR_ALPHA:
3518     {
3519       componentIndex = 3;
3520       break;
3521     }
3522
3523     default:
3524     {
3525       // Do nothing
3526       break;
3527     }
3528   }
3529
3530   return componentIndex;
3531 }
3532
3533 void Actor::SetParent(Actor* parent)
3534 {
3535   if( parent )
3536   {
3537     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3538
3539     mParent = parent;
3540
3541     if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3542          parent->OnStage() )
3543     {
3544       StagePtr stage = parent->mStage;
3545
3546       // Instruct each actor to create a corresponding node in the scene graph
3547       ConnectToStage(*stage);
3548     }
3549   }
3550   else // parent being set to NULL
3551   {
3552     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3553
3554     mParent = NULL;
3555
3556     if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3557          OnStage() )
3558     {
3559       DALI_ASSERT_ALWAYS(mNode != NULL);
3560
3561       if( NULL != mNode )
3562       {
3563         // Disconnect the Node & its children from the scene-graph.
3564         DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3565       }
3566
3567       // Instruct each actor to discard pointers to the scene-graph
3568       DisconnectFromStage();
3569     }
3570   }
3571 }
3572
3573 SceneGraph::Node* Actor::CreateNode() const
3574 {
3575   return Node::New();
3576 }
3577
3578 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3579 {
3580   bool done = false;
3581   Actor* actor = dynamic_cast<Actor*>(object);
3582
3583   if( actor )
3584   {
3585     if(Dali::Actor::ACTION_SHOW == actionName)
3586     {
3587       actor->SetVisible(true);
3588       done = true;
3589     }
3590     else if(Dali::Actor::ACTION_HIDE == actionName)
3591     {
3592       actor->SetVisible(false);
3593       done = true;
3594     }
3595   }
3596
3597   return done;
3598 }
3599
3600 } // namespace Internal
3601
3602 } // namespace Dali