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