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