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