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