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