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