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