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