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