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