Stage member has been removed from actor.
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
1 /*
2  * Copyright (c) 2015 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 #include <cfloat>
25
26 // INTERNAL INCLUDES
27
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/math/vector2.h>
31 #include <dali/public-api/math/vector3.h>
32 #include <dali/public-api/math/radian.h>
33 #include <dali/public-api/object/type-registry.h>
34 #include <dali/devel-api/scripting/scripting.h>
35
36 #include <dali/internal/common/internal-constants.h>
37 #include <dali/internal/event/common/event-thread-services.h>
38 #include <dali/internal/event/render-tasks/render-task-impl.h>
39 #include <dali/internal/event/actors/camera-actor-impl.h>
40 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
41 #include <dali/internal/event/common/property-helper.h>
42 #include <dali/internal/event/common/stage-impl.h>
43 #include <dali/internal/event/common/type-info-impl.h>
44 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
45 #include <dali/internal/event/actor-attachments/renderer-attachment-impl.h>
46 #include <dali/internal/event/animation/constraint-impl.h>
47 #include <dali/internal/event/common/projection.h>
48 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
49 #include <dali/internal/update/common/animatable-property.h>
50 #include <dali/internal/update/nodes/node-messages.h>
51 #include <dali/internal/update/nodes/node-declarations.h>
52 #include <dali/internal/update/animation/scene-graph-constraint.h>
53 #include <dali/internal/event/events/actor-gesture-data.h>
54 #include <dali/internal/common/message.h>
55 #include <dali/integration-api/debug.h>
56
57 #ifdef DALI_DYNAMICS_SUPPORT
58 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
59 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
60 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
61 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
62 #endif
63
64 using Dali::Internal::SceneGraph::Node;
65 using Dali::Internal::SceneGraph::AnimatableProperty;
66 using Dali::Internal::SceneGraph::PropertyBase;
67
68 namespace Dali
69 {
70 namespace ResizePolicy
71 {
72
73 namespace
74 {
75 DALI_ENUM_TO_STRING_TABLE_BEGIN( Type )
76 DALI_ENUM_TO_STRING( FIXED )
77 DALI_ENUM_TO_STRING( USE_NATURAL_SIZE )
78 DALI_ENUM_TO_STRING( FILL_TO_PARENT )
79 DALI_ENUM_TO_STRING( SIZE_RELATIVE_TO_PARENT )
80 DALI_ENUM_TO_STRING( SIZE_FIXED_OFFSET_FROM_PARENT )
81 DALI_ENUM_TO_STRING( FIT_TO_CHILDREN )
82 DALI_ENUM_TO_STRING( DIMENSION_DEPENDENCY )
83 DALI_ENUM_TO_STRING( USE_ASSIGNED_SIZE )
84 DALI_ENUM_TO_STRING_TABLE_END( Type )
85
86 } // unnamed namespace
87 } // ResizePolicy
88
89 namespace SizeScalePolicy
90 {
91 namespace
92 {
93 // Enumeration to / from string conversion tables
94 DALI_ENUM_TO_STRING_TABLE_BEGIN( Type )
95 DALI_ENUM_TO_STRING( USE_SIZE_SET )
96 DALI_ENUM_TO_STRING( FIT_WITH_ASPECT_RATIO )
97 DALI_ENUM_TO_STRING( FILL_WITH_ASPECT_RATIO )
98 DALI_ENUM_TO_STRING_TABLE_END( Type )
99 } // unnamed namespace
100 } // SizeScalePolicy
101
102 namespace Internal
103 {
104
105 unsigned int Actor::mActorCounter = 0;
106
107 namespace
108 {
109 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
110 inline const Vector3& GetDefaultSizeModeFactor()
111 {
112   return Vector3::ONE;
113 }
114
115 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
116 inline const Vector2& GetDefaultPreferredSize()
117 {
118   return Vector2::ZERO;
119 }
120
121 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
122 inline const Vector2& GetDefaultDimensionPadding()
123 {
124   return Vector2::ZERO;
125 }
126
127 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
128
129 } // unnamed namespace
130
131 /**
132  * Struct to collect relayout variables
133  */
134 struct Actor::RelayoutData
135 {
136   RelayoutData()
137     : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
138   {
139     // Set size negotiation defaults
140     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
141     {
142       resizePolicies[ i ] = ResizePolicy::DEFAULT;
143       negotiatedDimensions[ i ] = 0.0f;
144       dimensionNegotiated[ i ] = false;
145       dimensionDirty[ i ] = false;
146       dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
147       dimensionPadding[ i ] = GetDefaultDimensionPadding();
148       minimumSize[ i ] = 0.0f;
149       maximumSize[ i ] = FLT_MAX;
150     }
151   }
152
153   ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ];      ///< Resize policies
154
155   Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ];  ///< A list of dimension dependencies
156
157   Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ];         ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
158
159   float negotiatedDimensions[ Dimension::DIMENSION_COUNT ];       ///< Storage for when a dimension is negotiated but before set on actor
160
161   float minimumSize[ Dimension::DIMENSION_COUNT ];                ///< The minimum size an actor can be
162   float maximumSize[ Dimension::DIMENSION_COUNT ];                ///< The maximum size an actor can be
163
164   bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ];         ///< Has the dimension been negotiated
165   bool dimensionDirty[ Dimension::DIMENSION_COUNT ];              ///< Flags indicating whether the layout dimension is dirty or not
166
167   Vector3 sizeModeFactor;                              ///< Factor of size used for certain SizeModes
168
169   Vector2 preferredSize;                               ///< The preferred size of the actor
170
171   SizeScalePolicy::Type sizeSetPolicy :3;            ///< Policy to apply when setting size. Enough room for the enum
172
173   bool relayoutEnabled :1;                   ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
174   bool insideRelayout :1;                    ///< Locking flag to prevent recursive relayouts on size set
175 };
176
177 #ifdef DALI_DYNAMICS_SUPPORT
178
179 // Encapsulate actor related dynamics data
180 struct DynamicsData
181 {
182   DynamicsData( Actor* slotOwner )
183   : slotDelegate( slotOwner )
184   {
185   }
186
187   typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
188   typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
189
190   DynamicsBodyPtr body;
191   JointContainer joints;
192   ReferencedJointContainer referencedJoints;
193
194   SlotDelegate< Actor > slotDelegate;
195 };
196
197 #endif // DALI_DYNAMICS_SUPPORT
198
199 namespace // unnamed namespace
200 {
201
202 // Properties
203
204 /**
205  * We want to discourage the use of property strings (minimize string comparisons),
206  * particularly for the default properties.
207  *              Name                Type   writable animatable constraint-input  enum for index-checking
208  */
209 DALI_PROPERTY_TABLE_BEGIN
210 DALI_PROPERTY( "parent-origin",     VECTOR3,  true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN )
211 DALI_PROPERTY( "parent-origin-x",   FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_X )
212 DALI_PROPERTY( "parent-origin-y",   FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_Y )
213 DALI_PROPERTY( "parent-origin-z",   FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_Z )
214 DALI_PROPERTY( "anchor-point",      VECTOR3,  true,  false, true,  Dali::Actor::Property::ANCHOR_POINT )
215 DALI_PROPERTY( "anchor-point-x",    FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_X )
216 DALI_PROPERTY( "anchor-point-y",    FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_Y )
217 DALI_PROPERTY( "anchor-point-z",    FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_Z )
218 DALI_PROPERTY( "size",              VECTOR3,  true,  true,  true,  Dali::Actor::Property::SIZE )
219 DALI_PROPERTY( "size-width",        FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_WIDTH )
220 DALI_PROPERTY( "size-height",       FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_HEIGHT )
221 DALI_PROPERTY( "size-depth",        FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_DEPTH )
222 DALI_PROPERTY( "position",          VECTOR3,  true,  true,  true,  Dali::Actor::Property::POSITION )
223 DALI_PROPERTY( "position-x",        FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_X )
224 DALI_PROPERTY( "position-y",        FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_Y )
225 DALI_PROPERTY( "position-z",        FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_Z )
226 DALI_PROPERTY( "world-position",    VECTOR3,  false, false, true,  Dali::Actor::Property::WORLD_POSITION )
227 DALI_PROPERTY( "world-position-x",  FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_X )
228 DALI_PROPERTY( "world-position-y",  FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_Y )
229 DALI_PROPERTY( "world-position-z",  FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_Z )
230 DALI_PROPERTY( "orientation",       ROTATION, true,  true,  true,  Dali::Actor::Property::ORIENTATION )
231 DALI_PROPERTY( "world-orientation", ROTATION, false, false, true,  Dali::Actor::Property::WORLD_ORIENTATION )
232 DALI_PROPERTY( "scale",             VECTOR3,  true,  true,  true,  Dali::Actor::Property::SCALE )
233 DALI_PROPERTY( "scale-x",           FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_X )
234 DALI_PROPERTY( "scale-y",           FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_Y )
235 DALI_PROPERTY( "scale-z",           FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_Z )
236 DALI_PROPERTY( "world-scale",       VECTOR3,  false, false, true,  Dali::Actor::Property::WORLD_SCALE )
237 DALI_PROPERTY( "visible",           BOOLEAN,  true,  true,  true,  Dali::Actor::Property::VISIBLE )
238 DALI_PROPERTY( "color",             VECTOR4,  true,  true,  true,  Dali::Actor::Property::COLOR )
239 DALI_PROPERTY( "color-red",         FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_RED )
240 DALI_PROPERTY( "color-green",       FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_GREEN )
241 DALI_PROPERTY( "color-blue",        FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_BLUE )
242 DALI_PROPERTY( "color-alpha",       FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_ALPHA )
243 DALI_PROPERTY( "world-color",       VECTOR4,  false, false, true,  Dali::Actor::Property::WORLD_COLOR )
244 DALI_PROPERTY( "world-matrix",      MATRIX,   false, false, true,  Dali::Actor::Property::WORLD_MATRIX )
245 DALI_PROPERTY( "name",              STRING,   true,  false, false, Dali::Actor::Property::NAME )
246 DALI_PROPERTY( "sensitive",         BOOLEAN,  true,  false, false, Dali::Actor::Property::SENSITIVE )
247 DALI_PROPERTY( "leave-required",    BOOLEAN,  true,  false, false, Dali::Actor::Property::LEAVE_REQUIRED )
248 DALI_PROPERTY( "inherit-orientation",BOOLEAN, true,  false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
249 DALI_PROPERTY( "inherit-scale",     BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_SCALE )
250 DALI_PROPERTY( "color-mode",        STRING,   true,  false, false, Dali::Actor::Property::COLOR_MODE )
251 DALI_PROPERTY( "position-inheritance",STRING, true,  false, false, Dali::Actor::Property::POSITION_INHERITANCE )
252 DALI_PROPERTY( "draw-mode",         STRING,   true,  false, false, Dali::Actor::Property::DRAW_MODE )
253 DALI_PROPERTY( "size-mode-factor",  VECTOR3,  true,  false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
254 DALI_PROPERTY( "width-resize-policy",STRING,  true,  false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
255 DALI_PROPERTY( "height-resize-policy",STRING, true,  false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
256 DALI_PROPERTY( "size-scale-policy", STRING,   true,  false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
257 DALI_PROPERTY( "width-for-height",  BOOLEAN,  true,  false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
258 DALI_PROPERTY( "height-for-width",  BOOLEAN,  true,  false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
259 DALI_PROPERTY( "padding",           VECTOR4,  true,  false, false, Dali::Actor::Property::PADDING )
260 DALI_PROPERTY( "minimum-size",      VECTOR2,  true,  false, false, Dali::Actor::Property::MINIMUM_SIZE )
261 DALI_PROPERTY( "maximum-size",      VECTOR2,  true,  false, false, Dali::Actor::Property::MAXIMUM_SIZE )
262 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
263
264 // Signals
265
266 const char* const SIGNAL_TOUCHED = "touched";
267 const char* const SIGNAL_HOVERED = "hovered";
268 const char* const SIGNAL_WHEEL_EVENT = "wheel-event";
269 const char* const SIGNAL_ON_STAGE = "on-stage";
270 const char* const SIGNAL_OFF_STAGE = "off-stage";
271
272 // Actions
273
274 const char* const ACTION_SHOW = "show";
275 const char* const ACTION_HIDE = "hide";
276
277 BaseHandle CreateActor()
278 {
279   return Dali::Actor::New();
280 }
281
282 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
283
284 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
285 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
286 SignalConnectorType signalConnector3( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
287 SignalConnectorType signalConnector4( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
288
289 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
290 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
291
292 /**
293  * @brief Extract a given dimension from a Vector2
294  *
295  * @param[in] values The values to extract from
296  * @param[in] dimension The dimension to extract
297  * @return Return the value for the dimension
298  */
299 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
300 {
301   switch( dimension )
302   {
303     case Dimension::WIDTH:
304     {
305       return values.width;
306     }
307     case Dimension::HEIGHT:
308     {
309       return values.height;
310     }
311     default:
312     {
313       break;
314     }
315   }
316   return 0.0f;
317 }
318
319 /**
320  * @brief Extract a given dimension from a Vector3
321  *
322  * @param[in] values The values to extract from
323  * @param[in] dimension The dimension to extract
324  * @return Return the value for the dimension
325  */
326 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
327 {
328   return GetDimensionValue( values.GetVectorXY(), dimension );
329 }
330
331
332 } // unnamed namespace
333
334 ActorPtr Actor::New()
335 {
336   ActorPtr actor( new Actor( BASIC ) );
337
338   // Second-phase construction
339   actor->Initialize();
340
341   return actor;
342 }
343
344 const std::string& Actor::GetName() const
345 {
346   return mName;
347 }
348
349 void Actor::SetName( const std::string& name )
350 {
351   mName = name;
352
353   if( NULL != mNode )
354   {
355     // ATTENTION: string for debug purposes is not thread safe.
356     DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
357   }
358 }
359
360 unsigned int Actor::GetId() const
361 {
362   return mId;
363 }
364
365 void Actor::Attach( ActorAttachment& attachment )
366 {
367   DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
368
369   if( OnStage() )
370   {
371     attachment.Connect();
372   }
373
374   mAttachment = ActorAttachmentPtr( &attachment );
375 }
376
377 ActorAttachmentPtr Actor::GetAttachment()
378 {
379   return mAttachment;
380 }
381
382 bool Actor::OnStage() const
383 {
384   return mIsOnStage;
385 }
386
387 Dali::Layer Actor::GetLayer()
388 {
389   Dali::Layer layer;
390
391   // Short-circuit for Layer derived actors
392   if( mIsLayer )
393   {
394     layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
395   }
396
397   // Find the immediate Layer parent
398   for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
399   {
400     if( parent->IsLayer() )
401     {
402       layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
403     }
404   }
405
406   return layer;
407 }
408
409 void Actor::Add( Actor& child )
410 {
411   DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
412   DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
413
414   if( !mChildren )
415   {
416     mChildren = new ActorContainer;
417   }
418
419   Actor* const oldParent( child.mParent );
420
421   // child might already be ours
422   if( this != oldParent )
423   {
424     // if we already have parent, unparent us first
425     if( oldParent )
426     {
427       oldParent->Remove( child ); // This causes OnChildRemove callback
428
429       // Old parent may need to readjust to missing child
430       if( oldParent->RelayoutDependentOnChildren() )
431       {
432         oldParent->RelayoutRequest();
433       }
434     }
435
436     // Guard against Add() during previous OnChildRemove callback
437     if( !child.mParent )
438     {
439       // Do this first, since user callbacks from within SetParent() may need to remove child
440       mChildren->push_back( Dali::Actor( &child ) );
441
442       // SetParent asserts that child can be added
443       child.SetParent( this );
444
445       // Notification for derived classes
446       OnChildAdd( child );
447
448       // Only put in a relayout request if there is a suitable dependency
449       if( RelayoutDependentOnChildren() )
450       {
451         RelayoutRequest();
452       }
453     }
454   }
455 }
456
457 void Actor::Insert( unsigned int index, Actor& child )
458 {
459   DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
460   DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
461
462   if( !mChildren )
463   {
464     mChildren = new ActorContainer;
465   }
466
467   Actor* const oldParent( child.mParent );
468
469   // since an explicit position has been given, always insert, even if already a child
470   if( oldParent )
471   {
472     oldParent->Remove( child ); // This causes OnChildRemove callback
473
474     // Old parent may need to readjust to missing child
475     if( oldParent->RelayoutDependentOnChildren() )
476     {
477       oldParent->RelayoutRequest();
478     }
479   }
480
481   // Guard against Add() during previous OnChildRemove callback
482   if( !child.mParent )
483   {
484     // Do this first, since user callbacks from within SetParent() may need to remove child
485     if( index < GetChildCount() )
486     {
487       ActorIter it = mChildren->begin();
488       std::advance( it, index );
489       mChildren->insert( it, Dali::Actor( &child ) );
490     }
491     else
492     {
493       mChildren->push_back( Dali::Actor( &child ) );
494     }
495     // SetParent asserts that child can be added
496     child.SetParent( this, index );
497
498     // Notification for derived classes
499     OnChildAdd( child );
500
501     // Only put in a relayout request if there is a suitable dependency
502     if( RelayoutDependentOnChildren() )
503     {
504       RelayoutRequest();
505     }
506
507     if( child.RelayoutDependentOnParent() )
508     {
509       child.RelayoutRequest();
510     }
511   }
512 }
513
514 void Actor::Remove( Actor& child )
515 {
516   DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
517
518   Dali::Actor removed;
519
520   if( !mChildren )
521   {
522     // no children
523     return;
524   }
525
526   // Find the child in mChildren, and unparent it
527   ActorIter end = mChildren->end();
528   for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
529   {
530     Actor& actor = GetImplementation( *iter );
531
532     if( &actor == &child )
533     {
534       // Keep handle for OnChildRemove notification
535       removed = Dali::Actor( &actor );
536
537       // Do this first, since user callbacks from within SetParent() may need to add the child
538       mChildren->erase( iter );
539
540       DALI_ASSERT_DEBUG( actor.GetParent() == this );
541       actor.SetParent( NULL );
542
543       break;
544     }
545   }
546
547   if( removed )
548   {
549     // Notification for derived classes
550     OnChildRemove( GetImplementation( removed ) );
551
552     // Only put in a relayout request if there is a suitable dependency
553     if( RelayoutDependentOnChildren() )
554     {
555       RelayoutRequest();
556     }
557   }
558 }
559
560 void Actor::Unparent()
561 {
562   if( mParent )
563   {
564     // Remove this actor from the parent. The remove will put a relayout request in for
565     // the parent if required
566     mParent->Remove( *this );
567     // mParent is now NULL!
568   }
569 }
570
571 unsigned int Actor::GetChildCount() const
572 {
573   return ( NULL != mChildren ) ? mChildren->size() : 0;
574 }
575
576 Dali::Actor Actor::GetChildAt( unsigned int index ) const
577 {
578   DALI_ASSERT_ALWAYS( index < GetChildCount() );
579
580   return ( ( mChildren ) ? ( *mChildren )[ index ] : Dali::Actor() );
581 }
582
583 ActorPtr Actor::FindChildByName( const std::string& actorName )
584 {
585   ActorPtr child = 0;
586   if( actorName == mName )
587   {
588     child = this;
589   }
590   else if( mChildren )
591   {
592     ActorIter end = mChildren->end();
593     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
594     {
595       child = GetImplementation( *iter ).FindChildByName( actorName );
596
597       if( child )
598       {
599         break;
600       }
601     }
602   }
603   return child;
604 }
605
606 ActorPtr Actor::FindChildById( const unsigned int id )
607 {
608   ActorPtr child = 0;
609   if( id == mId )
610   {
611     child = this;
612   }
613   else if( mChildren )
614   {
615     ActorIter end = mChildren->end();
616     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
617     {
618       child = GetImplementation( *iter ).FindChildById( id );
619
620       if( child )
621       {
622         break;
623       }
624     }
625   }
626   return child;
627 }
628
629 void Actor::SetParentOrigin( const Vector3& origin )
630 {
631   if( NULL != mNode )
632   {
633     // mNode is being used in a separate thread; queue a message to set the value & base value
634     SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
635   }
636
637   // Cache for event-thread access
638   if( !mParentOrigin )
639   {
640     // not allocated, check if different from default
641     if( ParentOrigin::DEFAULT != origin )
642     {
643       mParentOrigin = new Vector3( origin );
644     }
645   }
646   else
647   {
648     // check if different from current costs more than just set
649     *mParentOrigin = origin;
650   }
651 }
652
653 void Actor::SetParentOriginX( float x )
654 {
655   const Vector3& current = GetCurrentParentOrigin();
656
657   SetParentOrigin( Vector3( x, current.y, current.z ) );
658 }
659
660 void Actor::SetParentOriginY( float y )
661 {
662   const Vector3& current = GetCurrentParentOrigin();
663
664   SetParentOrigin( Vector3( current.x, y, current.z ) );
665 }
666
667 void Actor::SetParentOriginZ( float z )
668 {
669   const Vector3& current = GetCurrentParentOrigin();
670
671   SetParentOrigin( Vector3( current.x, current.y, z ) );
672 }
673
674 const Vector3& Actor::GetCurrentParentOrigin() const
675 {
676   // Cached for event-thread access
677   return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
678 }
679
680 void Actor::SetAnchorPoint( const Vector3& anchor )
681 {
682   if( NULL != mNode )
683   {
684     // mNode is being used in a separate thread; queue a message to set the value & base value
685     SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
686   }
687
688   // Cache for event-thread access
689   if( !mAnchorPoint )
690   {
691     // not allocated, check if different from default
692     if( AnchorPoint::DEFAULT != anchor )
693     {
694       mAnchorPoint = new Vector3( anchor );
695     }
696   }
697   else
698   {
699     // check if different from current costs more than just set
700     *mAnchorPoint = anchor;
701   }
702 }
703
704 void Actor::SetAnchorPointX( float x )
705 {
706   const Vector3& current = GetCurrentAnchorPoint();
707
708   SetAnchorPoint( Vector3( x, current.y, current.z ) );
709 }
710
711 void Actor::SetAnchorPointY( float y )
712 {
713   const Vector3& current = GetCurrentAnchorPoint();
714
715   SetAnchorPoint( Vector3( current.x, y, current.z ) );
716 }
717
718 void Actor::SetAnchorPointZ( float z )
719 {
720   const Vector3& current = GetCurrentAnchorPoint();
721
722   SetAnchorPoint( Vector3( current.x, current.y, z ) );
723 }
724
725 const Vector3& Actor::GetCurrentAnchorPoint() const
726 {
727   // Cached for event-thread access
728   return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
729 }
730
731 void Actor::SetPosition( float x, float y )
732 {
733   SetPosition( Vector3( x, y, 0.0f ) );
734 }
735
736 void Actor::SetPosition( float x, float y, float z )
737 {
738   SetPosition( Vector3( x, y, z ) );
739 }
740
741 void Actor::SetPosition( const Vector3& position )
742 {
743   mTargetPosition = position;
744
745   if( NULL != mNode )
746   {
747     // mNode is being used in a separate thread; queue a message to set the value & base value
748     SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
749   }
750 }
751
752 void Actor::SetX( float x )
753 {
754   mTargetPosition.x = x;
755
756   if( NULL != mNode )
757   {
758     // mNode is being used in a separate thread; queue a message to set the value & base value
759     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
760   }
761 }
762
763 void Actor::SetY( float y )
764 {
765   mTargetPosition.y = y;
766
767   if( NULL != mNode )
768   {
769     // mNode is being used in a separate thread; queue a message to set the value & base value
770     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
771   }
772 }
773
774 void Actor::SetZ( float z )
775 {
776   mTargetPosition.z = z;
777
778   if( NULL != mNode )
779   {
780     // mNode is being used in a separate thread; queue a message to set the value & base value
781     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
782   }
783 }
784
785 void Actor::TranslateBy( const Vector3& distance )
786 {
787   mTargetPosition += distance;
788
789   if( NULL != mNode )
790   {
791     // mNode is being used in a separate thread; queue a message to set the value & base value
792     SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
793   }
794 }
795
796 const Vector3& Actor::GetCurrentPosition() const
797 {
798   if( NULL != mNode )
799   {
800     // mNode is being used in a separate thread; copy the value from the previous update
801     return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
802   }
803
804   return Vector3::ZERO;
805 }
806
807 const Vector3& Actor::GetTargetPosition() const
808 {
809   return mTargetPosition;
810 }
811
812 const Vector3& Actor::GetCurrentWorldPosition() const
813 {
814   if( NULL != mNode )
815   {
816     // mNode is being used in a separate thread; copy the value from the previous update
817     return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
818   }
819
820   return Vector3::ZERO;
821 }
822
823 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
824 {
825   // this flag is not animatable so keep the value
826   mPositionInheritanceMode = mode;
827   if( NULL != mNode )
828   {
829     // mNode is being used in a separate thread; queue a message to set the value
830     SetPositionInheritanceModeMessage( GetEventThreadServices(), *mNode, mode );
831   }
832 }
833
834 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
835 {
836   // Cached for event-thread access
837   return mPositionInheritanceMode;
838 }
839
840 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
841 {
842   Vector3 normalizedAxis( axis.x, axis.y, axis.z );
843   normalizedAxis.Normalize();
844
845   Quaternion orientation( angle, normalizedAxis );
846
847   SetOrientation( orientation );
848 }
849
850 void Actor::SetOrientation( const Quaternion& orientation )
851 {
852   if( NULL != mNode )
853   {
854     // mNode is being used in a separate thread; queue a message to set the value & base value
855     SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::Bake, orientation );
856   }
857 }
858
859 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
860 {
861   if( NULL != mNode )
862   {
863     // mNode is being used in a separate thread; queue a message to set the value & base value
864     SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
865   }
866 }
867
868 void Actor::RotateBy( const Quaternion& relativeRotation )
869 {
870   if( NULL != mNode )
871   {
872     // mNode is being used in a separate thread; queue a message to set the value & base value
873     SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
874   }
875 }
876
877 const Quaternion& Actor::GetCurrentOrientation() const
878 {
879   if( NULL != mNode )
880   {
881     // mNode is being used in a separate thread; copy the value from the previous update
882     return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
883   }
884
885   return Quaternion::IDENTITY;
886 }
887
888 const Quaternion& Actor::GetCurrentWorldOrientation() const
889 {
890   if( NULL != mNode )
891   {
892     // mNode is being used in a separate thread; copy the value from the previous update
893     return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
894   }
895
896   return Quaternion::IDENTITY;
897 }
898
899 void Actor::SetScale( float scale )
900 {
901   SetScale( Vector3( scale, scale, scale ) );
902 }
903
904 void Actor::SetScale( float x, float y, float z )
905 {
906   SetScale( Vector3( x, y, z ) );
907 }
908
909 void Actor::SetScale( const Vector3& scale )
910 {
911   if( NULL != mNode )
912   {
913     // mNode is being used in a separate thread; queue a message to set the value & base value
914     SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
915   }
916 }
917
918 void Actor::SetScaleX( float x )
919 {
920   if( NULL != mNode )
921   {
922     // mNode is being used in a separate thread; queue a message to set the value & base value
923     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
924   }
925 }
926
927 void Actor::SetScaleY( float y )
928 {
929   if( NULL != mNode )
930   {
931     // mNode is being used in a separate thread; queue a message to set the value & base value
932     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
933   }
934 }
935
936 void Actor::SetScaleZ( float z )
937 {
938   if( NULL != mNode )
939   {
940     // mNode is being used in a separate thread; queue a message to set the value & base value
941     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
942   }
943 }
944
945 void Actor::ScaleBy(const Vector3& relativeScale)
946 {
947   if( NULL != mNode )
948   {
949     // mNode is being used in a separate thread; queue a message to set the value & base value
950     SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
951   }
952 }
953
954 const Vector3& Actor::GetCurrentScale() const
955 {
956   if( NULL != mNode )
957   {
958     // mNode is being used in a separate thread; copy the value from the previous update
959     return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
960   }
961
962   return Vector3::ONE;
963 }
964
965 const Vector3& Actor::GetCurrentWorldScale() const
966 {
967   if( NULL != mNode )
968   {
969     // mNode is being used in a separate thread; copy the value from the previous update
970     return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
971   }
972
973   return Vector3::ONE;
974 }
975
976 void Actor::SetInheritScale( bool inherit )
977 {
978   // non animateable so keep local copy
979   mInheritScale = inherit;
980   if( NULL != mNode )
981   {
982     // mNode is being used in a separate thread; queue a message to set the value
983     SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
984   }
985 }
986
987 bool Actor::IsScaleInherited() const
988 {
989   return mInheritScale;
990 }
991
992 Matrix Actor::GetCurrentWorldMatrix() const
993 {
994   if( NULL != mNode )
995   {
996     // World matrix is no longer updated unless there is something observing the node.
997     // Need to calculate it from node's world position, orientation and scale:
998     BufferIndex updateBufferIndex = GetEventThreadServices().GetEventBufferIndex();
999     Matrix worldMatrix(false);
1000     worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
1001                                         mNode->GetWorldOrientation( updateBufferIndex ),
1002                                         mNode->GetWorldPosition( updateBufferIndex ) );
1003     return worldMatrix;
1004   }
1005
1006   return Matrix::IDENTITY;
1007 }
1008
1009 void Actor::SetVisible( bool visible )
1010 {
1011   if( NULL != mNode )
1012   {
1013     // mNode is being used in a separate thread; queue a message to set the value & base value
1014     SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
1015   }
1016 }
1017
1018 bool Actor::IsVisible() const
1019 {
1020   if( NULL != mNode )
1021   {
1022     // mNode is being used in a separate thread; copy the value from the previous update
1023     return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1024   }
1025
1026   return true;
1027 }
1028
1029 void Actor::SetOpacity( float opacity )
1030 {
1031   if( NULL != mNode )
1032   {
1033     // mNode is being used in a separate thread; queue a message to set the value & base value
1034     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1035   }
1036 }
1037
1038 float Actor::GetCurrentOpacity() const
1039 {
1040   if( NULL != mNode )
1041   {
1042     // mNode is being used in a separate thread; copy the value from the previous update
1043     return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1044   }
1045
1046   return 1.0f;
1047 }
1048
1049 const Vector4& Actor::GetCurrentWorldColor() const
1050 {
1051   if( NULL != mNode )
1052   {
1053     return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1054   }
1055
1056   return Color::WHITE;
1057 }
1058
1059 void Actor::SetColor( const Vector4& color )
1060 {
1061   if( NULL != mNode )
1062   {
1063     // mNode is being used in a separate thread; queue a message to set the value & base value
1064     SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1065   }
1066 }
1067
1068 void Actor::SetColorRed( float red )
1069 {
1070   if( NULL != mNode )
1071   {
1072     // mNode is being used in a separate thread; queue a message to set the value & base value
1073     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1074   }
1075 }
1076
1077 void Actor::SetColorGreen( float green )
1078 {
1079   if( NULL != mNode )
1080   {
1081     // mNode is being used in a separate thread; queue a message to set the value & base value
1082     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1083   }
1084 }
1085
1086 void Actor::SetColorBlue( float blue )
1087 {
1088   if( NULL != mNode )
1089   {
1090     // mNode is being used in a separate thread; queue a message to set the value & base value
1091     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1092   }
1093 }
1094
1095 const Vector4& Actor::GetCurrentColor() const
1096 {
1097   if( NULL != mNode )
1098   {
1099     // mNode is being used in a separate thread; copy the value from the previous update
1100     return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1101   }
1102
1103   return Color::WHITE;
1104 }
1105
1106 void Actor::SetInheritOrientation( bool inherit )
1107 {
1108   // non animateable so keep local copy
1109   mInheritOrientation = inherit;
1110   if( NULL != mNode )
1111   {
1112     // mNode is being used in a separate thread; queue a message to set the value
1113     SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1114   }
1115 }
1116
1117 bool Actor::IsOrientationInherited() const
1118 {
1119   return mInheritOrientation;
1120 }
1121
1122 void Actor::SetSizeModeFactor( const Vector3& factor )
1123 {
1124   EnsureRelayoutData();
1125
1126   mRelayoutData->sizeModeFactor = factor;
1127 }
1128
1129 const Vector3& Actor::GetSizeModeFactor() const
1130 {
1131   if ( mRelayoutData )
1132   {
1133     return mRelayoutData->sizeModeFactor;
1134   }
1135
1136   return GetDefaultSizeModeFactor();
1137 }
1138
1139 void Actor::SetColorMode( ColorMode colorMode )
1140 {
1141   // non animateable so keep local copy
1142   mColorMode = colorMode;
1143   if( NULL != mNode )
1144   {
1145     // mNode is being used in a separate thread; queue a message to set the value
1146     SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1147   }
1148 }
1149
1150 ColorMode Actor::GetColorMode() const
1151 {
1152   // we have cached copy
1153   return mColorMode;
1154 }
1155
1156 void Actor::SetSize( float width, float height )
1157 {
1158   SetSize( Vector2( width, height ) );
1159 }
1160
1161 void Actor::SetSize( float width, float height, float depth )
1162 {
1163   SetSize( Vector3( width, height, depth ) );
1164 }
1165
1166 void Actor::SetSize( const Vector2& size )
1167 {
1168   SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1169 }
1170
1171 void Actor::SetSizeInternal( const Vector2& size )
1172 {
1173   SetSizeInternal( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1174 }
1175
1176 float Actor::CalculateSizeZ( const Vector2& size ) const
1177 {
1178   return std::min( size.width, size.height );
1179 }
1180
1181 void Actor::SetSize( const Vector3& size )
1182 {
1183   if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1184   {
1185     SetPreferredSize( size.GetVectorXY() );
1186   }
1187   else
1188   {
1189     SetSizeInternal( size );
1190   }
1191 }
1192
1193 void Actor::SetSizeInternal( const Vector3& size )
1194 {
1195   // dont allow recursive loop
1196   DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1197   // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
1198   if( ( NULL != mNode )&&
1199       ( ( fabsf( mTargetSize.width - size.width  ) > Math::MACHINE_EPSILON_1 )||
1200         ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1201         ( fabsf( mTargetSize.depth - size.depth  ) > Math::MACHINE_EPSILON_1 ) ) )
1202   {
1203     mTargetSize = size;
1204
1205     // mNode is being used in a separate thread; queue a message to set the value & base value
1206     SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mTargetSize );
1207
1208     // Notification for derived classes
1209     mInsideOnSizeSet = true;
1210     OnSizeSet( mTargetSize );
1211     mInsideOnSizeSet = false;
1212
1213     // Raise a relayout request if the flag is not locked
1214     if( mRelayoutData && !mRelayoutData->insideRelayout )
1215     {
1216       RelayoutRequest();
1217     }
1218   }
1219 }
1220
1221 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1222 {
1223   mTargetSize = targetSize;
1224
1225   // Notify deriving classes
1226   OnSizeAnimation( animation, mTargetSize );
1227 }
1228
1229 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1230 {
1231   if ( Dali::Actor::Property::SIZE_WIDTH == property )
1232   {
1233     mTargetSize.width = targetSize;
1234   }
1235   else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1236   {
1237     mTargetSize.height = targetSize;
1238   }
1239   // Notify deriving classes
1240   OnSizeAnimation( animation, mTargetSize );
1241 }
1242
1243 void Actor::SetWidth( float width )
1244 {
1245   if( NULL != mNode )
1246   {
1247     // mNode is being used in a separate thread; queue a message to set the value & base value
1248     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1249   }
1250 }
1251
1252 void Actor::SetHeight( float height )
1253 {
1254   if( NULL != mNode )
1255   {
1256     // mNode is being used in a separate thread; queue a message to set the value & base value
1257     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1258   }
1259 }
1260
1261 void Actor::SetDepth( float depth )
1262 {
1263   if( NULL != mNode )
1264   {
1265     // mNode is being used in a separate thread; queue a message to set the value & base value
1266     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1267   }
1268 }
1269
1270 const Vector3& Actor::GetTargetSize() const
1271 {
1272   return mTargetSize;
1273 }
1274
1275 const Vector3& Actor::GetCurrentSize() const
1276 {
1277   if( NULL != mNode )
1278   {
1279     // mNode is being used in a separate thread; copy the value from the previous update
1280     return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1281   }
1282
1283   return Vector3::ZERO;
1284 }
1285
1286 Vector3 Actor::GetNaturalSize() const
1287 {
1288   // It is up to deriving classes to return the appropriate natural size
1289   return Vector3( 0.0f, 0.0f, 0.0f );
1290 }
1291
1292 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1293 {
1294   EnsureRelayoutData();
1295
1296   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1297   {
1298     if( dimension & ( 1 << i ) )
1299     {
1300       mRelayoutData->resizePolicies[ i ] = policy;
1301     }
1302   }
1303
1304   if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1305   {
1306     if( dimension & Dimension::WIDTH )
1307     {
1308       SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1309     }
1310
1311     if( dimension & Dimension::HEIGHT )
1312     {
1313       SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1314     }
1315   }
1316
1317   // If calling SetResizePolicy, assume we want relayout enabled
1318   SetRelayoutEnabled( true );
1319
1320   OnSetResizePolicy( policy, dimension );
1321
1322   // Trigger relayout on this control
1323   RelayoutRequest();
1324 }
1325
1326 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1327 {
1328   if ( mRelayoutData )
1329   {
1330     // If more than one dimension is requested, just return the first one found
1331     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1332     {
1333       if( ( dimension & ( 1 << i ) ) )
1334       {
1335         return mRelayoutData->resizePolicies[ i ];
1336       }
1337     }
1338   }
1339
1340   return ResizePolicy::DEFAULT;
1341 }
1342
1343 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1344 {
1345   EnsureRelayoutData();
1346
1347   mRelayoutData->sizeSetPolicy = policy;
1348 }
1349
1350 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1351 {
1352   if ( mRelayoutData )
1353   {
1354     return mRelayoutData->sizeSetPolicy;
1355   }
1356
1357   return DEFAULT_SIZE_SCALE_POLICY;
1358 }
1359
1360 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1361 {
1362   EnsureRelayoutData();
1363
1364   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1365   {
1366     if( dimension & ( 1 << i ) )
1367     {
1368       mRelayoutData->dimensionDependencies[ i ] = dependency;
1369     }
1370   }
1371 }
1372
1373 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1374 {
1375   if ( mRelayoutData )
1376   {
1377     // If more than one dimension is requested, just return the first one found
1378     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1379     {
1380       if( ( dimension & ( 1 << i ) ) )
1381       {
1382         return mRelayoutData->dimensionDependencies[ i ];
1383       }
1384     }
1385   }
1386
1387   return Dimension::ALL_DIMENSIONS;   // Default
1388 }
1389
1390 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1391 {
1392   // If relayout data has not been allocated yet and the client is requesting
1393   // to disable it, do nothing
1394   if( mRelayoutData || relayoutEnabled )
1395   {
1396     EnsureRelayoutData();
1397
1398     mRelayoutData->relayoutEnabled = relayoutEnabled;
1399   }
1400 }
1401
1402 bool Actor::IsRelayoutEnabled() const
1403 {
1404   // Assume that if relayout data has not been allocated yet then
1405   // relayout is disabled
1406   return mRelayoutData && mRelayoutData->relayoutEnabled;
1407 }
1408
1409 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1410 {
1411   EnsureRelayoutData();
1412
1413   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1414   {
1415     if( dimension & ( 1 << i ) )
1416     {
1417       mRelayoutData->dimensionDirty[ i ] = dirty;
1418     }
1419   }
1420 }
1421
1422 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1423 {
1424   if ( mRelayoutData )
1425   {
1426     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1427     {
1428       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1429       {
1430         return true;
1431       }
1432     }
1433   }
1434
1435   return false;
1436 }
1437
1438 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1439 {
1440   return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1441 }
1442
1443 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1444 {
1445   return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1446 }
1447
1448 unsigned int Actor::AddRenderer( Renderer& renderer )
1449 {
1450   //TODO: MESH_REWORK : Add support for multiple renderers
1451   if ( ! mAttachment )
1452   {
1453     mAttachment = RendererAttachment::New( GetEventThreadServices(), *mNode, renderer );
1454   }
1455
1456   return 0;
1457 }
1458
1459 unsigned int Actor::GetRendererCount() const
1460 {
1461   //TODO: MESH_REWORK : Add support for multiple renderers
1462   RendererAttachment* attachment = dynamic_cast<RendererAttachment*>(mAttachment.Get());
1463   return attachment ? 1u : 0u;
1464 }
1465
1466 Renderer& Actor::GetRendererAt( unsigned int index )
1467 {
1468   //TODO: MESH_REWORK : Add support for multiple renderers
1469   DALI_ASSERT_DEBUG( index == 0 && "Only one renderer is supported." );
1470
1471   //TODO: MESH_REWORK : Temporary code
1472   RendererAttachment* attachment = dynamic_cast<RendererAttachment*>(mAttachment.Get());
1473   DALI_ASSERT_ALWAYS( attachment && "Actor doesn't have a renderer" );
1474
1475   return attachment->GetRenderer();
1476 }
1477
1478 void Actor::RemoveRenderer( Renderer& renderer )
1479 {
1480   //TODO: MESH_REWORK : Add support for multiple renderers
1481   mAttachment = NULL;
1482 }
1483
1484 void Actor::RemoveRenderer( unsigned int index )
1485 {
1486   //TODO: MESH_REWORK : Add support for multiple renderers
1487   mAttachment = NULL;
1488 }
1489
1490
1491 #ifdef DALI_DYNAMICS_SUPPORT
1492
1493 //--------------- Dynamics ---------------
1494
1495 void Actor::DisableDynamics()
1496 {
1497   if( NULL != mDynamicsData )
1498   {
1499     DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1500
1501     // ensure dynamics object are disconnected from scene
1502     DisconnectDynamics();
1503
1504     // delete joint owned by this actor
1505     while( !mDynamicsData->joints.empty() )
1506     {
1507       RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1508     }
1509
1510     // delete other joints referencing this actor
1511     while( !mDynamicsData->referencedJoints.empty() )
1512     {
1513       DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1514       ActorPtr jointOwner( joint->GetActor( true ) );
1515       if( jointOwner )
1516       {
1517         jointOwner->RemoveDynamicsJoint( joint );
1518       }
1519       else
1520       {
1521         mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1522       }
1523     }
1524     // delete the DynamicsBody object
1525     mDynamicsData->body.Reset();
1526
1527     // Discard Dynamics data structure
1528     delete mDynamicsData;
1529     mDynamicsData = NULL;
1530   }
1531 }
1532
1533 DynamicsBodyPtr Actor::GetDynamicsBody() const
1534 {
1535   DynamicsBodyPtr body;
1536
1537   if( NULL != mDynamicsData )
1538   {
1539     body = mDynamicsData->body;
1540   }
1541
1542   return body;
1543 }
1544
1545 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1546 {
1547   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1548
1549   if( NULL == mDynamicsData )
1550   {
1551     mDynamicsData = new DynamicsData( this );
1552   }
1553
1554   if( !mDynamicsData->body )
1555   {
1556     mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1557
1558     if( OnStage() )
1559     {
1560       DynamicsWorldPtr world( DynamicsWorld::Get() );
1561       if( world )
1562       {
1563         if( mParent == world->GetRootActor().Get() )
1564         {
1565           mDynamicsData->body->Connect( GetEventThreadServices() );
1566         }
1567       }
1568     }
1569   }
1570
1571   return mDynamicsData->body;
1572 }
1573
1574 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1575 {
1576   DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1577   return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1578 }
1579
1580 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1581 {
1582   DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1583   DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1584
1585   DynamicsJointPtr joint;
1586
1587   DynamicsWorldPtr world( DynamicsWorld::Get() );
1588
1589   if( world )
1590   {
1591     if( NULL != mDynamicsData )
1592     {
1593       DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1594
1595       if( mDynamicsData->joints.end() != it )
1596       {
1597         // use existing joint
1598         joint = it->second;
1599       }
1600
1601       if( !joint )
1602       {
1603         DynamicsBodyPtr bodyA( GetDynamicsBody() );
1604         DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1605
1606         if( !bodyA )
1607         {
1608           bodyA = EnableDynamics( new DynamicsBodyConfig );
1609         }
1610
1611         if( !bodyB )
1612         {
1613           bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1614         }
1615
1616         joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1617         mDynamicsData->joints[ attachedActor.Get() ] = joint;
1618
1619         if( OnStage() && attachedActor->OnStage() )
1620         {
1621           joint->Connect( GetEventThreadServices() );
1622         }
1623
1624         attachedActor->ReferenceJoint( joint );
1625
1626         attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1627         attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1628       }
1629     }
1630   }
1631   return joint;
1632 }
1633
1634 const int Actor::GetNumberOfJoints() const
1635 {
1636   return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1637 }
1638
1639 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1640 {
1641   DynamicsJointPtr joint;
1642
1643   if( NULL != mDynamicsData )
1644   {
1645     if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1646     {
1647       DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1648
1649       for( int i = 0; i < index; ++i )
1650       {
1651         ++it;
1652       }
1653
1654       joint = it->second;
1655     }
1656   }
1657
1658   return joint;
1659 }
1660
1661 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1662 {
1663   DynamicsJointPtr joint;
1664
1665   if( NULL != mDynamicsData )
1666   {
1667     DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1668
1669     if( mDynamicsData->joints.end() != it )
1670     {
1671       // use existing joint
1672       joint = it->second;
1673     }
1674   }
1675
1676   return joint;
1677 }
1678
1679 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1680 {
1681   if( NULL != mDynamicsData )
1682   {
1683     DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1684     DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1685
1686     for(; it != endIt; ++it )
1687     {
1688       if( it->second == joint.Get() )
1689       {
1690         ActorPtr attachedActor( it->first );
1691
1692         if( OnStage() && attachedActor && attachedActor->OnStage() )
1693         {
1694           joint->Disconnect( GetEventThreadServices() );
1695         }
1696
1697         if( attachedActor )
1698         {
1699           attachedActor->ReleaseJoint( joint );
1700           attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1701           attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1702         }
1703
1704         mDynamicsData->joints.erase(it);
1705         break;
1706       }
1707     }
1708   }
1709 }
1710
1711 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1712 {
1713   DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1714
1715   if( NULL != mDynamicsData )
1716   {
1717     mDynamicsData->referencedJoints.push_back(joint);
1718   }
1719 }
1720
1721 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1722 {
1723   DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1724
1725   if( NULL != mDynamicsData )
1726   {
1727     DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1728
1729     if( it != mDynamicsData->referencedJoints.end() )
1730     {
1731       mDynamicsData->referencedJoints.erase( it );
1732     }
1733   }
1734 }
1735
1736 void Actor::SetDynamicsRoot(bool flag)
1737 {
1738   if( mIsDynamicsRoot != flag )
1739   {
1740     mIsDynamicsRoot = flag;
1741
1742     if( OnStage() && mChildren )
1743     {
1744       // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1745       ActorIter end = mChildren->end();
1746       for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1747       {
1748         Actor& child = GetImplementation(*iter);
1749
1750         if( child.GetDynamicsBody() )
1751         {
1752           if( mIsDynamicsRoot )
1753           {
1754             child.ConnectDynamics();
1755           }
1756           else
1757           {
1758             child.DisconnectDynamics();
1759           }
1760         }
1761       }
1762     }
1763   }
1764 }
1765
1766 bool Actor::IsDynamicsRoot() const
1767 {
1768   return mIsDynamicsRoot;
1769 }
1770
1771 void Actor::AttachedActorOnStage( Dali::Actor actor )
1772 {
1773   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1774
1775   if( OnStage() )
1776   {
1777     ActorPtr attachedActor( &GetImplementation(actor) );
1778
1779     DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1780     if( NULL != mDynamicsData )
1781     {
1782       DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1783       if( mDynamicsData->joints.end() != it )
1784       {
1785         DynamicsJointPtr joint( it->second );
1786         joint->Connect( GetEventThreadServices() );
1787       }
1788     }
1789   }
1790 }
1791
1792 void Actor::AttachedActorOffStage( Dali::Actor actor )
1793 {
1794   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1795
1796   if( OnStage() )
1797   {
1798     ActorPtr attachedActor( &GetImplementation(actor) );
1799
1800     DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1801     if( NULL != mDynamicsData )
1802     {
1803       DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1804       if( mDynamicsData->joints.end() != it )
1805       {
1806         DynamicsJointPtr joint( it->second );
1807         joint->Disconnect( GetEventThreadServices() );
1808       }
1809     }
1810   }
1811 }
1812
1813 void Actor::ConnectDynamics()
1814 {
1815   if( NULL != mDynamicsData && mDynamicsData->body )
1816   {
1817     if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1818     {
1819       mDynamicsData->body->Connect( GetEventThreadServices() );
1820
1821       // Connect all joints where attachedActor is also on stage
1822       if( !mDynamicsData->joints.empty() )
1823       {
1824         DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1825         DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1826
1827         for(; it != endIt; ++it )
1828         {
1829           Actor* attachedActor( it->first );
1830           if( NULL != attachedActor && attachedActor->OnStage() )
1831           {
1832             DynamicsJointPtr joint( it->second );
1833
1834             joint->Connect( GetEventThreadServices() );
1835           }
1836         }
1837       }
1838     }
1839   }
1840 }
1841
1842 void Actor::DisconnectDynamics()
1843 {
1844   if( NULL != mDynamicsData && mDynamicsData->body )
1845   {
1846     if( OnStage() )
1847     {
1848       mDynamicsData->body->Disconnect( GetEventThreadServices() );
1849
1850       // Disconnect all joints
1851       if( !mDynamicsData->joints.empty() )
1852       {
1853         DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1854         DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1855
1856         for(; it != endIt; ++it )
1857         {
1858           DynamicsJointPtr joint( it->second );
1859
1860           joint->Disconnect( GetEventThreadServices() );
1861         }
1862       }
1863     }
1864   }
1865 }
1866
1867 #endif // DALI_DYNAMICS_SUPPORT
1868
1869 void Actor::SetOverlay( bool enable )
1870 {
1871   // Setting STENCIL will override OVERLAY
1872   if( DrawMode::STENCIL != mDrawMode )
1873   {
1874     SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1875   }
1876 }
1877
1878 bool Actor::IsOverlay() const
1879 {
1880   return ( DrawMode::OVERLAY == mDrawMode );
1881 }
1882
1883 void Actor::SetDrawMode( DrawMode::Type drawMode )
1884 {
1885   // this flag is not animatable so keep the value
1886   mDrawMode = drawMode;
1887   if( NULL != mNode )
1888   {
1889     // mNode is being used in a separate thread; queue a message to set the value
1890     SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1891   }
1892 }
1893
1894 DrawMode::Type Actor::GetDrawMode() const
1895 {
1896   return mDrawMode;
1897 }
1898
1899 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1900 {
1901   // only valid when on-stage
1902   StagePtr stage = Stage::GetCurrent();
1903   if( stage && OnStage() )
1904   {
1905     const RenderTaskList& taskList = stage->GetRenderTaskList();
1906
1907     Vector2 converted( screenX, screenY );
1908
1909     // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1910     const int taskCount = taskList.GetTaskCount();
1911     for( int i = taskCount - 1; i >= 0; --i )
1912     {
1913       Dali::RenderTask task = taskList.GetTask( i );
1914       if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1915       {
1916         // found a task where this conversion was ok so return
1917         return true;
1918       }
1919     }
1920   }
1921   return false;
1922 }
1923
1924 bool Actor::ScreenToLocal( RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1925 {
1926   bool retval = false;
1927   // only valid when on-stage
1928   if( OnStage() )
1929   {
1930     CameraActor* camera = renderTask.GetCameraActor();
1931     if( camera )
1932     {
1933       Viewport viewport;
1934       renderTask.GetViewport( viewport );
1935
1936       // need to translate coordinates to render tasks coordinate space
1937       Vector2 converted( screenX, screenY );
1938       if( renderTask.TranslateCoordinates( converted ) )
1939       {
1940         retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1941       }
1942     }
1943   }
1944   return retval;
1945 }
1946
1947 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1948 {
1949   // Early-out if mNode is NULL
1950   if( !OnStage() )
1951   {
1952     return false;
1953   }
1954
1955   BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1956
1957   // Calculate the ModelView matrix
1958   Matrix modelView( false/*don't init*/);
1959   // need to use the components as world matrix is only updated for actors that need it
1960   modelView.SetTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) );
1961   Matrix::Multiply( modelView, modelView, viewMatrix );
1962
1963   // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1964   Matrix invertedMvp( false/*don't init*/);
1965   Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1966   bool success = invertedMvp.Invert();
1967
1968   // Convert to GL coordinates
1969   Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1970
1971   Vector4 nearPos;
1972   if( success )
1973   {
1974     success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1975   }
1976
1977   Vector4 farPos;
1978   if( success )
1979   {
1980     screenPos.z = 1.0f;
1981     success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1982   }
1983
1984   if( success )
1985   {
1986     Vector4 local;
1987     if( XyPlaneIntersect( nearPos, farPos, local ) )
1988     {
1989       Vector3 size = GetCurrentSize();
1990       localX = local.x + size.x * 0.5f;
1991       localY = local.y + size.y * 0.5f;
1992     }
1993     else
1994     {
1995       success = false;
1996     }
1997   }
1998
1999   return success;
2000 }
2001
2002 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
2003 {
2004   /*
2005    http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
2006
2007    Mathematical Formulation
2008
2009    Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
2010
2011    ( p - c ) dot ( p - c ) = r^2
2012
2013    Given a ray with a point of origin 'o', and a direction vector 'd':
2014
2015    ray(t) = o + td, t >= 0
2016
2017    we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
2018
2019    (o + td - c ) dot ( o + td - c ) = r^2
2020
2021    To solve for t we first expand the above into a more recognisable quadratic equation form
2022
2023    ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
2024
2025    or
2026
2027    At2 + Bt + C = 0
2028
2029    where
2030
2031    A = d dot d
2032    B = 2( o - c ) dot d
2033    C = ( o - c ) dot ( o - c ) - r^2
2034
2035    which can be solved using a standard quadratic formula.
2036
2037    Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
2038
2039    Practical Simplification
2040
2041    In a renderer, we often differentiate between world space and object space. In the object space
2042    of a sphere it is centred at origin, meaning that if we first transform the ray from world space
2043    into object space, the mathematical solution presented above can be simplified significantly.
2044
2045    If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
2046
2047    p dot p = r^2
2048
2049    and we can find the t at which the (transformed) ray intersects the sphere by
2050
2051    ( o + td ) dot ( o + td ) = r^2
2052
2053    According to the reasoning above, we expand the above quadratic equation into the general form
2054
2055    At2 + Bt + C = 0
2056
2057    which now has coefficients:
2058
2059    A = d dot d
2060    B = 2( d dot o )
2061    C = o dot o - r^2
2062    */
2063
2064   // Early out if mNode is NULL
2065   if( !mNode )
2066   {
2067     return false;
2068   }
2069
2070   BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
2071
2072   // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
2073   const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
2074   Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
2075
2076   // Compute the radius is not needed, square radius it's enough.
2077   const Vector3& size( mNode->GetSize( bufferIndex ) );
2078
2079   // Scale the sphere.
2080   const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
2081
2082   const float width = size.width * scale.width;
2083   const float height = size.height * scale.height;
2084
2085   float squareSphereRadius = 0.5f * ( width * width + height * height );
2086
2087   float a = rayDir.Dot( rayDir );                                       // a
2088   float b2 = rayDir.Dot( rayOriginLocal );                              // b/2
2089   float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius;  // c
2090
2091   return ( b2 * b2 - a * c ) >= 0.f;
2092 }
2093
2094 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
2095 {
2096   bool hit = false;
2097
2098   if( OnStage() &&
2099   NULL != mNode )
2100   {
2101     BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
2102
2103     // Transforms the ray to the local reference system.
2104
2105     // Calculate the inverse of Model matrix
2106     Matrix invModelMatrix( false/*don't init*/);
2107     // need to use the components as world matrix is only updated for actors that need it
2108     invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) );
2109
2110     Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
2111     Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
2112
2113     // Test with the actor's XY plane (Normal = 0 0 1 1).
2114
2115     float a = -rayOriginLocal.z;
2116     float b = rayDirLocal.z;
2117
2118     if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
2119     {
2120       // Ray travels distance * rayDirLocal to intersect with plane.
2121       distance = a / b;
2122
2123       const Vector3& size = mNode->GetSize( bufferIndex );
2124
2125       hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
2126       hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
2127
2128       // Test with the actor's geometry.
2129       hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
2130     }
2131   }
2132
2133   return hit;
2134 }
2135
2136 void Actor::SetLeaveRequired( bool required )
2137 {
2138   mLeaveRequired = required;
2139 }
2140
2141 bool Actor::GetLeaveRequired() const
2142 {
2143   return mLeaveRequired;
2144 }
2145
2146 void Actor::SetKeyboardFocusable( bool focusable )
2147 {
2148   mKeyboardFocusable = focusable;
2149 }
2150
2151 bool Actor::IsKeyboardFocusable() const
2152 {
2153   return mKeyboardFocusable;
2154 }
2155
2156 bool Actor::GetTouchRequired() const
2157 {
2158   return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
2159 }
2160
2161 bool Actor::GetHoverRequired() const
2162 {
2163   return !mHoveredSignal.Empty() || mDerivedRequiresHover;
2164 }
2165
2166 bool Actor::GetWheelEventRequired() const
2167 {
2168   return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
2169 }
2170
2171 bool Actor::IsHittable() const
2172 {
2173   return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
2174 }
2175
2176 ActorGestureData& Actor::GetGestureData()
2177 {
2178   // Likely scenario is that once gesture-data is created for this actor, the actor will require
2179   // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
2180   if( NULL == mGestureData )
2181   {
2182     mGestureData = new ActorGestureData;
2183   }
2184   return *mGestureData;
2185 }
2186
2187 bool Actor::IsGestureRequred( Gesture::Type type ) const
2188 {
2189   return mGestureData && mGestureData->IsGestureRequred( type );
2190 }
2191
2192 bool Actor::EmitTouchEventSignal( const TouchEvent& event )
2193 {
2194   bool consumed = false;
2195
2196   if( !mTouchedSignal.Empty() )
2197   {
2198     Dali::Actor handle( this );
2199     consumed = mTouchedSignal.Emit( handle, event );
2200   }
2201
2202   if( !consumed )
2203   {
2204     // Notification for derived classes
2205     consumed = OnTouchEvent( event );
2206   }
2207
2208   return consumed;
2209 }
2210
2211 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
2212 {
2213   bool consumed = false;
2214
2215   if( !mHoveredSignal.Empty() )
2216   {
2217     Dali::Actor handle( this );
2218     consumed = mHoveredSignal.Emit( handle, event );
2219   }
2220
2221   if( !consumed )
2222   {
2223     // Notification for derived classes
2224     consumed = OnHoverEvent( event );
2225   }
2226
2227   return consumed;
2228 }
2229
2230 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
2231 {
2232   bool consumed = false;
2233
2234   if( !mWheelEventSignal.Empty() )
2235   {
2236     Dali::Actor handle( this );
2237     consumed = mWheelEventSignal.Emit( handle, event );
2238   }
2239
2240   if( !consumed )
2241   {
2242     // Notification for derived classes
2243     consumed = OnWheelEvent( event );
2244   }
2245
2246   return consumed;
2247 }
2248
2249 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
2250 {
2251   return mTouchedSignal;
2252 }
2253
2254 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2255 {
2256   return mHoveredSignal;
2257 }
2258
2259 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
2260 {
2261   return mWheelEventSignal;
2262 }
2263
2264 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2265 {
2266   return mOnStageSignal;
2267 }
2268
2269 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2270 {
2271   return mOffStageSignal;
2272 }
2273
2274 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2275 {
2276   return mOnRelayoutSignal;
2277 }
2278
2279 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2280 {
2281   bool connected( true );
2282   Actor* actor = dynamic_cast< Actor* >( object );
2283
2284   if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2285   {
2286     actor->TouchedSignal().Connect( tracker, functor );
2287   }
2288   else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2289   {
2290     actor->HoveredSignal().Connect( tracker, functor );
2291   }
2292   else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2293   {
2294     actor->WheelEventSignal().Connect( tracker, functor );
2295   }
2296   else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2297   {
2298     actor->OnStageSignal().Connect( tracker, functor );
2299   }
2300   else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2301   {
2302     actor->OffStageSignal().Connect( tracker, functor );
2303   }
2304   else
2305   {
2306     // signalName does not match any signal
2307     connected = false;
2308   }
2309
2310   return connected;
2311 }
2312
2313 Actor::Actor( DerivedType derivedType )
2314 : mParent( NULL ),
2315   mChildren( NULL ),
2316   mNode( NULL ),
2317   mParentOrigin( NULL ),
2318   mAnchorPoint( NULL ),
2319   mRelayoutData( NULL ),
2320 #ifdef DALI_DYNAMICS_SUPPORT
2321   mDynamicsData( NULL ),
2322 #endif
2323   mGestureData( NULL ),
2324   mAttachment(),
2325   mTargetSize( 0.0f, 0.0f, 0.0f ),
2326   mName(),
2327   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2328   mDepth( 0 ),
2329   mIsRoot( ROOT_LAYER == derivedType ),
2330   mIsRenderable( RENDERABLE == derivedType ),
2331   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2332   mIsOnStage( false ),
2333   mIsDynamicsRoot( false ),
2334   mSensitive( true ),
2335   mLeaveRequired( false ),
2336   mKeyboardFocusable( false ),
2337   mDerivedRequiresTouch( false ),
2338   mDerivedRequiresHover( false ),
2339   mDerivedRequiresWheelEvent( false ),
2340   mOnStageSignalled( false ),
2341   mInsideOnSizeSet( false ),
2342   mInheritOrientation( true ),
2343   mInheritScale( true ),
2344   mDrawMode( DrawMode::NORMAL ),
2345   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2346   mColorMode( Node::DEFAULT_COLOR_MODE )
2347 {
2348 }
2349
2350 void Actor::Initialize()
2351 {
2352   // Node creation
2353   SceneGraph::Node* node = CreateNode();
2354
2355   AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2356   mNode = node; // Keep raw-pointer to Node
2357
2358   OnInitialize();
2359
2360   GetEventThreadServices().RegisterObject( this );
2361 }
2362
2363 Actor::~Actor()
2364 {
2365   // Remove mParent pointers from children even if we're destroying core,
2366   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2367   if( mChildren )
2368   {
2369     ActorConstIter endIter = mChildren->end();
2370     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2371     {
2372       Actor& actor = GetImplementation( *iter );
2373       actor.SetParent( NULL );
2374     }
2375   }
2376   delete mChildren;
2377
2378   // Guard to allow handle destruction after Core has been destroyed
2379   if( EventThreadServices::IsCoreRunning() )
2380   {
2381     if( NULL != mNode )
2382     {
2383       DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2384       mNode = NULL; // Node is about to be destroyed
2385     }
2386
2387     GetEventThreadServices().UnregisterObject( this );
2388   }
2389
2390 #ifdef DALI_DYNAMICS_SUPPORT
2391   // Cleanup dynamics
2392   delete mDynamicsData;
2393 #endif
2394
2395   // Cleanup optional gesture data
2396   delete mGestureData;
2397
2398   // Cleanup optional parent origin and anchor
2399   delete mParentOrigin;
2400   delete mAnchorPoint;
2401
2402   // Delete optional relayout data
2403   if( mRelayoutData )
2404   {
2405     delete mRelayoutData;
2406   }
2407 }
2408
2409 void Actor::ConnectToStage( unsigned int parentDepth, int index )
2410 {
2411   // This container is used instead of walking the Actor hierachy.
2412   // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2413   ActorContainer connectionList;
2414
2415
2416   // This stage is atomic i.e. not interrupted by user callbacks
2417   RecursiveConnectToStage( connectionList, parentDepth+1, index );
2418
2419   // Notify applications about the newly connected actors.
2420   const ActorIter endIter = connectionList.end();
2421   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2422   {
2423     Actor& actor = GetImplementation( *iter );
2424     actor.NotifyStageConnection();
2425   }
2426
2427   RelayoutRequest();
2428 }
2429
2430 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth, int index )
2431 {
2432   DALI_ASSERT_ALWAYS( !OnStage() );
2433
2434   mIsOnStage = true;
2435   mDepth = depth;
2436
2437   ConnectToSceneGraph( index );
2438
2439   // Notification for internal derived classes
2440   OnStageConnectionInternal();
2441
2442   // This stage is atomic; avoid emitting callbacks until all Actors are connected
2443   connectionList.push_back( Dali::Actor( this ) );
2444
2445   // Recursively connect children
2446   if( mChildren )
2447   {
2448     ActorConstIter endIter = mChildren->end();
2449     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2450     {
2451       Actor& actor = GetImplementation( *iter );
2452       actor.RecursiveConnectToStage( connectionList, depth+1 );
2453     }
2454   }
2455 }
2456
2457 /**
2458  * This method is called when the Actor is connected to the Stage.
2459  * The parent must have added its Node to the scene-graph.
2460  * The child must connect its Node to the parent's Node.
2461  * This is resursive; the child calls ConnectToStage() for its children.
2462  */
2463 void Actor::ConnectToSceneGraph( int index )
2464 {
2465   DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2466
2467   if( NULL != mNode )
2468   {
2469     // Reparent Node in next Update
2470     ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode, index );
2471   }
2472
2473   // Notify attachment
2474   if( mAttachment )
2475   {
2476     mAttachment->Connect();
2477   }
2478
2479 #ifdef DALI_DYNAMICS_SUPPORT
2480   // Notify dynamics
2481   if( NULL != mDynamicsData )
2482   {
2483     ConnectDynamics();
2484   }
2485 #endif
2486
2487   // Request relayout on all actors that are added to the scenegraph
2488   RelayoutRequest();
2489
2490   // Notification for Object::Observers
2491   OnSceneObjectAdd();
2492 }
2493
2494 void Actor::NotifyStageConnection()
2495 {
2496   // Actors can be removed (in a callback), before the on-stage stage is reported.
2497   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2498   if( OnStage() && !mOnStageSignalled )
2499   {
2500     // Notification for external (CustomActor) derived classes
2501     OnStageConnectionExternal( mDepth );
2502
2503     if( !mOnStageSignal.Empty() )
2504     {
2505       Dali::Actor handle( this );
2506       mOnStageSignal.Emit( handle );
2507     }
2508
2509     // Guard against Remove during callbacks
2510     if( OnStage() )
2511     {
2512       mOnStageSignalled = true; // signal required next time Actor is removed
2513     }
2514   }
2515 }
2516
2517 void Actor::DisconnectFromStage()
2518 {
2519   // This container is used instead of walking the Actor hierachy.
2520   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2521   ActorContainer disconnectionList;
2522
2523   // This stage is atomic i.e. not interrupted by user callbacks
2524   RecursiveDisconnectFromStage( disconnectionList );
2525
2526   // Notify applications about the newly disconnected actors.
2527   const ActorIter endIter = disconnectionList.end();
2528   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2529   {
2530     Actor& actor = GetImplementation( *iter );
2531     actor.NotifyStageDisconnection();
2532   }
2533 }
2534
2535 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2536 {
2537   DALI_ASSERT_ALWAYS( OnStage() );
2538
2539   // Recursively disconnect children
2540   if( mChildren )
2541   {
2542     ActorConstIter endIter = mChildren->end();
2543     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2544     {
2545       Actor& actor = GetImplementation( *iter );
2546       actor.RecursiveDisconnectFromStage( disconnectionList );
2547     }
2548   }
2549
2550   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2551   disconnectionList.push_back( Dali::Actor( this ) );
2552
2553   // Notification for internal derived classes
2554   OnStageDisconnectionInternal();
2555
2556   DisconnectFromSceneGraph();
2557
2558   mIsOnStage = false;
2559 }
2560
2561 /**
2562  * This method is called by an actor or its parent, before a node removal message is sent.
2563  * This is recursive; the child calls DisconnectFromStage() for its children.
2564  */
2565 void Actor::DisconnectFromSceneGraph()
2566 {
2567   // Notification for Object::Observers
2568   OnSceneObjectRemove();
2569
2570   // Notify attachment
2571   if( mAttachment )
2572   {
2573     mAttachment->Disconnect();
2574   }
2575
2576 #ifdef DALI_DYNAMICS_SUPPORT
2577   // Notify dynamics
2578   if( NULL != mDynamicsData )
2579   {
2580     DisconnectDynamics();
2581   }
2582 #endif
2583 }
2584
2585 void Actor::NotifyStageDisconnection()
2586 {
2587   // Actors can be added (in a callback), before the off-stage state is reported.
2588   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2589   // only do this step if there is a stage, i.e. Core is not being shut down
2590   if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2591   {
2592     // Notification for external (CustomeActor) derived classes
2593     OnStageDisconnectionExternal();
2594
2595     if( !mOffStageSignal.Empty() )
2596     {
2597       Dali::Actor handle( this );
2598       mOffStageSignal.Emit( handle );
2599     }
2600
2601     // Guard against Add during callbacks
2602     if( !OnStage() )
2603     {
2604       mOnStageSignalled = false; // signal required next time Actor is added
2605     }
2606   }
2607 }
2608
2609 bool Actor::IsNodeConnected() const
2610 {
2611   bool connected( false );
2612
2613   if( OnStage() &&
2614   NULL != mNode )
2615   {
2616     if( mNode->IsRoot() || mNode->GetParent() )
2617     {
2618       connected = true;
2619     }
2620   }
2621
2622   return connected;
2623 }
2624
2625 unsigned int Actor::GetDefaultPropertyCount() const
2626 {
2627   return DEFAULT_PROPERTY_COUNT;
2628 }
2629
2630 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2631 {
2632   indices.Reserve( DEFAULT_PROPERTY_COUNT );
2633
2634   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2635   {
2636     indices.PushBack( i );
2637   }
2638 }
2639
2640 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2641 {
2642   if( index < DEFAULT_PROPERTY_COUNT )
2643   {
2644     return DEFAULT_PROPERTY_DETAILS[ index ].name;
2645   }
2646
2647   return NULL;
2648 }
2649
2650 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2651 {
2652   Property::Index index = Property::INVALID_INDEX;
2653
2654   // Look for name in default properties
2655   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2656   {
2657     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2658     if( 0 == name.compare( property->name ) )
2659     {
2660       index = i;
2661       break;
2662     }
2663   }
2664
2665   return index;
2666 }
2667
2668 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2669 {
2670   if( index < DEFAULT_PROPERTY_COUNT )
2671   {
2672     return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2673   }
2674
2675   return false;
2676 }
2677
2678 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2679 {
2680   if( index < DEFAULT_PROPERTY_COUNT )
2681   {
2682     return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2683   }
2684
2685   return false;
2686 }
2687
2688 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2689 {
2690   if( index < DEFAULT_PROPERTY_COUNT )
2691   {
2692     return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2693   }
2694
2695   return false;
2696 }
2697
2698 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2699 {
2700   if( index < DEFAULT_PROPERTY_COUNT )
2701   {
2702     return DEFAULT_PROPERTY_DETAILS[ index ].type;
2703   }
2704
2705   // index out of range...return Property::NONE
2706   return Property::NONE;
2707 }
2708
2709 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2710 {
2711   switch( index )
2712   {
2713     case Dali::Actor::Property::PARENT_ORIGIN:
2714     {
2715       SetParentOrigin( property.Get< Vector3 >() );
2716       break;
2717     }
2718
2719     case Dali::Actor::Property::PARENT_ORIGIN_X:
2720     {
2721       SetParentOriginX( property.Get< float >() );
2722       break;
2723     }
2724
2725     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2726     {
2727       SetParentOriginY( property.Get< float >() );
2728       break;
2729     }
2730
2731     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2732     {
2733       SetParentOriginZ( property.Get< float >() );
2734       break;
2735     }
2736
2737     case Dali::Actor::Property::ANCHOR_POINT:
2738     {
2739       SetAnchorPoint( property.Get< Vector3 >() );
2740       break;
2741     }
2742
2743     case Dali::Actor::Property::ANCHOR_POINT_X:
2744     {
2745       SetAnchorPointX( property.Get< float >() );
2746       break;
2747     }
2748
2749     case Dali::Actor::Property::ANCHOR_POINT_Y:
2750     {
2751       SetAnchorPointY( property.Get< float >() );
2752       break;
2753     }
2754
2755     case Dali::Actor::Property::ANCHOR_POINT_Z:
2756     {
2757       SetAnchorPointZ( property.Get< float >() );
2758       break;
2759     }
2760
2761     case Dali::Actor::Property::SIZE:
2762     {
2763       SetSize( property.Get< Vector3 >() );
2764       break;
2765     }
2766
2767     case Dali::Actor::Property::SIZE_WIDTH:
2768     {
2769       SetWidth( property.Get< float >() );
2770       break;
2771     }
2772
2773     case Dali::Actor::Property::SIZE_HEIGHT:
2774     {
2775       SetHeight( property.Get< float >() );
2776       break;
2777     }
2778
2779     case Dali::Actor::Property::SIZE_DEPTH:
2780     {
2781       SetDepth( property.Get< float >() );
2782       break;
2783     }
2784
2785     case Dali::Actor::Property::POSITION:
2786     {
2787       SetPosition( property.Get< Vector3 >() );
2788       break;
2789     }
2790
2791     case Dali::Actor::Property::POSITION_X:
2792     {
2793       SetX( property.Get< float >() );
2794       break;
2795     }
2796
2797     case Dali::Actor::Property::POSITION_Y:
2798     {
2799       SetY( property.Get< float >() );
2800       break;
2801     }
2802
2803     case Dali::Actor::Property::POSITION_Z:
2804     {
2805       SetZ( property.Get< float >() );
2806       break;
2807     }
2808
2809     case Dali::Actor::Property::ORIENTATION:
2810     {
2811       SetOrientation( property.Get< Quaternion >() );
2812       break;
2813     }
2814
2815     case Dali::Actor::Property::SCALE:
2816     {
2817       SetScale( property.Get< Vector3 >() );
2818       break;
2819     }
2820
2821     case Dali::Actor::Property::SCALE_X:
2822     {
2823       SetScaleX( property.Get< float >() );
2824       break;
2825     }
2826
2827     case Dali::Actor::Property::SCALE_Y:
2828     {
2829       SetScaleY( property.Get< float >() );
2830       break;
2831     }
2832
2833     case Dali::Actor::Property::SCALE_Z:
2834     {
2835       SetScaleZ( property.Get< float >() );
2836       break;
2837     }
2838
2839     case Dali::Actor::Property::VISIBLE:
2840     {
2841       SetVisible( property.Get< bool >() );
2842       break;
2843     }
2844
2845     case Dali::Actor::Property::COLOR:
2846     {
2847       SetColor( property.Get< Vector4 >() );
2848       break;
2849     }
2850
2851     case Dali::Actor::Property::COLOR_RED:
2852     {
2853       SetColorRed( property.Get< float >() );
2854       break;
2855     }
2856
2857     case Dali::Actor::Property::COLOR_GREEN:
2858     {
2859       SetColorGreen( property.Get< float >() );
2860       break;
2861     }
2862
2863     case Dali::Actor::Property::COLOR_BLUE:
2864     {
2865       SetColorBlue( property.Get< float >() );
2866       break;
2867     }
2868
2869     case Dali::Actor::Property::COLOR_ALPHA:
2870     {
2871       SetOpacity( property.Get< float >() );
2872       break;
2873     }
2874
2875     case Dali::Actor::Property::NAME:
2876     {
2877       SetName( property.Get< std::string >() );
2878       break;
2879     }
2880
2881     case Dali::Actor::Property::SENSITIVE:
2882     {
2883       SetSensitive( property.Get< bool >() );
2884       break;
2885     }
2886
2887     case Dali::Actor::Property::LEAVE_REQUIRED:
2888     {
2889       SetLeaveRequired( property.Get< bool >() );
2890       break;
2891     }
2892
2893     case Dali::Actor::Property::INHERIT_ORIENTATION:
2894     {
2895       SetInheritOrientation( property.Get< bool >() );
2896       break;
2897     }
2898
2899     case Dali::Actor::Property::INHERIT_SCALE:
2900     {
2901       SetInheritScale( property.Get< bool >() );
2902       break;
2903     }
2904
2905     case Dali::Actor::Property::COLOR_MODE:
2906     {
2907       SetColorMode( Scripting::GetColorMode( property.Get< std::string >() ) );
2908       break;
2909     }
2910
2911     case Dali::Actor::Property::POSITION_INHERITANCE:
2912     {
2913       SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get< std::string >() ) );
2914       break;
2915     }
2916
2917     case Dali::Actor::Property::DRAW_MODE:
2918     {
2919       SetDrawMode( Scripting::GetDrawMode( property.Get< std::string >() ) );
2920       break;
2921     }
2922
2923     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2924     {
2925       SetSizeModeFactor( property.Get< Vector3 >() );
2926       break;
2927     }
2928
2929     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2930     {
2931       ResizePolicy::Type type;
2932       if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount, type ) )
2933       {
2934         SetResizePolicy( type, Dimension::WIDTH );
2935       }
2936       break;
2937     }
2938
2939     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2940     {
2941       ResizePolicy::Type type;
2942       if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount, type ) )
2943       {
2944         SetResizePolicy( type, Dimension::HEIGHT );
2945       }
2946       break;
2947     }
2948
2949     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2950     {
2951       SizeScalePolicy::Type type;
2952       if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount, type ) )
2953       {
2954         SetSizeScalePolicy( type );
2955       }
2956       break;
2957     }
2958
2959     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2960     {
2961       if( property.Get< bool >() )
2962       {
2963         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2964       }
2965       break;
2966     }
2967
2968     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2969     {
2970       if( property.Get< bool >() )
2971       {
2972         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2973       }
2974       break;
2975     }
2976
2977     case Dali::Actor::Property::PADDING:
2978     {
2979       Vector4 padding = property.Get< Vector4 >();
2980       SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2981       SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2982       break;
2983     }
2984
2985     case Dali::Actor::Property::MINIMUM_SIZE:
2986     {
2987       Vector2 size = property.Get< Vector2 >();
2988       SetMinimumSize( size.x, Dimension::WIDTH );
2989       SetMinimumSize( size.y, Dimension::HEIGHT );
2990       break;
2991     }
2992
2993     case Dali::Actor::Property::MAXIMUM_SIZE:
2994     {
2995       Vector2 size = property.Get< Vector2 >();
2996       SetMaximumSize( size.x, Dimension::WIDTH );
2997       SetMaximumSize( size.y, Dimension::HEIGHT );
2998       break;
2999     }
3000
3001     default:
3002     {
3003       // this can happen in the case of a non-animatable default property so just do nothing
3004       break;
3005     }
3006   }
3007 }
3008
3009 // TODO: This method needs to be removed
3010 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
3011 {
3012   switch( entry.type )
3013   {
3014     case Property::BOOLEAN:
3015     {
3016       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
3017       DALI_ASSERT_DEBUG( NULL != property );
3018
3019       // property is being used in a separate thread; queue a message to set the property
3020       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
3021
3022       break;
3023     }
3024
3025     case Property::INTEGER:
3026     {
3027       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
3028       DALI_ASSERT_DEBUG( NULL != property );
3029
3030       // property is being used in a separate thread; queue a message to set the property
3031       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
3032
3033       break;
3034     }
3035
3036     case Property::UNSIGNED_INTEGER:
3037     {
3038       const AnimatableProperty< unsigned int >* property = dynamic_cast< const AnimatableProperty< unsigned int >* >( entry.GetSceneGraphProperty() );
3039       DALI_ASSERT_DEBUG( NULL != property );
3040
3041       // property is being used in a separate thread; queue a message to set the property
3042       SceneGraph::NodePropertyMessage<unsigned int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<unsigned int>::Bake, value.Get<unsigned int>() );
3043
3044       break;
3045     }
3046
3047     case Property::FLOAT:
3048     {
3049       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
3050       DALI_ASSERT_DEBUG( NULL != property );
3051
3052       // property is being used in a separate thread; queue a message to set the property
3053       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
3054
3055       break;
3056     }
3057
3058     case Property::VECTOR2:
3059     {
3060       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
3061       DALI_ASSERT_DEBUG( NULL != property );
3062
3063       // property is being used in a separate thread; queue a message to set the property
3064       if(entry.componentIndex == 0)
3065       {
3066         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
3067       }
3068       else if(entry.componentIndex == 1)
3069       {
3070         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
3071       }
3072       else
3073       {
3074         SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
3075       }
3076
3077       break;
3078     }
3079
3080     case Property::VECTOR3:
3081     {
3082       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
3083       DALI_ASSERT_DEBUG( NULL != property );
3084
3085       // property is being used in a separate thread; queue a message to set the property
3086       if(entry.componentIndex == 0)
3087       {
3088         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
3089       }
3090       else if(entry.componentIndex == 1)
3091       {
3092         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
3093       }
3094       else if(entry.componentIndex == 2)
3095       {
3096         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
3097       }
3098       else
3099       {
3100         SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
3101       }
3102
3103       break;
3104     }
3105
3106     case Property::VECTOR4:
3107     {
3108       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
3109       DALI_ASSERT_DEBUG( NULL != property );
3110
3111       // property is being used in a separate thread; queue a message to set the property
3112       if(entry.componentIndex == 0)
3113       {
3114         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3115       }
3116       else if(entry.componentIndex == 1)
3117       {
3118         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3119       }
3120       else if(entry.componentIndex == 2)
3121       {
3122         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3123       }
3124       else if(entry.componentIndex == 3)
3125       {
3126         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3127       }
3128       else
3129       {
3130         SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3131       }
3132
3133       break;
3134     }
3135
3136     case Property::ROTATION:
3137     {
3138       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3139       DALI_ASSERT_DEBUG( NULL != property );
3140
3141       // property is being used in a separate thread; queue a message to set the property
3142       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
3143
3144       break;
3145     }
3146
3147     case Property::MATRIX:
3148     {
3149       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3150       DALI_ASSERT_DEBUG( NULL != property );
3151
3152       // property is being used in a separate thread; queue a message to set the property
3153       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
3154
3155       break;
3156     }
3157
3158     case Property::MATRIX3:
3159     {
3160       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3161       DALI_ASSERT_DEBUG( NULL != property );
3162
3163       // property is being used in a separate thread; queue a message to set the property
3164       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
3165
3166       break;
3167     }
3168
3169     default:
3170     {
3171       DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
3172       break;
3173     }
3174   }
3175 }
3176
3177 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3178 {
3179   Property::Value value;
3180
3181   switch( index )
3182   {
3183     case Dali::Actor::Property::PARENT_ORIGIN:
3184     {
3185       value = GetCurrentParentOrigin();
3186       break;
3187     }
3188
3189     case Dali::Actor::Property::PARENT_ORIGIN_X:
3190     {
3191       value = GetCurrentParentOrigin().x;
3192       break;
3193     }
3194
3195     case Dali::Actor::Property::PARENT_ORIGIN_Y:
3196     {
3197       value = GetCurrentParentOrigin().y;
3198       break;
3199     }
3200
3201     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3202     {
3203       value = GetCurrentParentOrigin().z;
3204       break;
3205     }
3206
3207     case Dali::Actor::Property::ANCHOR_POINT:
3208     {
3209       value = GetCurrentAnchorPoint();
3210       break;
3211     }
3212
3213     case Dali::Actor::Property::ANCHOR_POINT_X:
3214     {
3215       value = GetCurrentAnchorPoint().x;
3216       break;
3217     }
3218
3219     case Dali::Actor::Property::ANCHOR_POINT_Y:
3220     {
3221       value = GetCurrentAnchorPoint().y;
3222       break;
3223     }
3224
3225     case Dali::Actor::Property::ANCHOR_POINT_Z:
3226     {
3227       value = GetCurrentAnchorPoint().z;
3228       break;
3229     }
3230
3231     case Dali::Actor::Property::SIZE:
3232     {
3233       value = GetCurrentSize();
3234       break;
3235     }
3236
3237     case Dali::Actor::Property::SIZE_WIDTH:
3238     {
3239       value = GetCurrentSize().width;
3240       break;
3241     }
3242
3243     case Dali::Actor::Property::SIZE_HEIGHT:
3244     {
3245       value = GetCurrentSize().height;
3246       break;
3247     }
3248
3249     case Dali::Actor::Property::SIZE_DEPTH:
3250     {
3251       value = GetCurrentSize().depth;
3252       break;
3253     }
3254
3255     case Dali::Actor::Property::POSITION:
3256     {
3257       value = GetCurrentPosition();
3258       break;
3259     }
3260
3261     case Dali::Actor::Property::POSITION_X:
3262     {
3263       value = GetCurrentPosition().x;
3264       break;
3265     }
3266
3267     case Dali::Actor::Property::POSITION_Y:
3268     {
3269       value = GetCurrentPosition().y;
3270       break;
3271     }
3272
3273     case Dali::Actor::Property::POSITION_Z:
3274     {
3275       value = GetCurrentPosition().z;
3276       break;
3277     }
3278
3279     case Dali::Actor::Property::WORLD_POSITION:
3280     {
3281       value = GetCurrentWorldPosition();
3282       break;
3283     }
3284
3285     case Dali::Actor::Property::WORLD_POSITION_X:
3286     {
3287       value = GetCurrentWorldPosition().x;
3288       break;
3289     }
3290
3291     case Dali::Actor::Property::WORLD_POSITION_Y:
3292     {
3293       value = GetCurrentWorldPosition().y;
3294       break;
3295     }
3296
3297     case Dali::Actor::Property::WORLD_POSITION_Z:
3298     {
3299       value = GetCurrentWorldPosition().z;
3300       break;
3301     }
3302
3303     case Dali::Actor::Property::ORIENTATION:
3304     {
3305       value = GetCurrentOrientation();
3306       break;
3307     }
3308
3309     case Dali::Actor::Property::WORLD_ORIENTATION:
3310     {
3311       value = GetCurrentWorldOrientation();
3312       break;
3313     }
3314
3315     case Dali::Actor::Property::SCALE:
3316     {
3317       value = GetCurrentScale();
3318       break;
3319     }
3320
3321     case Dali::Actor::Property::SCALE_X:
3322     {
3323       value = GetCurrentScale().x;
3324       break;
3325     }
3326
3327     case Dali::Actor::Property::SCALE_Y:
3328     {
3329       value = GetCurrentScale().y;
3330       break;
3331     }
3332
3333     case Dali::Actor::Property::SCALE_Z:
3334     {
3335       value = GetCurrentScale().z;
3336       break;
3337     }
3338
3339     case Dali::Actor::Property::WORLD_SCALE:
3340     {
3341       value = GetCurrentWorldScale();
3342       break;
3343     }
3344
3345     case Dali::Actor::Property::VISIBLE:
3346     {
3347       value = IsVisible();
3348       break;
3349     }
3350
3351     case Dali::Actor::Property::COLOR:
3352     {
3353       value = GetCurrentColor();
3354       break;
3355     }
3356
3357     case Dali::Actor::Property::COLOR_RED:
3358     {
3359       value = GetCurrentColor().r;
3360       break;
3361     }
3362
3363     case Dali::Actor::Property::COLOR_GREEN:
3364     {
3365       value = GetCurrentColor().g;
3366       break;
3367     }
3368
3369     case Dali::Actor::Property::COLOR_BLUE:
3370     {
3371       value = GetCurrentColor().b;
3372       break;
3373     }
3374
3375     case Dali::Actor::Property::COLOR_ALPHA:
3376     {
3377       value = GetCurrentColor().a;
3378       break;
3379     }
3380
3381     case Dali::Actor::Property::WORLD_COLOR:
3382     {
3383       value = GetCurrentWorldColor();
3384       break;
3385     }
3386
3387     case Dali::Actor::Property::WORLD_MATRIX:
3388     {
3389       value = GetCurrentWorldMatrix();
3390       break;
3391     }
3392
3393     case Dali::Actor::Property::NAME:
3394     {
3395       value = GetName();
3396       break;
3397     }
3398
3399     case Dali::Actor::Property::SENSITIVE:
3400     {
3401       value = IsSensitive();
3402       break;
3403     }
3404
3405     case Dali::Actor::Property::LEAVE_REQUIRED:
3406     {
3407       value = GetLeaveRequired();
3408       break;
3409     }
3410
3411     case Dali::Actor::Property::INHERIT_ORIENTATION:
3412     {
3413       value = IsOrientationInherited();
3414       break;
3415     }
3416
3417     case Dali::Actor::Property::INHERIT_SCALE:
3418     {
3419       value = IsScaleInherited();
3420       break;
3421     }
3422
3423     case Dali::Actor::Property::COLOR_MODE:
3424     {
3425       value = Scripting::GetColorMode( GetColorMode() );
3426       break;
3427     }
3428
3429     case Dali::Actor::Property::POSITION_INHERITANCE:
3430     {
3431       value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3432       break;
3433     }
3434
3435     case Dali::Actor::Property::DRAW_MODE:
3436     {
3437       value = Scripting::GetDrawMode( GetDrawMode() );
3438       break;
3439     }
3440
3441     case Dali::Actor::Property::SIZE_MODE_FACTOR:
3442     {
3443       value = GetSizeModeFactor();
3444       break;
3445     }
3446
3447     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3448     {
3449       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount );
3450       break;
3451     }
3452
3453     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3454     {
3455       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount );
3456       break;
3457     }
3458
3459     case Dali::Actor::Property::SIZE_SCALE_POLICY:
3460     {
3461       value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount );
3462       break;
3463     }
3464
3465     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3466     {
3467       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3468       break;
3469     }
3470
3471     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3472     {
3473       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3474       break;
3475     }
3476
3477     case Dali::Actor::Property::PADDING:
3478     {
3479       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3480       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3481       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3482       break;
3483     }
3484
3485     case Dali::Actor::Property::MINIMUM_SIZE:
3486     {
3487       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3488       break;
3489     }
3490
3491     case Dali::Actor::Property::MAXIMUM_SIZE:
3492     {
3493       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3494       break;
3495     }
3496
3497     default:
3498     {
3499       DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3500       break;
3501     }
3502   }
3503
3504   return value;
3505 }
3506
3507 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3508 {
3509   return mNode;
3510 }
3511
3512 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3513 {
3514   // This method should only return an object connected to the scene-graph
3515   return OnStage() ? mNode : NULL;
3516 }
3517
3518 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3519 {
3520   DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3521
3522   const PropertyBase* property( NULL );
3523
3524   // This method should only return a property of an object connected to the scene-graph
3525   if( !OnStage() )
3526   {
3527     return property;
3528   }
3529
3530   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3531   {
3532     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3533     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3534
3535     property = animatable->GetSceneGraphProperty();
3536   }
3537   else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3538   {
3539     CustomPropertyMetadata* custom = FindCustomProperty( index );
3540     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3541
3542     property = custom->GetSceneGraphProperty();
3543   }
3544   else if( NULL != mNode )
3545   {
3546     switch( index )
3547     {
3548       case Dali::Actor::Property::SIZE:
3549         property = &mNode->mSize;
3550         break;
3551
3552       case Dali::Actor::Property::SIZE_WIDTH:
3553         property = &mNode->mSize;
3554         break;
3555
3556       case Dali::Actor::Property::SIZE_HEIGHT:
3557         property = &mNode->mSize;
3558         break;
3559
3560       case Dali::Actor::Property::SIZE_DEPTH:
3561         property = &mNode->mSize;
3562         break;
3563
3564       case Dali::Actor::Property::POSITION:
3565         property = &mNode->mPosition;
3566         break;
3567
3568       case Dali::Actor::Property::POSITION_X:
3569         property = &mNode->mPosition;
3570         break;
3571
3572       case Dali::Actor::Property::POSITION_Y:
3573         property = &mNode->mPosition;
3574         break;
3575
3576       case Dali::Actor::Property::POSITION_Z:
3577         property = &mNode->mPosition;
3578         break;
3579
3580       case Dali::Actor::Property::ORIENTATION:
3581         property = &mNode->mOrientation;
3582         break;
3583
3584       case Dali::Actor::Property::SCALE:
3585         property = &mNode->mScale;
3586         break;
3587
3588       case Dali::Actor::Property::SCALE_X:
3589         property = &mNode->mScale;
3590         break;
3591
3592       case Dali::Actor::Property::SCALE_Y:
3593         property = &mNode->mScale;
3594         break;
3595
3596       case Dali::Actor::Property::SCALE_Z:
3597         property = &mNode->mScale;
3598         break;
3599
3600       case Dali::Actor::Property::VISIBLE:
3601         property = &mNode->mVisible;
3602         break;
3603
3604       case Dali::Actor::Property::COLOR:
3605         property = &mNode->mColor;
3606         break;
3607
3608       case Dali::Actor::Property::COLOR_RED:
3609         property = &mNode->mColor;
3610         break;
3611
3612       case Dali::Actor::Property::COLOR_GREEN:
3613         property = &mNode->mColor;
3614         break;
3615
3616       case Dali::Actor::Property::COLOR_BLUE:
3617         property = &mNode->mColor;
3618         break;
3619
3620       case Dali::Actor::Property::COLOR_ALPHA:
3621         property = &mNode->mColor;
3622         break;
3623
3624       default:
3625         break;
3626     }
3627   }
3628
3629   return property;
3630 }
3631
3632 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3633 {
3634   const PropertyInputImpl* property( NULL );
3635
3636   // This method should only return a property of an object connected to the scene-graph
3637   if( !OnStage() )
3638   {
3639     return property;
3640   }
3641
3642   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3643   {
3644     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3645     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3646
3647     property = animatable->GetSceneGraphProperty();
3648   }
3649   else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3650   {
3651     CustomPropertyMetadata* custom = FindCustomProperty( index );
3652     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3653     property = custom->GetSceneGraphProperty();
3654   }
3655   else if( NULL != mNode )
3656   {
3657     switch( index )
3658     {
3659       case Dali::Actor::Property::PARENT_ORIGIN:
3660         property = &mNode->mParentOrigin;
3661         break;
3662
3663       case Dali::Actor::Property::PARENT_ORIGIN_X:
3664         property = &mNode->mParentOrigin;
3665         break;
3666
3667       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3668         property = &mNode->mParentOrigin;
3669         break;
3670
3671       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3672         property = &mNode->mParentOrigin;
3673         break;
3674
3675       case Dali::Actor::Property::ANCHOR_POINT:
3676         property = &mNode->mAnchorPoint;
3677         break;
3678
3679       case Dali::Actor::Property::ANCHOR_POINT_X:
3680         property = &mNode->mAnchorPoint;
3681         break;
3682
3683       case Dali::Actor::Property::ANCHOR_POINT_Y:
3684         property = &mNode->mAnchorPoint;
3685         break;
3686
3687       case Dali::Actor::Property::ANCHOR_POINT_Z:
3688         property = &mNode->mAnchorPoint;
3689         break;
3690
3691       case Dali::Actor::Property::SIZE:
3692         property = &mNode->mSize;
3693         break;
3694
3695       case Dali::Actor::Property::SIZE_WIDTH:
3696         property = &mNode->mSize;
3697         break;
3698
3699       case Dali::Actor::Property::SIZE_HEIGHT:
3700         property = &mNode->mSize;
3701         break;
3702
3703       case Dali::Actor::Property::SIZE_DEPTH:
3704         property = &mNode->mSize;
3705         break;
3706
3707       case Dali::Actor::Property::POSITION:
3708         property = &mNode->mPosition;
3709         break;
3710
3711       case Dali::Actor::Property::POSITION_X:
3712         property = &mNode->mPosition;
3713         break;
3714
3715       case Dali::Actor::Property::POSITION_Y:
3716         property = &mNode->mPosition;
3717         break;
3718
3719       case Dali::Actor::Property::POSITION_Z:
3720         property = &mNode->mPosition;
3721         break;
3722
3723       case Dali::Actor::Property::WORLD_POSITION:
3724         property = &mNode->mWorldPosition;
3725         break;
3726
3727       case Dali::Actor::Property::WORLD_POSITION_X:
3728         property = &mNode->mWorldPosition;
3729         break;
3730
3731       case Dali::Actor::Property::WORLD_POSITION_Y:
3732         property = &mNode->mWorldPosition;
3733         break;
3734
3735       case Dali::Actor::Property::WORLD_POSITION_Z:
3736         property = &mNode->mWorldPosition;
3737         break;
3738
3739       case Dali::Actor::Property::ORIENTATION:
3740         property = &mNode->mOrientation;
3741         break;
3742
3743       case Dali::Actor::Property::WORLD_ORIENTATION:
3744         property = &mNode->mWorldOrientation;
3745         break;
3746
3747       case Dali::Actor::Property::SCALE:
3748         property = &mNode->mScale;
3749         break;
3750
3751       case Dali::Actor::Property::SCALE_X:
3752         property = &mNode->mScale;
3753         break;
3754
3755       case Dali::Actor::Property::SCALE_Y:
3756         property = &mNode->mScale;
3757         break;
3758
3759       case Dali::Actor::Property::SCALE_Z:
3760         property = &mNode->mScale;
3761         break;
3762
3763       case Dali::Actor::Property::WORLD_SCALE:
3764         property = &mNode->mWorldScale;
3765         break;
3766
3767       case Dali::Actor::Property::VISIBLE:
3768         property = &mNode->mVisible;
3769         break;
3770
3771       case Dali::Actor::Property::COLOR:
3772         property = &mNode->mColor;
3773         break;
3774
3775       case Dali::Actor::Property::COLOR_RED:
3776         property = &mNode->mColor;
3777         break;
3778
3779       case Dali::Actor::Property::COLOR_GREEN:
3780         property = &mNode->mColor;
3781         break;
3782
3783       case Dali::Actor::Property::COLOR_BLUE:
3784         property = &mNode->mColor;
3785         break;
3786
3787       case Dali::Actor::Property::COLOR_ALPHA:
3788         property = &mNode->mColor;
3789         break;
3790
3791       case Dali::Actor::Property::WORLD_COLOR:
3792         property = &mNode->mWorldColor;
3793         break;
3794
3795       case Dali::Actor::Property::WORLD_MATRIX:
3796         property = &mNode->mWorldMatrix;
3797         break;
3798
3799       default:
3800         break;
3801     }
3802   }
3803
3804   return property;
3805 }
3806
3807 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3808 {
3809   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3810
3811   if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3812   {
3813     // check whether the animatable property is registered already, if not then register one.
3814     AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3815     if( animatableProperty )
3816     {
3817       componentIndex = animatableProperty->componentIndex;
3818     }
3819   }
3820   else
3821   {
3822     switch( index )
3823     {
3824       case Dali::Actor::Property::PARENT_ORIGIN_X:
3825       case Dali::Actor::Property::ANCHOR_POINT_X:
3826       case Dali::Actor::Property::SIZE_WIDTH:
3827       case Dali::Actor::Property::POSITION_X:
3828       case Dali::Actor::Property::WORLD_POSITION_X:
3829       case Dali::Actor::Property::SCALE_X:
3830       case Dali::Actor::Property::COLOR_RED:
3831       {
3832         componentIndex = 0;
3833         break;
3834       }
3835
3836       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3837       case Dali::Actor::Property::ANCHOR_POINT_Y:
3838       case Dali::Actor::Property::SIZE_HEIGHT:
3839       case Dali::Actor::Property::POSITION_Y:
3840       case Dali::Actor::Property::WORLD_POSITION_Y:
3841       case Dali::Actor::Property::SCALE_Y:
3842       case Dali::Actor::Property::COLOR_GREEN:
3843       {
3844         componentIndex = 1;
3845         break;
3846       }
3847
3848       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3849       case Dali::Actor::Property::ANCHOR_POINT_Z:
3850       case Dali::Actor::Property::SIZE_DEPTH:
3851       case Dali::Actor::Property::POSITION_Z:
3852       case Dali::Actor::Property::WORLD_POSITION_Z:
3853       case Dali::Actor::Property::SCALE_Z:
3854       case Dali::Actor::Property::COLOR_BLUE:
3855       {
3856         componentIndex = 2;
3857         break;
3858       }
3859
3860       case Dali::Actor::Property::COLOR_ALPHA:
3861       {
3862         componentIndex = 3;
3863         break;
3864       }
3865
3866       default:
3867       {
3868         // Do nothing
3869         break;
3870       }
3871     }
3872   }
3873
3874   return componentIndex;
3875 }
3876
3877 void Actor::SetParent( Actor* parent, int index )
3878 {
3879   if( parent )
3880   {
3881     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3882
3883     mParent = parent;
3884
3885     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3886          parent->OnStage() )
3887     {
3888       // Instruct each actor to create a corresponding node in the scene graph
3889       ConnectToStage( parent->GetDepth(), index );
3890     }
3891   }
3892   else // parent being set to NULL
3893   {
3894     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3895
3896     mParent = NULL;
3897
3898     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3899          OnStage() )
3900     {
3901       DALI_ASSERT_ALWAYS( mNode != NULL );
3902
3903       if( NULL != mNode )
3904       {
3905         // Disconnect the Node & its children from the scene-graph.
3906         DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3907       }
3908
3909       // Instruct each actor to discard pointers to the scene-graph
3910       DisconnectFromStage();
3911     }
3912   }
3913 }
3914
3915 SceneGraph::Node* Actor::CreateNode() const
3916 {
3917   return Node::New();
3918 }
3919
3920 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3921 {
3922   bool done = false;
3923   Actor* actor = dynamic_cast< Actor* >( object );
3924
3925   if( actor )
3926   {
3927     if( 0 == actionName.compare( ACTION_SHOW ) )
3928     {
3929       actor->SetVisible( true );
3930       done = true;
3931     }
3932     else if( 0 == actionName.compare( ACTION_HIDE ) )
3933     {
3934       actor->SetVisible( false );
3935       done = true;
3936     }
3937   }
3938
3939   return done;
3940 }
3941
3942 void Actor::EnsureRelayoutData()
3943 {
3944   // Assign relayout data.
3945   if( !mRelayoutData )
3946   {
3947     mRelayoutData = new RelayoutData();
3948   }
3949 }
3950
3951 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3952 {
3953   // Check if actor is dependent on parent
3954   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3955   {
3956     if( ( dimension & ( 1 << i ) ) )
3957     {
3958       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3959       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3960       {
3961         return true;
3962       }
3963     }
3964   }
3965
3966   return false;
3967 }
3968
3969 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3970 {
3971   // Check if actor is dependent on children
3972   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3973   {
3974     if( ( dimension & ( 1 << i ) ) )
3975     {
3976       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3977       switch( resizePolicy )
3978       {
3979         case ResizePolicy::FIT_TO_CHILDREN:
3980         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
3981         {
3982           return true;
3983         }
3984
3985         default:
3986         {
3987           break;
3988         }
3989       }
3990     }
3991   }
3992
3993   return false;
3994 }
3995
3996 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3997 {
3998   return Actor::RelayoutDependentOnChildren( dimension );
3999 }
4000
4001 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4002 {
4003   // Check each possible dimension and see if it is dependent on the input one
4004   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4005   {
4006     if( dimension & ( 1 << i ) )
4007     {
4008       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4009     }
4010   }
4011
4012   return false;
4013 }
4014
4015 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4016 {
4017   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4018   {
4019     if( dimension & ( 1 << i ) )
4020     {
4021       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4022     }
4023   }
4024 }
4025
4026 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4027 {
4028   // If more than one dimension is requested, just return the first one found
4029   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4030   {
4031     if( ( dimension & ( 1 << i ) ) )
4032     {
4033       return mRelayoutData->negotiatedDimensions[ i ];
4034     }
4035   }
4036
4037   return 0.0f;   // Default
4038 }
4039
4040 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4041 {
4042   EnsureRelayoutData();
4043
4044   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4045   {
4046     if( dimension & ( 1 << i ) )
4047     {
4048       mRelayoutData->dimensionPadding[ i ] = padding;
4049     }
4050   }
4051 }
4052
4053 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4054 {
4055   if ( mRelayoutData )
4056   {
4057     // If more than one dimension is requested, just return the first one found
4058     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4059     {
4060       if( ( dimension & ( 1 << i ) ) )
4061       {
4062         return mRelayoutData->dimensionPadding[ i ];
4063       }
4064     }
4065   }
4066
4067   return GetDefaultDimensionPadding();
4068 }
4069
4070 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4071 {
4072   EnsureRelayoutData();
4073
4074   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4075   {
4076     if( dimension & ( 1 << i ) )
4077     {
4078       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4079     }
4080   }
4081 }
4082
4083 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4084 {
4085   if ( mRelayoutData )
4086   {
4087     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4088     {
4089       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4090       {
4091         return true;
4092       }
4093     }
4094   }
4095
4096   return false;
4097 }
4098
4099 float Actor::GetHeightForWidthBase( float width )
4100 {
4101   float height = 0.0f;
4102
4103   const Vector3 naturalSize = GetNaturalSize();
4104   if( naturalSize.width > 0.0f )
4105   {
4106     height = naturalSize.height * width / naturalSize.width;
4107   }
4108   else // we treat 0 as 1:1 aspect ratio
4109   {
4110     height = width;
4111   }
4112
4113   return height;
4114 }
4115
4116 float Actor::GetWidthForHeightBase( float height )
4117 {
4118   float width = 0.0f;
4119
4120   const Vector3 naturalSize = GetNaturalSize();
4121   if( naturalSize.height > 0.0f )
4122   {
4123     width = naturalSize.width * height / naturalSize.height;
4124   }
4125   else // we treat 0 as 1:1 aspect ratio
4126   {
4127     width = height;
4128   }
4129
4130   return width;
4131 }
4132
4133 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4134 {
4135   // Fill to parent, taking size mode factor into account
4136   switch( child.GetResizePolicy( dimension ) )
4137   {
4138     case ResizePolicy::FILL_TO_PARENT:
4139     {
4140       return GetLatestSize( dimension );
4141     }
4142
4143     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4144     {
4145       return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4146     }
4147
4148     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4149     {
4150       return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4151     }
4152
4153     default:
4154     {
4155       return GetLatestSize( dimension );
4156     }
4157   }
4158 }
4159
4160 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4161 {
4162   // Can be overridden in derived class
4163   return CalculateChildSizeBase( child, dimension );
4164 }
4165
4166 float Actor::GetHeightForWidth( float width )
4167 {
4168   // Can be overridden in derived class
4169   return GetHeightForWidthBase( width );
4170 }
4171
4172 float Actor::GetWidthForHeight( float height )
4173 {
4174   // Can be overridden in derived class
4175   return GetWidthForHeightBase( height );
4176 }
4177
4178 float Actor::GetLatestSize( Dimension::Type dimension ) const
4179 {
4180   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4181 }
4182
4183 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4184 {
4185   Vector2 padding = GetPadding( dimension );
4186
4187   return GetLatestSize( dimension ) + padding.x + padding.y;
4188 }
4189
4190 float Actor::NegotiateFromParent( Dimension::Type dimension )
4191 {
4192   Actor* parent = GetParent();
4193   if( parent )
4194   {
4195     Vector2 padding( GetPadding( dimension ) );
4196     Vector2 parentPadding( parent->GetPadding( dimension ) );
4197     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4198   }
4199
4200   return 0.0f;
4201 }
4202
4203 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4204 {
4205   float maxDimensionPoint = 0.0f;
4206
4207   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4208   {
4209     Dali::Actor child = GetChildAt( i );
4210     Actor& childImpl = GetImplementation( child );
4211
4212     if( !childImpl.RelayoutDependentOnParent( dimension ) )
4213     {
4214       // Calculate the min and max points that the children range across
4215       float childPosition = GetDimensionValue( childImpl.GetTargetPosition(), dimension );
4216       float dimensionSize = childImpl.GetRelayoutSize( dimension );
4217       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4218     }
4219   }
4220
4221   return maxDimensionPoint;
4222 }
4223
4224 float Actor::GetSize( Dimension::Type dimension ) const
4225 {
4226   return GetDimensionValue( GetTargetSize(), dimension );
4227 }
4228
4229 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4230 {
4231   return GetDimensionValue( GetNaturalSize(), dimension );
4232 }
4233
4234 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4235 {
4236   switch( GetResizePolicy( dimension ) )
4237   {
4238     case ResizePolicy::USE_NATURAL_SIZE:
4239     {
4240       return GetNaturalSize( dimension );
4241     }
4242
4243     case ResizePolicy::FIXED:
4244     {
4245       return GetDimensionValue( GetPreferredSize(), dimension );
4246     }
4247
4248     case ResizePolicy::USE_ASSIGNED_SIZE:
4249     {
4250       return GetDimensionValue( maximumSize, dimension );
4251     }
4252
4253     case ResizePolicy::FILL_TO_PARENT:
4254     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4255     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4256     {
4257       return NegotiateFromParent( dimension );
4258     }
4259
4260     case ResizePolicy::FIT_TO_CHILDREN:
4261     {
4262       return NegotiateFromChildren( dimension );
4263     }
4264
4265     case ResizePolicy::DIMENSION_DEPENDENCY:
4266     {
4267       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4268
4269       // Custom rules
4270       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4271       {
4272         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4273       }
4274
4275       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4276       {
4277         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4278       }
4279
4280       break;
4281     }
4282
4283     default:
4284     {
4285       break;
4286     }
4287   }
4288
4289   return 0.0f;  // Default
4290 }
4291
4292 float Actor::ClampDimension( float size, Dimension::Type dimension )
4293 {
4294   const float minSize = GetMinimumSize( dimension );
4295   const float maxSize = GetMaximumSize( dimension );
4296
4297   return std::max( minSize, std::min( size, maxSize ) );
4298 }
4299
4300 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4301 {
4302   // Check if it needs to be negotiated
4303   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4304   {
4305     // Check that we havn't gotten into an infinite loop
4306     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4307     bool recursionFound = false;
4308     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4309     {
4310       if( *it == searchActor )
4311       {
4312         recursionFound = true;
4313         break;
4314       }
4315     }
4316
4317     if( !recursionFound )
4318     {
4319       // Record the path that we have taken
4320       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4321
4322       // Dimension dependency check
4323       for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4324       {
4325         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4326
4327         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4328         {
4329           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4330         }
4331       }
4332
4333       // Parent dependency check
4334       Actor* parent = GetParent();
4335       if( parent && RelayoutDependentOnParent( dimension ) )
4336       {
4337         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4338       }
4339
4340       // Children dependency check
4341       if( RelayoutDependentOnChildren( dimension ) )
4342       {
4343         for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4344         {
4345           Dali::Actor child = GetChildAt( i );
4346           Actor& childImpl = GetImplementation( child );
4347
4348           // Only relayout child first if it is not dependent on this actor
4349           if( !childImpl.RelayoutDependentOnParent( dimension ) )
4350           {
4351             childImpl.NegotiateDimension( dimension, allocatedSize, recursionStack );
4352           }
4353         }
4354       }
4355
4356       // For deriving classes
4357       OnCalculateRelayoutSize( dimension );
4358
4359       // All dependencies checked, calculate the size and set negotiated flag
4360       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4361
4362       SetNegotiatedDimension( newSize, dimension );
4363       SetLayoutNegotiated( true, dimension );
4364
4365       // For deriving classes
4366       OnLayoutNegotiated( newSize, dimension );
4367
4368       // This actor has been successfully processed, pop it off the recursion stack
4369       recursionStack.pop_back();
4370     }
4371     else
4372     {
4373       // TODO: Break infinite loop
4374       SetLayoutNegotiated( true, dimension );
4375     }
4376   }
4377 }
4378
4379 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4380 {
4381   // Negotiate all dimensions that require it
4382   ActorDimensionStack recursionStack;
4383
4384   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4385   {
4386     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4387
4388     // Negotiate
4389     NegotiateDimension( dimension, allocatedSize, recursionStack );
4390   }
4391 }
4392
4393 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4394 {
4395   switch( mRelayoutData->sizeSetPolicy )
4396   {
4397     case SizeScalePolicy::USE_SIZE_SET:
4398     {
4399       return size;
4400     }
4401
4402     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4403     {
4404       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4405       const Vector3 naturalSize = GetNaturalSize();
4406       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4407       {
4408         const float sizeRatio = size.width / size.height;
4409         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4410
4411         if( naturalSizeRatio < sizeRatio )
4412         {
4413           return Vector2( naturalSizeRatio * size.height, size.height );
4414         }
4415         else if( naturalSizeRatio > sizeRatio )
4416         {
4417           return Vector2( size.width, size.width / naturalSizeRatio );
4418         }
4419         else
4420         {
4421           return size;
4422         }
4423       }
4424
4425       break;
4426     }
4427
4428     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4429     {
4430       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4431       const Vector3 naturalSize = GetNaturalSize();
4432       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4433       {
4434         const float sizeRatio = size.width / size.height;
4435         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4436
4437         if( naturalSizeRatio < sizeRatio )
4438         {
4439           return Vector2( size.width, size.width / naturalSizeRatio );
4440         }
4441         else if( naturalSizeRatio > sizeRatio )
4442         {
4443           return Vector2( naturalSizeRatio * size.height, size.height );
4444         }
4445         else
4446         {
4447           return size;
4448         }
4449       }
4450     }
4451
4452     default:
4453     {
4454       break;
4455     }
4456   }
4457
4458   return size;
4459 }
4460
4461 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4462 {
4463   // Do the set actor size
4464   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4465
4466   // Adjust for size set policy
4467   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4468
4469   // Lock the flag to stop recursive relayouts on set size
4470   mRelayoutData->insideRelayout = true;
4471   SetSize( negotiatedSize );
4472   mRelayoutData->insideRelayout = false;
4473
4474   // Clear flags for all dimensions
4475   SetLayoutDirty( false );
4476
4477   // Give deriving classes a chance to respond
4478   OnRelayout( negotiatedSize, container );
4479
4480   if( !mOnRelayoutSignal.Empty() )
4481   {
4482     Dali::Actor handle( this );
4483     mOnRelayoutSignal.Emit( handle );
4484   }
4485 }
4486
4487 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4488 {
4489   // Do the negotiation
4490   NegotiateDimensions( allocatedSize );
4491
4492   // Set the actor size
4493   SetNegotiatedSize( container );
4494
4495   // Negotiate down to children
4496   const Vector2 newBounds = GetTargetSize().GetVectorXY();
4497
4498   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4499   {
4500     Dali::Actor child = GetChildAt( i );
4501
4502     // Only relayout if required
4503     if( GetImplementation( child ).RelayoutRequired() )
4504     {
4505       container.Add( child, newBounds );
4506     }
4507   }
4508 }
4509
4510 void Actor::RelayoutRequest( Dimension::Type dimension )
4511 {
4512   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4513   if( relayoutController )
4514   {
4515     Dali::Actor self( this );
4516     relayoutController->RequestRelayout( self, dimension );
4517   }
4518 }
4519
4520 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4521 {
4522 }
4523
4524 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4525 {
4526 }
4527
4528 void Actor::SetPreferredSize( const Vector2& size )
4529 {
4530   EnsureRelayoutData();
4531
4532   if( size.width > 0.0f )
4533   {
4534     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4535   }
4536
4537   if( size.height > 0.0f )
4538   {
4539     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4540   }
4541
4542   mRelayoutData->preferredSize = size;
4543
4544   RelayoutRequest();
4545 }
4546
4547 Vector2 Actor::GetPreferredSize() const
4548 {
4549   if ( mRelayoutData )
4550   {
4551     return mRelayoutData->preferredSize;
4552   }
4553
4554   return GetDefaultPreferredSize();
4555 }
4556
4557 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4558 {
4559   EnsureRelayoutData();
4560
4561   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4562   {
4563     if( dimension & ( 1 << i ) )
4564     {
4565       mRelayoutData->minimumSize[ i ] = size;
4566     }
4567   }
4568
4569   RelayoutRequest();
4570 }
4571
4572 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4573 {
4574   if ( mRelayoutData )
4575   {
4576     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4577     {
4578       if( dimension & ( 1 << i ) )
4579       {
4580         return mRelayoutData->minimumSize[ i ];
4581       }
4582     }
4583   }
4584
4585   return 0.0f;  // Default
4586 }
4587
4588 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4589 {
4590   EnsureRelayoutData();
4591
4592   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4593   {
4594     if( dimension & ( 1 << i ) )
4595     {
4596       mRelayoutData->maximumSize[ i ] = size;
4597     }
4598   }
4599
4600   RelayoutRequest();
4601 }
4602
4603 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4604 {
4605   if ( mRelayoutData )
4606   {
4607     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4608     {
4609       if( dimension & ( 1 << i ) )
4610       {
4611         return mRelayoutData->maximumSize[ i ];
4612       }
4613     }
4614   }
4615
4616   return FLT_MAX;  // Default
4617 }
4618
4619 } // namespace Internal
4620
4621 } // namespace Dali