(Properties) Fixes to Actor/ShaderEffect/ImageActor incorrectly setting properties.
[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   "scale-x",
140   "scale-y",
141   "scale-z",
142   "world-scale",
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 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2327 {
2328   indices.reserve( DEFAULT_PROPERTY_COUNT );
2329
2330   for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2331   {
2332     indices.push_back( i );
2333   }
2334 }
2335
2336 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2337 {
2338   if( index < DEFAULT_PROPERTY_COUNT )
2339   {
2340     return DEFAULT_PROPERTY_NAMES[index];
2341   }
2342   else
2343   {
2344     // index out of range..return empty string
2345     return INVALID_PROPERTY_NAME;
2346   }
2347 }
2348
2349 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2350 {
2351   Property::Index index = Property::INVALID_INDEX;
2352
2353   DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2354
2355   // Look for name in default properties
2356   DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2357   if ( mDefaultPropertyLookup->end() != result )
2358   {
2359     index = result->second;
2360   }
2361
2362   return index;
2363 }
2364
2365 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2366 {
2367   // World-properties are not writable
2368   return ( Dali::Actor::WORLD_POSITION   != index &&
2369            Dali::Actor::WORLD_POSITION_X != index &&
2370            Dali::Actor::WORLD_POSITION_Y != index &&
2371            Dali::Actor::WORLD_POSITION_Z != index &&
2372            Dali::Actor::WORLD_ROTATION   != index &&
2373            Dali::Actor::WORLD_SCALE      != index &&
2374            Dali::Actor::WORLD_COLOR      != index &&
2375            Dali::Actor::WORLD_MATRIX     != index);
2376 }
2377
2378 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2379 {
2380   // ParentOrigin, AnchorPoint & World-properties are not animatable
2381   return ( Dali::Actor::PARENT_ORIGIN    != index &&
2382            Dali::Actor::PARENT_ORIGIN_X  != index &&
2383            Dali::Actor::PARENT_ORIGIN_Y  != index &&
2384            Dali::Actor::PARENT_ORIGIN_Z  != index &&
2385            Dali::Actor::ANCHOR_POINT     != index &&
2386            Dali::Actor::ANCHOR_POINT_X   != index &&
2387            Dali::Actor::ANCHOR_POINT_Y   != index &&
2388            Dali::Actor::ANCHOR_POINT_Z   != index &&
2389            Dali::Actor::WORLD_POSITION   != index &&
2390            Dali::Actor::WORLD_POSITION_X != index &&
2391            Dali::Actor::WORLD_POSITION_Y != index &&
2392            Dali::Actor::WORLD_POSITION_Z != index &&
2393            Dali::Actor::WORLD_ROTATION   != index &&
2394            Dali::Actor::WORLD_SCALE      != index &&
2395            Dali::Actor::WORLD_COLOR      != index &&
2396            Dali::Actor::WORLD_MATRIX     != index);
2397 }
2398
2399 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2400 {
2401   if( index < DEFAULT_PROPERTY_COUNT )
2402   {
2403     return DEFAULT_PROPERTY_TYPES[index];
2404   }
2405   else
2406   {
2407     // index out of range...return Property::NONE
2408     return Property::NONE;
2409   }
2410 }
2411
2412 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2413 {
2414   switch ( index )
2415   {
2416     case Dali::Actor::PARENT_ORIGIN:
2417     {
2418       SetParentOrigin( property.Get<Vector3>() );
2419       break;
2420     }
2421
2422     case Dali::Actor::PARENT_ORIGIN_X:
2423     {
2424       SetParentOriginX( property.Get<float>() );
2425       break;
2426     }
2427
2428     case Dali::Actor::PARENT_ORIGIN_Y:
2429     {
2430       SetParentOriginY( property.Get<float>() );
2431       break;
2432     }
2433
2434     case Dali::Actor::PARENT_ORIGIN_Z:
2435     {
2436       SetParentOriginZ( property.Get<float>() );
2437       break;
2438     }
2439
2440     case Dali::Actor::ANCHOR_POINT:
2441     {
2442       SetAnchorPoint( property.Get<Vector3>() );
2443       break;
2444     }
2445
2446     case Dali::Actor::ANCHOR_POINT_X:
2447     {
2448       SetAnchorPointX( property.Get<float>() );
2449       break;
2450     }
2451
2452     case Dali::Actor::ANCHOR_POINT_Y:
2453     {
2454       SetAnchorPointY( property.Get<float>() );
2455       break;
2456     }
2457
2458     case Dali::Actor::ANCHOR_POINT_Z:
2459     {
2460       SetAnchorPointZ( property.Get<float>() );
2461       break;
2462     }
2463
2464     case Dali::Actor::SIZE:
2465     {
2466       SetSize( property.Get<Vector3>() );
2467       break;
2468     }
2469
2470     case Dali::Actor::SIZE_WIDTH:
2471     {
2472       SetWidth( property.Get<float>() );
2473       break;
2474     }
2475
2476     case Dali::Actor::SIZE_HEIGHT:
2477     {
2478       SetHeight( property.Get<float>() );
2479       break;
2480     }
2481
2482     case Dali::Actor::SIZE_DEPTH:
2483     {
2484       SetDepth( property.Get<float>() );
2485       break;
2486     }
2487
2488     case Dali::Actor::POSITION:
2489     {
2490       SetPosition( property.Get<Vector3>() );
2491       break;
2492     }
2493
2494     case Dali::Actor::POSITION_X:
2495     {
2496       SetX( property.Get<float>() );
2497       break;
2498     }
2499
2500     case Dali::Actor::POSITION_Y:
2501     {
2502       SetY( property.Get<float>() );
2503       break;
2504     }
2505
2506     case Dali::Actor::POSITION_Z:
2507     {
2508       SetZ( property.Get<float>() );
2509       break;
2510     }
2511
2512     case Dali::Actor::ROTATION:
2513     {
2514       SetRotation( property.Get<Quaternion>() );
2515       break;
2516     }
2517
2518     case Dali::Actor::SCALE:
2519     {
2520       SetScale( property.Get<Vector3>() );
2521       break;
2522     }
2523
2524     case Dali::Actor::SCALE_X:
2525     {
2526       SetScaleX( property.Get<float>() );
2527       break;
2528     }
2529
2530     case Dali::Actor::SCALE_Y:
2531     {
2532       SetScaleY( property.Get<float>() );
2533       break;
2534     }
2535
2536     case Dali::Actor::SCALE_Z:
2537     {
2538       SetScaleZ( property.Get<float>() );
2539       break;
2540     }
2541
2542     case Dali::Actor::VISIBLE:
2543     {
2544       SetVisible( property.Get<bool>() );
2545       break;
2546     }
2547
2548     case Dali::Actor::COLOR:
2549     {
2550       SetColor( property.Get<Vector4>() );
2551       break;
2552     }
2553
2554     case Dali::Actor::COLOR_RED:
2555     {
2556       SetColorRed( property.Get<float>() );
2557       break;
2558     }
2559
2560     case Dali::Actor::COLOR_GREEN:
2561     {
2562       SetColorGreen( property.Get<float>() );
2563       break;
2564     }
2565
2566     case Dali::Actor::COLOR_BLUE:
2567     {
2568       SetColorBlue( property.Get<float>() );
2569       break;
2570     }
2571
2572     case Dali::Actor::COLOR_ALPHA:
2573     {
2574       SetOpacity( property.Get<float>() );
2575       break;
2576     }
2577
2578     case Dali::Actor::NAME:
2579     {
2580       SetName( property.Get<std::string>() );
2581       break;
2582     }
2583
2584     default:
2585     {
2586       DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2587       break;
2588     }
2589   }
2590 }
2591
2592 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2593 {
2594   // TODO: This should be deprecated
2595   OnPropertySet(index, value);
2596
2597   if(entry.IsAnimatable())
2598   {
2599     // TODO: ADD MATRIX & MATRIX3 types
2600
2601     switch ( entry.type )
2602     {
2603       case Property::BOOLEAN:
2604       {
2605         AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2606         DALI_ASSERT_DEBUG( NULL != property );
2607
2608         // property is being used in a separate thread; queue a message to set the property
2609         SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2610
2611         break;
2612       }
2613
2614       case Property::FLOAT:
2615       {
2616         AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2617         DALI_ASSERT_DEBUG( NULL != property );
2618
2619         // property is being used in a separate thread; queue a message to set the property
2620         SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2621
2622         break;
2623       }
2624
2625       case Property::VECTOR2:
2626       {
2627         AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2628         DALI_ASSERT_DEBUG( NULL != property );
2629
2630         // property is being used in a separate thread; queue a message to set the property
2631         SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2632
2633         break;
2634       }
2635
2636       case Property::VECTOR3:
2637       {
2638         AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2639         DALI_ASSERT_DEBUG( NULL != property );
2640
2641         // property is being used in a separate thread; queue a message to set the property
2642         SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2643
2644         break;
2645       }
2646
2647       case Property::VECTOR4:
2648       {
2649         AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2650         DALI_ASSERT_DEBUG( NULL != property );
2651
2652         // property is being used in a separate thread; queue a message to set the property
2653         SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2654
2655         break;
2656       }
2657
2658       case Property::ROTATION:
2659       {
2660         AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2661         DALI_ASSERT_DEBUG( NULL != property );
2662
2663         // property is being used in a separate thread; queue a message to set the property
2664         SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
2665
2666         break;
2667       }
2668
2669       default:
2670       {
2671         DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2672         break;
2673       }
2674     }
2675   }
2676 }
2677
2678 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2679 {
2680   Property::Value value;
2681
2682   switch ( index )
2683   {
2684     case Dali::Actor::PARENT_ORIGIN:
2685     {
2686       value = GetCurrentParentOrigin();
2687       break;
2688     }
2689
2690     case Dali::Actor::PARENT_ORIGIN_X:
2691     {
2692       value = GetCurrentParentOrigin().x;
2693       break;
2694     }
2695
2696     case Dali::Actor::PARENT_ORIGIN_Y:
2697     {
2698       value = GetCurrentParentOrigin().y;
2699       break;
2700     }
2701
2702     case Dali::Actor::PARENT_ORIGIN_Z:
2703     {
2704       value = GetCurrentParentOrigin().z;
2705       break;
2706     }
2707
2708     case Dali::Actor::ANCHOR_POINT:
2709     {
2710       value = GetCurrentAnchorPoint();
2711       break;
2712     }
2713
2714     case Dali::Actor::ANCHOR_POINT_X:
2715     {
2716       value = GetCurrentAnchorPoint().x;
2717       break;
2718     }
2719
2720     case Dali::Actor::ANCHOR_POINT_Y:
2721     {
2722       value = GetCurrentAnchorPoint().y;
2723       break;
2724     }
2725
2726     case Dali::Actor::ANCHOR_POINT_Z:
2727     {
2728       value = GetCurrentAnchorPoint().z;
2729       break;
2730     }
2731
2732     case Dali::Actor::SIZE:
2733     {
2734       value = GetCurrentSize();
2735       break;
2736     }
2737
2738     case Dali::Actor::SIZE_WIDTH:
2739     {
2740       value = GetCurrentSize().width;
2741       break;
2742     }
2743
2744     case Dali::Actor::SIZE_HEIGHT:
2745     {
2746       value = GetCurrentSize().height;
2747       break;
2748     }
2749
2750     case Dali::Actor::SIZE_DEPTH:
2751     {
2752       value = GetCurrentSize().depth;
2753       break;
2754     }
2755
2756     case Dali::Actor::POSITION:
2757     {
2758       value = GetCurrentPosition();
2759       break;
2760     }
2761
2762     case Dali::Actor::POSITION_X:
2763     {
2764       value = GetCurrentPosition().x;
2765       break;
2766     }
2767
2768     case Dali::Actor::POSITION_Y:
2769     {
2770       value = GetCurrentPosition().y;
2771       break;
2772     }
2773
2774     case Dali::Actor::POSITION_Z:
2775     {
2776       value = GetCurrentPosition().z;
2777       break;
2778     }
2779
2780     case Dali::Actor::WORLD_POSITION:
2781     {
2782       value = GetCurrentWorldPosition();
2783       break;
2784     }
2785
2786     case Dali::Actor::WORLD_POSITION_X:
2787     {
2788       value = GetCurrentWorldPosition().x;
2789       break;
2790     }
2791
2792     case Dali::Actor::WORLD_POSITION_Y:
2793     {
2794       value = GetCurrentWorldPosition().y;
2795       break;
2796     }
2797
2798     case Dali::Actor::WORLD_POSITION_Z:
2799     {
2800       value = GetCurrentWorldPosition().z;
2801       break;
2802     }
2803
2804     case Dali::Actor::ROTATION:
2805     {
2806       value = GetCurrentRotation();
2807       break;
2808     }
2809
2810     case Dali::Actor::WORLD_ROTATION:
2811     {
2812       value = GetCurrentWorldRotation();
2813       break;
2814     }
2815
2816     case Dali::Actor::SCALE:
2817     {
2818       value = GetCurrentScale();
2819       break;
2820     }
2821
2822     case Dali::Actor::SCALE_X:
2823     {
2824       value = GetCurrentScale().x;
2825       break;
2826     }
2827
2828     case Dali::Actor::SCALE_Y:
2829     {
2830       value = GetCurrentScale().y;
2831       break;
2832     }
2833
2834     case Dali::Actor::SCALE_Z:
2835     {
2836       value = GetCurrentScale().z;
2837       break;
2838     }
2839
2840     case Dali::Actor::WORLD_SCALE:
2841     {
2842       value = GetCurrentWorldScale();
2843       break;
2844     }
2845
2846     case Dali::Actor::VISIBLE:
2847     {
2848       value = IsVisible();
2849       break;
2850     }
2851
2852     case Dali::Actor::COLOR:
2853     {
2854       value = GetCurrentColor();
2855       break;
2856     }
2857
2858     case Dali::Actor::COLOR_RED:
2859     {
2860       value = GetCurrentColor().r;
2861       break;
2862     }
2863
2864     case Dali::Actor::COLOR_GREEN:
2865     {
2866       value = GetCurrentColor().g;
2867       break;
2868     }
2869
2870     case Dali::Actor::COLOR_BLUE:
2871     {
2872       value = GetCurrentColor().b;
2873       break;
2874     }
2875
2876     case Dali::Actor::COLOR_ALPHA:
2877     {
2878       value = GetCurrentColor().a;
2879       break;
2880     }
2881
2882     case Dali::Actor::WORLD_COLOR:
2883     {
2884       value = GetCurrentWorldColor();
2885       break;
2886     }
2887
2888     case Dali::Actor::WORLD_MATRIX:
2889     {
2890       value = GetCurrentWorldMatrix();
2891       break;
2892     }
2893
2894     case Dali::Actor::NAME:
2895     {
2896       value = GetName();
2897       break;
2898     }
2899
2900     default:
2901     {
2902       DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2903       break;
2904     }
2905   }
2906
2907   return value;
2908 }
2909
2910 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
2911 {
2912   if( NULL != mNode )
2913   {
2914     // mNode is being used in a separate thread; queue a message to add the property
2915     InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
2916   }
2917 }
2918
2919 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2920 {
2921   // This method should only return an object connected to the scene-graph
2922   return OnStage() ? mNode : NULL;
2923 }
2924
2925 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
2926 {
2927   DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
2928
2929   const PropertyBase* property( NULL );
2930
2931   // This method should only return a property of an object connected to the scene-graph
2932   if ( !OnStage() )
2933   {
2934     return property;
2935   }
2936
2937   if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
2938   {
2939     CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
2940
2941     DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
2942
2943     property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
2944   }
2945   else if( NULL != mNode )
2946   {
2947     switch ( index )
2948     {
2949       case Dali::Actor::SIZE:
2950         property = &mNode->mSize;
2951         break;
2952
2953       case Dali::Actor::SIZE_WIDTH:
2954         property = &mNode->mSize;
2955         break;
2956
2957       case Dali::Actor::SIZE_HEIGHT:
2958         property = &mNode->mSize;
2959         break;
2960
2961       case Dali::Actor::SIZE_DEPTH:
2962         property = &mNode->mSize;
2963         break;
2964
2965       case Dali::Actor::POSITION:
2966         property = &mNode->mPosition;
2967         break;
2968
2969       case Dali::Actor::POSITION_X:
2970         property = &mNode->mPosition;
2971         break;
2972
2973       case Dali::Actor::POSITION_Y:
2974         property = &mNode->mPosition;
2975         break;
2976
2977       case Dali::Actor::POSITION_Z:
2978         property = &mNode->mPosition;
2979         break;
2980
2981       case Dali::Actor::ROTATION:
2982         property = &mNode->mRotation;
2983         break;
2984
2985       case Dali::Actor::SCALE:
2986         property = &mNode->mScale;
2987         break;
2988
2989       case Dali::Actor::SCALE_X:
2990         property = &mNode->mScale;
2991         break;
2992
2993       case Dali::Actor::SCALE_Y:
2994         property = &mNode->mScale;
2995         break;
2996
2997       case Dali::Actor::SCALE_Z:
2998         property = &mNode->mScale;
2999         break;
3000
3001       case Dali::Actor::VISIBLE:
3002         property = &mNode->mVisible;
3003         break;
3004
3005       case Dali::Actor::COLOR:
3006         property = &mNode->mColor;
3007         break;
3008
3009       case Dali::Actor::COLOR_RED:
3010         property = &mNode->mColor;
3011         break;
3012
3013       case Dali::Actor::COLOR_GREEN:
3014         property = &mNode->mColor;
3015         break;
3016
3017       case Dali::Actor::COLOR_BLUE:
3018         property = &mNode->mColor;
3019         break;
3020
3021       case Dali::Actor::COLOR_ALPHA:
3022         property = &mNode->mColor;
3023         break;
3024
3025       default:
3026         break;
3027     }
3028   }
3029
3030   return property;
3031 }
3032
3033 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3034 {
3035   const PropertyInputImpl* property( NULL );
3036
3037   // This method should only return a property of an object connected to the scene-graph
3038   if ( !OnStage() )
3039   {
3040     return property;
3041   }
3042
3043   if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3044   {
3045     CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3046
3047     DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3048
3049     property = entry->second.GetSceneGraphProperty();
3050   }
3051   else if( NULL != mNode )
3052   {
3053     switch ( index )
3054     {
3055       case Dali::Actor::PARENT_ORIGIN:
3056         property = &mNode->mParentOrigin;
3057         break;
3058
3059       case Dali::Actor::PARENT_ORIGIN_X:
3060         property = &mNode->mParentOrigin;
3061         break;
3062
3063       case Dali::Actor::PARENT_ORIGIN_Y:
3064         property = &mNode->mParentOrigin;
3065         break;
3066
3067       case Dali::Actor::PARENT_ORIGIN_Z:
3068         property = &mNode->mParentOrigin;
3069         break;
3070
3071       case Dali::Actor::ANCHOR_POINT:
3072         property = &mNode->mAnchorPoint;
3073         break;
3074
3075       case Dali::Actor::ANCHOR_POINT_X:
3076         property = &mNode->mAnchorPoint;
3077         break;
3078
3079       case Dali::Actor::ANCHOR_POINT_Y:
3080         property = &mNode->mAnchorPoint;
3081         break;
3082
3083       case Dali::Actor::ANCHOR_POINT_Z:
3084         property = &mNode->mAnchorPoint;
3085         break;
3086
3087       case Dali::Actor::SIZE:
3088         property = &mNode->mSize;
3089         break;
3090
3091       case Dali::Actor::SIZE_WIDTH:
3092         property = &mNode->mSize;
3093         break;
3094
3095       case Dali::Actor::SIZE_HEIGHT:
3096         property = &mNode->mSize;
3097         break;
3098
3099       case Dali::Actor::SIZE_DEPTH:
3100         property = &mNode->mSize;
3101         break;
3102
3103       case Dali::Actor::POSITION:
3104         property = &mNode->mPosition;
3105         break;
3106
3107       case Dali::Actor::POSITION_X:
3108         property = &mNode->mPosition;
3109         break;
3110
3111       case Dali::Actor::POSITION_Y:
3112         property = &mNode->mPosition;
3113         break;
3114
3115       case Dali::Actor::POSITION_Z:
3116         property = &mNode->mPosition;
3117         break;
3118
3119       case Dali::Actor::WORLD_POSITION:
3120         property = &mNode->mWorldPosition;
3121         break;
3122
3123       case Dali::Actor::WORLD_POSITION_X:
3124         property = &mNode->mWorldPosition;
3125         break;
3126
3127       case Dali::Actor::WORLD_POSITION_Y:
3128         property = &mNode->mWorldPosition;
3129         break;
3130
3131       case Dali::Actor::WORLD_POSITION_Z:
3132         property = &mNode->mWorldPosition;
3133         break;
3134
3135       case Dali::Actor::ROTATION:
3136         property = &mNode->mRotation;
3137         break;
3138
3139       case Dali::Actor::WORLD_ROTATION:
3140         property = &mNode->mWorldRotation;
3141         break;
3142
3143       case Dali::Actor::SCALE:
3144         property = &mNode->mScale;
3145         break;
3146
3147       case Dali::Actor::SCALE_X:
3148         property = &mNode->mScale;
3149         break;
3150
3151       case Dali::Actor::SCALE_Y:
3152         property = &mNode->mScale;
3153         break;
3154
3155       case Dali::Actor::SCALE_Z:
3156         property = &mNode->mScale;
3157         break;
3158
3159       case Dali::Actor::WORLD_SCALE:
3160         property = &mNode->mWorldScale;
3161         break;
3162
3163       case Dali::Actor::VISIBLE:
3164         property = &mNode->mVisible;
3165         break;
3166
3167       case Dali::Actor::COLOR:
3168         property = &mNode->mColor;
3169         break;
3170
3171       case Dali::Actor::COLOR_RED:
3172         property = &mNode->mColor;
3173         break;
3174
3175       case Dali::Actor::COLOR_GREEN:
3176         property = &mNode->mColor;
3177         break;
3178
3179       case Dali::Actor::COLOR_BLUE:
3180         property = &mNode->mColor;
3181         break;
3182
3183       case Dali::Actor::COLOR_ALPHA:
3184         property = &mNode->mColor;
3185         break;
3186
3187       case Dali::Actor::WORLD_COLOR:
3188         property = &mNode->mWorldColor;
3189         break;
3190
3191       case Dali::Actor::WORLD_MATRIX:
3192         property = &mNode->mWorldMatrix;
3193         break;
3194
3195       default:
3196         break;
3197     }
3198   }
3199
3200   return property;
3201 }
3202
3203 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3204 {
3205   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3206
3207   switch ( index )
3208   {
3209     case Dali::Actor::PARENT_ORIGIN_X:
3210     case Dali::Actor::ANCHOR_POINT_X:
3211     case Dali::Actor::SIZE_WIDTH:
3212     case Dali::Actor::POSITION_X:
3213     case Dali::Actor::SCALE_X:
3214     case Dali::Actor::COLOR_RED:
3215     case Dali::Actor::WORLD_POSITION_X:
3216     {
3217       componentIndex = 0;
3218       break;
3219     }
3220
3221     case Dali::Actor::PARENT_ORIGIN_Y:
3222     case Dali::Actor::ANCHOR_POINT_Y:
3223     case Dali::Actor::SIZE_HEIGHT:
3224     case Dali::Actor::POSITION_Y:
3225     case Dali::Actor::SCALE_Y:
3226     case Dali::Actor::COLOR_GREEN:
3227     case Dali::Actor::WORLD_POSITION_Y:
3228     {
3229       componentIndex = 1;
3230       break;
3231     }
3232
3233     case Dali::Actor::PARENT_ORIGIN_Z:
3234     case Dali::Actor::ANCHOR_POINT_Z:
3235     case Dali::Actor::SIZE_DEPTH:
3236     case Dali::Actor::POSITION_Z:
3237     case Dali::Actor::SCALE_Z:
3238     case Dali::Actor::COLOR_BLUE:
3239     case Dali::Actor::WORLD_POSITION_Z:
3240     {
3241       componentIndex = 2;
3242       break;
3243     }
3244
3245     case Dali::Actor::COLOR_ALPHA:
3246     {
3247       componentIndex = 3;
3248       break;
3249     }
3250
3251     default:
3252     {
3253       // Do nothing
3254       break;
3255     }
3256   }
3257
3258   return componentIndex;
3259 }
3260
3261 void Actor::SetParent(Actor* parent)
3262 {
3263   if( parent )
3264   {
3265     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3266
3267     mParent = parent;
3268
3269     if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3270          parent->OnStage() )
3271     {
3272       StagePtr stage = parent->mStage;
3273
3274       // Instruct each actor to create a corresponding node in the scene graph
3275       ConnectToStage(*stage);
3276     }
3277   }
3278   else // parent being set to NULL
3279   {
3280     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3281
3282     mParent = NULL;
3283
3284     if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3285          OnStage() )
3286     {
3287       DALI_ASSERT_ALWAYS(mNode != NULL);
3288
3289       if( NULL != mNode )
3290       {
3291         // Disconnect the Node & its children from the scene-graph.
3292         DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3293       }
3294
3295       // Instruct each actor to discard pointers to the scene-graph
3296       DisconnectFromStage();
3297     }
3298   }
3299 }
3300
3301 SceneGraph::Node* Actor::CreateNode() const
3302 {
3303   return Node::New();
3304 }
3305
3306 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3307 {
3308   bool done = false;
3309   Actor* actor = dynamic_cast<Actor*>(object);
3310
3311   if( actor )
3312   {
3313     if(Dali::Actor::ACTION_SHOW == actionName)
3314     {
3315       actor->SetVisible(true);
3316       done = true;
3317     }
3318     else if(Dali::Actor::ACTION_HIDE == actionName)
3319     {
3320       actor->SetVisible(false);
3321       done = true;
3322     }
3323   }
3324
3325   return done;
3326 }
3327
3328 } // namespace Internal
3329
3330 } // namespace Dali