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