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