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