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