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