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