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