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