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