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