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