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