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