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