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