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