Merge "Remove unnecessary stream operators from radian and degree as well as unnecess...
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/actors/actor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cmath>
23 #include <algorithm>
24 #include <cfloat>
25 #include <cstring> // for strcmp
26
27 // INTERNAL INCLUDES
28
29 #include <dali/public-api/common/dali-common.h>
30 #include <dali/public-api/common/constants.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/public-api/scripting/scripting.h>
36
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
46 #include <dali/internal/event/animation/constraint-impl.h>
47 #include <dali/internal/event/common/projection.h>
48 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
49 #include <dali/internal/update/common/animatable-property.h>
50 #include <dali/internal/update/nodes/node-messages.h>
51 #include <dali/internal/update/nodes/node-declarations.h>
52 #include <dali/internal/update/animation/scene-graph-constraint.h>
53 #include <dali/internal/event/events/actor-gesture-data.h>
54 #include <dali/internal/common/message.h>
55 #include <dali/integration-api/debug.h>
56
57 #ifdef DYNAMICS_SUPPORT
58 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
59 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
60 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
61 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
62 #endif
63
64 using Dali::Internal::SceneGraph::Node;
65 using Dali::Internal::SceneGraph::AnimatableProperty;
66 using Dali::Internal::SceneGraph::PropertyBase;
67
68 namespace Dali
69 {
70 namespace ResizePolicy
71 {
72
73 namespace
74 {
75 DALI_ENUM_TO_STRING_TABLE_BEGIN( Type )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 )DALI_ENUM_TO_STRING( USE_SIZE_SET )
94 DALI_ENUM_TO_STRING( FIT_WITH_ASPECT_RATIO )
95 DALI_ENUM_TO_STRING( FILL_WITH_ASPECT_RATIO )
96 DALI_ENUM_TO_STRING_TABLE_END( Type )
97 } // unnamed namespace
98 } // SizeScalePolicy
99
100 namespace Internal
101 {
102
103 unsigned int Actor::mActorCounter = 0;
104 ActorContainer Actor::mNullChildren;
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::FIXED;
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_MOUSE_WHEEL_EVENT = "mouse-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 ActorContainer Actor::GetChildren()
561 {
562   if( NULL != mChildren )
563   {
564     return *mChildren;
565   }
566
567   // return copy of mNullChildren
568   return mNullChildren;
569 }
570
571 const ActorContainer& Actor::GetChildren() const
572 {
573   if( NULL != mChildren )
574   {
575     return *mChildren;
576   }
577
578   // return const reference to mNullChildren
579   return mNullChildren;
580 }
581
582 ActorPtr Actor::FindChildByName( const std::string& actorName )
583 {
584   ActorPtr child = 0;
585   if( actorName == mName )
586   {
587     child = this;
588   }
589   else if( mChildren )
590   {
591     ActorIter end = mChildren->end();
592     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
593     {
594       child = GetImplementation( *iter ).FindChildByName( actorName );
595
596       if( child )
597       {
598         break;
599       }
600     }
601   }
602   return child;
603 }
604
605 ActorPtr Actor::FindChildById( const unsigned int id )
606 {
607   ActorPtr child = 0;
608   if( id == mId )
609   {
610     child = this;
611   }
612   else if( mChildren )
613   {
614     ActorIter end = mChildren->end();
615     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
616     {
617       child = GetImplementation( *iter ).FindChildById( id );
618
619       if( child )
620       {
621         break;
622       }
623     }
624   }
625   return child;
626 }
627
628 void Actor::SetParentOrigin( const Vector3& origin )
629 {
630   if( NULL != mNode )
631   {
632     // mNode is being used in a separate thread; queue a message to set the value & base value
633     SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
634   }
635
636   // Cache for event-thread access
637   if( !mParentOrigin )
638   {
639     // not allocated, check if different from default
640     if( ParentOrigin::DEFAULT != origin )
641     {
642       mParentOrigin = new Vector3( origin );
643     }
644   }
645   else
646   {
647     // check if different from current costs more than just set
648     *mParentOrigin = origin;
649   }
650 }
651
652 void Actor::SetParentOriginX( float x )
653 {
654   const Vector3& current = GetCurrentParentOrigin();
655
656   SetParentOrigin( Vector3( x, current.y, current.z ) );
657 }
658
659 void Actor::SetParentOriginY( float y )
660 {
661   const Vector3& current = GetCurrentParentOrigin();
662
663   SetParentOrigin( Vector3( current.x, y, current.z ) );
664 }
665
666 void Actor::SetParentOriginZ( float z )
667 {
668   const Vector3& current = GetCurrentParentOrigin();
669
670   SetParentOrigin( Vector3( current.x, current.y, z ) );
671 }
672
673 const Vector3& Actor::GetCurrentParentOrigin() const
674 {
675   // Cached for event-thread access
676   return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
677 }
678
679 void Actor::SetAnchorPoint( const Vector3& anchor )
680 {
681   if( NULL != mNode )
682   {
683     // mNode is being used in a separate thread; queue a message to set the value & base value
684     SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
685   }
686
687   // Cache for event-thread access
688   if( !mAnchorPoint )
689   {
690     // not allocated, check if different from default
691     if( AnchorPoint::DEFAULT != anchor )
692     {
693       mAnchorPoint = new Vector3( anchor );
694     }
695   }
696   else
697   {
698     // check if different from current costs more than just set
699     *mAnchorPoint = anchor;
700   }
701 }
702
703 void Actor::SetAnchorPointX( float x )
704 {
705   const Vector3& current = GetCurrentAnchorPoint();
706
707   SetAnchorPoint( Vector3( x, current.y, current.z ) );
708 }
709
710 void Actor::SetAnchorPointY( float y )
711 {
712   const Vector3& current = GetCurrentAnchorPoint();
713
714   SetAnchorPoint( Vector3( current.x, y, current.z ) );
715 }
716
717 void Actor::SetAnchorPointZ( float z )
718 {
719   const Vector3& current = GetCurrentAnchorPoint();
720
721   SetAnchorPoint( Vector3( current.x, current.y, z ) );
722 }
723
724 const Vector3& Actor::GetCurrentAnchorPoint() const
725 {
726   // Cached for event-thread access
727   return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
728 }
729
730 void Actor::SetPosition( float x, float y )
731 {
732   SetPosition( Vector3( x, y, 0.0f ) );
733 }
734
735 void Actor::SetPosition( float x, float y, float z )
736 {
737   SetPosition( Vector3( x, y, z ) );
738 }
739
740 void Actor::SetPosition( const Vector3& position )
741 {
742   mTargetPosition = position;
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::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
748   }
749 }
750
751 void Actor::SetX( float x )
752 {
753   mTargetPosition.x = x;
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>::BakeX, x );
759   }
760 }
761
762 void Actor::SetY( float y )
763 {
764   mTargetPosition.y = y;
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::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
770   }
771 }
772
773 void Actor::SetZ( float z )
774 {
775   mTargetPosition.z = z;
776
777   if( NULL != mNode )
778   {
779     // mNode is being used in a separate thread; queue a message to set the value & base value
780     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
781   }
782 }
783
784 void Actor::TranslateBy( const Vector3& distance )
785 {
786   mTargetPosition += distance;
787
788   if( NULL != mNode )
789   {
790     // mNode is being used in a separate thread; queue a message to set the value & base value
791     SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
792   }
793 }
794
795 const Vector3& Actor::GetCurrentPosition() const
796 {
797   if( NULL != mNode )
798   {
799     // mNode is being used in a separate thread; copy the value from the previous update
800     return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
801   }
802
803   return Vector3::ZERO;
804 }
805
806 const Vector3& Actor::GetTargetPosition() const
807 {
808   return mTargetPosition;
809 }
810
811 const Vector3& Actor::GetCurrentWorldPosition() const
812 {
813   if( NULL != mNode )
814   {
815     // mNode is being used in a separate thread; copy the value from the previous update
816     return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
817   }
818
819   return Vector3::ZERO;
820 }
821
822 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
823 {
824   // this flag is not animatable so keep the value
825   mPositionInheritanceMode = mode;
826   if( NULL != mNode )
827   {
828     // mNode is being used in a separate thread; queue a message to set the value
829     SetPositionInheritanceModeMessage( GetEventThreadServices(), *mNode, mode );
830   }
831 }
832
833 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
834 {
835   // Cached for event-thread access
836   return mPositionInheritanceMode;
837 }
838
839 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
840 {
841   Vector3 normalizedAxis( axis.x, axis.y, axis.z );
842   normalizedAxis.Normalize();
843
844   Quaternion orientation( angle, normalizedAxis );
845
846   SetOrientation( orientation );
847 }
848
849 void Actor::SetOrientation( const Quaternion& orientation )
850 {
851   if( NULL != mNode )
852   {
853     // mNode is being used in a separate thread; queue a message to set the value & base value
854     SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::Bake, orientation );
855   }
856 }
857
858 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
859 {
860   if( NULL != mNode )
861   {
862     // mNode is being used in a separate thread; queue a message to set the value & base value
863     SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
864   }
865 }
866
867 void Actor::RotateBy( const Quaternion& relativeRotation )
868 {
869   if( NULL != mNode )
870   {
871     // mNode is being used in a separate thread; queue a message to set the value & base value
872     SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
873   }
874 }
875
876 const Quaternion& Actor::GetCurrentOrientation() const
877 {
878   if( NULL != mNode )
879   {
880     // mNode is being used in a separate thread; copy the value from the previous update
881     return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
882   }
883
884   return Quaternion::IDENTITY;
885 }
886
887 const Quaternion& Actor::GetCurrentWorldOrientation() const
888 {
889   if( NULL != mNode )
890   {
891     // mNode is being used in a separate thread; copy the value from the previous update
892     return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
893   }
894
895   return Quaternion::IDENTITY;
896 }
897
898 void Actor::SetScale( float scale )
899 {
900   SetScale( Vector3( scale, scale, scale ) );
901 }
902
903 void Actor::SetScale( float x, float y, float z )
904 {
905   SetScale( Vector3( x, y, z ) );
906 }
907
908 void Actor::SetScale( const Vector3& scale )
909 {
910   if( NULL != mNode )
911   {
912     // mNode is being used in a separate thread; queue a message to set the value & base value
913     SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
914   }
915 }
916
917 void Actor::SetScaleX( float x )
918 {
919   if( NULL != mNode )
920   {
921     // mNode is being used in a separate thread; queue a message to set the value & base value
922     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
923   }
924 }
925
926 void Actor::SetScaleY( float y )
927 {
928   if( NULL != mNode )
929   {
930     // mNode is being used in a separate thread; queue a message to set the value & base value
931     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
932   }
933 }
934
935 void Actor::SetScaleZ( float z )
936 {
937   if( NULL != mNode )
938   {
939     // mNode is being used in a separate thread; queue a message to set the value & base value
940     SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
941   }
942 }
943
944 void Actor::SetInitialVolume( const Vector3& volume )
945 {
946   if( NULL != mNode )
947   {
948     // mNode is being used in a separate thread; queue a message to set the value
949     SetInitialVolumeMessage( GetEventThreadServices(), *mNode, volume );
950   }
951 }
952
953 void Actor::SetTransmitGeometryScaling( bool transmitGeometryScaling )
954 {
955   if( NULL != mNode )
956   {
957     // mNode is being used in a separate thread; queue a message to set the value
958     SetTransmitGeometryScalingMessage( GetEventThreadServices(), *mNode, transmitGeometryScaling );
959   }
960 }
961
962 bool Actor::GetTransmitGeometryScaling() const
963 {
964   if( NULL != mNode )
965   {
966     // mNode is being used in a separate thread; copy the value from the previous update
967     return mNode->GetTransmitGeometryScaling();
968   }
969
970   return false;
971 }
972
973 void Actor::ScaleBy( const Vector3& relativeScale )
974 {
975   if( NULL != mNode )
976   {
977     // mNode is being used in a separate thread; queue a message to set the value & base value
978     SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
979   }
980 }
981
982 const Vector3& Actor::GetCurrentScale() const
983 {
984   if( NULL != mNode )
985   {
986     // mNode is being used in a separate thread; copy the value from the previous update
987     return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
988   }
989
990   return Vector3::ONE;
991 }
992
993 const Vector3& Actor::GetCurrentWorldScale() const
994 {
995   if( NULL != mNode )
996   {
997     // mNode is being used in a separate thread; copy the value from the previous update
998     return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
999   }
1000
1001   return Vector3::ONE;
1002 }
1003
1004 void Actor::SetInheritScale( bool inherit )
1005 {
1006   // non animateable so keep local copy
1007   mInheritScale = inherit;
1008   if( NULL != mNode )
1009   {
1010     // mNode is being used in a separate thread; queue a message to set the value
1011     SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
1012   }
1013 }
1014
1015 bool Actor::IsScaleInherited() const
1016 {
1017   return mInheritScale;
1018 }
1019
1020 Matrix Actor::GetCurrentWorldMatrix() const
1021 {
1022   if( NULL != mNode )
1023   {
1024     // World matrix is no longer updated unless there is something observing the node.
1025     // Need to calculate it from node's world position, orientation and scale:
1026     BufferIndex updateBufferIndex = GetEventThreadServices().GetEventBufferIndex();
1027     Matrix worldMatrix(false);
1028     worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
1029                                         mNode->GetWorldOrientation( updateBufferIndex ),
1030                                         mNode->GetWorldPosition( updateBufferIndex ) );
1031     return worldMatrix;
1032   }
1033
1034   return Matrix::IDENTITY;
1035 }
1036
1037 void Actor::SetVisible( bool visible )
1038 {
1039   if( NULL != mNode )
1040   {
1041     // mNode is being used in a separate thread; queue a message to set the value & base value
1042     SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
1043   }
1044 }
1045
1046 bool Actor::IsVisible() const
1047 {
1048   if( NULL != mNode )
1049   {
1050     // mNode is being used in a separate thread; copy the value from the previous update
1051     return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1052   }
1053
1054   return true;
1055 }
1056
1057 void Actor::SetOpacity( float opacity )
1058 {
1059   if( NULL != mNode )
1060   {
1061     // mNode is being used in a separate thread; queue a message to set the value & base value
1062     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1063   }
1064 }
1065
1066 float Actor::GetCurrentOpacity() const
1067 {
1068   if( NULL != mNode )
1069   {
1070     // mNode is being used in a separate thread; copy the value from the previous update
1071     return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1072   }
1073
1074   return 1.0f;
1075 }
1076
1077 const Vector4& Actor::GetCurrentWorldColor() const
1078 {
1079   if( NULL != mNode )
1080   {
1081     return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1082   }
1083
1084   return Color::WHITE;
1085 }
1086
1087 void Actor::SetColor( const Vector4& color )
1088 {
1089   if( NULL != mNode )
1090   {
1091     // mNode is being used in a separate thread; queue a message to set the value & base value
1092     SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1093   }
1094 }
1095
1096 void Actor::SetColorRed( float red )
1097 {
1098   if( NULL != mNode )
1099   {
1100     // mNode is being used in a separate thread; queue a message to set the value & base value
1101     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1102   }
1103 }
1104
1105 void Actor::SetColorGreen( float green )
1106 {
1107   if( NULL != mNode )
1108   {
1109     // mNode is being used in a separate thread; queue a message to set the value & base value
1110     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1111   }
1112 }
1113
1114 void Actor::SetColorBlue( float blue )
1115 {
1116   if( NULL != mNode )
1117   {
1118     // mNode is being used in a separate thread; queue a message to set the value & base value
1119     SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1120   }
1121 }
1122
1123 const Vector4& Actor::GetCurrentColor() const
1124 {
1125   if( NULL != mNode )
1126   {
1127     // mNode is being used in a separate thread; copy the value from the previous update
1128     return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1129   }
1130
1131   return Color::WHITE;
1132 }
1133
1134 void Actor::SetInheritOrientation( bool inherit )
1135 {
1136   // non animateable so keep local copy
1137   mInheritOrientation = inherit;
1138   if( NULL != mNode )
1139   {
1140     // mNode is being used in a separate thread; queue a message to set the value
1141     SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1142   }
1143 }
1144
1145 bool Actor::IsOrientationInherited() const
1146 {
1147   return mInheritOrientation;
1148 }
1149
1150 void Actor::SetSizeModeFactor( const Vector3& factor )
1151 {
1152   EnsureRelayoutData();
1153
1154   mRelayoutData->sizeModeFactor = factor;
1155 }
1156
1157 const Vector3& Actor::GetSizeModeFactor() const
1158 {
1159   EnsureRelayoutData();
1160
1161   return mRelayoutData->sizeModeFactor;
1162 }
1163
1164 void Actor::SetColorMode( ColorMode colorMode )
1165 {
1166   // non animateable so keep local copy
1167   mColorMode = colorMode;
1168   if( NULL != mNode )
1169   {
1170     // mNode is being used in a separate thread; queue a message to set the value
1171     SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1172   }
1173 }
1174
1175 ColorMode Actor::GetColorMode() const
1176 {
1177   // we have cached copy
1178   return mColorMode;
1179 }
1180
1181 void Actor::SetSize( float width, float height )
1182 {
1183   SetSize( Vector2( width, height ) );
1184 }
1185
1186 void Actor::SetSize( float width, float height, float depth )
1187 {
1188   SetSize( Vector3( width, height, depth ) );
1189 }
1190
1191 void Actor::SetSize( const Vector2& size )
1192 {
1193   SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1194 }
1195
1196 void Actor::SetSizeInternal( const Vector2& size )
1197 {
1198   SetSizeInternal( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1199 }
1200
1201 float Actor::CalculateSizeZ( const Vector2& size ) const
1202 {
1203   return std::min( size.width, size.height );
1204 }
1205
1206 void Actor::SetSize( const Vector3& size )
1207 {
1208   if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1209   {
1210     SetPreferredSize( size.GetVectorXY() );
1211   }
1212   else
1213   {
1214     SetSizeInternal( size );
1215   }
1216 }
1217
1218 void Actor::SetSizeInternal( const Vector3& size )
1219 {
1220   if( NULL != mNode )
1221   {
1222     mTargetSize = size;
1223
1224     // mNode is being used in a separate thread; queue a message to set the value & base value
1225     SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mTargetSize );
1226
1227     // Notification for derived classes
1228     OnSizeSet( mTargetSize );
1229
1230     // Raise a relayout request if the flag is not locked
1231     if( mRelayoutData && !mRelayoutData->insideRelayout )
1232     {
1233       RelayoutRequest();
1234     }
1235   }
1236 }
1237
1238 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1239 {
1240   mTargetSize = targetSize;
1241
1242   // Notify deriving classes
1243   OnSizeAnimation( animation, targetSize );
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::FIXED;   // 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::GetMouseWheelEventRequired() const
2124 {
2125   return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
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::EmitMouseWheelEventSignal( const MouseWheelEvent& event )
2188 {
2189   bool consumed = false;
2190
2191   if( !mMouseWheelEventSignal.Empty() )
2192   {
2193     Dali::Actor handle( this );
2194     consumed = mMouseWheelEventSignal.Emit( handle, event );
2195   }
2196
2197   if( !consumed )
2198   {
2199     // Notification for derived classes
2200     consumed = OnMouseWheelEvent( 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::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
2217 {
2218   return mMouseWheelEventSignal;
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 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) ) // don't want to convert char* to string
2242   {
2243     actor->TouchedSignal().Connect( tracker, functor );
2244   }
2245   else if( 0 == strcmp( signalName.c_str(), SIGNAL_HOVERED ) )
2246   {
2247     actor->HoveredSignal().Connect( tracker, functor );
2248   }
2249   else if( 0 == strcmp( signalName.c_str(), SIGNAL_MOUSE_WHEEL_EVENT ) )
2250   {
2251     actor->MouseWheelEventSignal().Connect( tracker, functor );
2252   }
2253   else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) )
2254   {
2255     actor->OnStageSignal().Connect( tracker, functor );
2256   }
2257   else if( 0 == strcmp( signalName.c_str(), 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 ), mAttachment(), mTargetSize( 0.0f, 0.0f, 0.0f ), mName(), mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2281         mIsRoot( ROOT_LAYER == derivedType ), mIsRenderable( RENDERABLE == derivedType ), mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ), mIsOnStage( false ), mIsDynamicsRoot( false ), mSensitive( true ), mLeaveRequired( false ), mKeyboardFocusable( false ), mDerivedRequiresTouch( false ), mDerivedRequiresHover( false ), mDerivedRequiresMouseWheelEvent( false ), mOnStageSignalled( false ), mInheritOrientation( true ), mInheritScale( true ), mDrawMode( DrawMode::NORMAL ), mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ), mColorMode( Node::DEFAULT_COLOR_MODE )
2282 {
2283 }
2284
2285 void Actor::Initialize()
2286 {
2287   // Node creation
2288   SceneGraph::Node* node = CreateNode();
2289
2290   AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2291   mNode = node; // Keep raw-pointer to Node
2292
2293   OnInitialize();
2294
2295   GetEventThreadServices().RegisterObject( this );
2296 }
2297
2298 Actor::~Actor()
2299 {
2300   // Remove mParent pointers from children even if we're destroying core,
2301   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2302   if( mChildren )
2303   {
2304     ActorConstIter endIter = mChildren->end();
2305     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2306     {
2307       Actor& actor = GetImplementation( *iter );
2308       actor.SetParent( NULL );
2309     }
2310   }
2311   delete mChildren;
2312
2313   // Guard to allow handle destruction after Core has been destroyed
2314   if( EventThreadServices::IsCoreRunning() )
2315   {
2316     if( NULL != mNode )
2317     {
2318       DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2319       mNode = NULL; // Node is about to be destroyed
2320     }
2321
2322     GetEventThreadServices().UnregisterObject( this );
2323   }
2324
2325 #ifdef DYNAMICS_SUPPORT
2326   // Cleanup dynamics
2327   delete mDynamicsData;
2328 #endif
2329
2330   // Cleanup optional gesture data
2331   delete mGestureData;
2332
2333   // Cleanup optional parent origin and anchor
2334   delete mParentOrigin;
2335   delete mAnchorPoint;
2336
2337   // Delete optional relayout data
2338   if( mRelayoutData )
2339   {
2340     delete mRelayoutData;
2341   }
2342 }
2343
2344 void Actor::ConnectToStage( int index )
2345 {
2346   // This container is used instead of walking the Actor hierachy.
2347   // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2348   ActorContainer connectionList;
2349
2350   // This stage is atomic i.e. not interrupted by user callbacks
2351   RecursiveConnectToStage( connectionList, index );
2352
2353   // Notify applications about the newly connected actors.
2354   const ActorIter endIter = connectionList.end();
2355   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2356   {
2357     Actor& actor = GetImplementation( *iter );
2358     actor.NotifyStageConnection();
2359   }
2360
2361   RelayoutRequest();
2362 }
2363
2364 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2365 {
2366   DALI_ASSERT_ALWAYS( !OnStage() );
2367
2368   mIsOnStage = true;
2369
2370   ConnectToSceneGraph( index );
2371
2372   // Notification for internal derived classes
2373   OnStageConnectionInternal();
2374
2375   // This stage is atomic; avoid emitting callbacks until all Actors are connected
2376   connectionList.push_back( Dali::Actor( this ) );
2377
2378   // Recursively connect children
2379   if( mChildren )
2380   {
2381     ActorConstIter endIter = mChildren->end();
2382     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2383     {
2384       Actor& actor = GetImplementation( *iter );
2385       actor.RecursiveConnectToStage( connectionList );
2386     }
2387   }
2388 }
2389
2390 /**
2391  * This method is called when the Actor is connected to the Stage.
2392  * The parent must have added its Node to the scene-graph.
2393  * The child must connect its Node to the parent's Node.
2394  * This is resursive; the child calls ConnectToStage() for its children.
2395  */
2396 void Actor::ConnectToSceneGraph( int index )
2397 {
2398   DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2399
2400   if( NULL != mNode )
2401   {
2402     // Reparent Node in next Update
2403     ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode, index );
2404   }
2405
2406   // Notify attachment
2407   if( mAttachment )
2408   {
2409     mAttachment->Connect();
2410   }
2411
2412 #ifdef DYNAMICS_SUPPORT
2413   // Notify dynamics
2414   if( NULL != mDynamicsData )
2415   {
2416     ConnectDynamics();
2417   }
2418 #endif
2419
2420   // Request relayout on all actors that are added to the scenegraph
2421   RelayoutRequest();
2422
2423   // Notification for Object::Observers
2424   OnSceneObjectAdd();
2425 }
2426
2427 void Actor::NotifyStageConnection()
2428 {
2429   // Actors can be removed (in a callback), before the on-stage stage is reported.
2430   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2431   if( OnStage() && !mOnStageSignalled )
2432   {
2433     // Notification for external (CustomActor) derived classes
2434     OnStageConnectionExternal();
2435
2436     if( !mOnStageSignal.Empty() )
2437     {
2438       Dali::Actor handle( this );
2439       mOnStageSignal.Emit( handle );
2440     }
2441
2442     // Guard against Remove during callbacks
2443     if( OnStage() )
2444     {
2445       mOnStageSignalled = true; // signal required next time Actor is removed
2446     }
2447   }
2448 }
2449
2450 void Actor::DisconnectFromStage()
2451 {
2452   // This container is used instead of walking the Actor hierachy.
2453   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2454   ActorContainer disconnectionList;
2455
2456   // This stage is atomic i.e. not interrupted by user callbacks
2457   RecursiveDisconnectFromStage( disconnectionList );
2458
2459   // Notify applications about the newly disconnected actors.
2460   const ActorIter endIter = disconnectionList.end();
2461   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2462   {
2463     Actor& actor = GetImplementation( *iter );
2464     actor.NotifyStageDisconnection();
2465   }
2466 }
2467
2468 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2469 {
2470   DALI_ASSERT_ALWAYS( OnStage() );
2471
2472   // Recursively disconnect children
2473   if( mChildren )
2474   {
2475     ActorConstIter endIter = mChildren->end();
2476     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2477     {
2478       Actor& actor = GetImplementation( *iter );
2479       actor.RecursiveDisconnectFromStage( disconnectionList );
2480     }
2481   }
2482
2483   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2484   disconnectionList.push_back( Dali::Actor( this ) );
2485
2486   // Notification for internal derived classes
2487   OnStageDisconnectionInternal();
2488
2489   DisconnectFromSceneGraph();
2490
2491   mIsOnStage = false;
2492 }
2493
2494 /**
2495  * This method is called by an actor or its parent, before a node removal message is sent.
2496  * This is recursive; the child calls DisconnectFromStage() for its children.
2497  */
2498 void Actor::DisconnectFromSceneGraph()
2499 {
2500   // Notification for Object::Observers
2501   OnSceneObjectRemove();
2502
2503   // Notify attachment
2504   if( mAttachment )
2505   {
2506     mAttachment->Disconnect();
2507   }
2508
2509 #ifdef DYNAMICS_SUPPORT
2510   // Notify dynamics
2511   if( NULL != mDynamicsData )
2512   {
2513     DisconnectDynamics();
2514   }
2515 #endif
2516 }
2517
2518 void Actor::NotifyStageDisconnection()
2519 {
2520   // Actors can be added (in a callback), before the off-stage state is reported.
2521   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2522   // only do this step if there is a stage, i.e. Core is not being shut down
2523   if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2524   {
2525     // Notification for external (CustomeActor) derived classes
2526     OnStageDisconnectionExternal();
2527
2528     if( !mOffStageSignal.Empty() )
2529     {
2530       Dali::Actor handle( this );
2531       mOffStageSignal.Emit( handle );
2532     }
2533
2534     // Guard against Add during callbacks
2535     if( !OnStage() )
2536     {
2537       mOnStageSignalled = false; // signal required next time Actor is added
2538     }
2539   }
2540 }
2541
2542 bool Actor::IsNodeConnected() const
2543 {
2544   bool connected( false );
2545
2546   if( OnStage() &&
2547   NULL != mNode )
2548   {
2549     if( mNode->IsRoot() || mNode->GetParent() )
2550     {
2551       connected = true;
2552     }
2553   }
2554
2555   return connected;
2556 }
2557
2558 unsigned int Actor::GetDefaultPropertyCount() const
2559 {
2560   return DEFAULT_PROPERTY_COUNT;
2561 }
2562
2563 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2564 {
2565   indices.reserve( DEFAULT_PROPERTY_COUNT );
2566
2567   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2568   {
2569     indices.push_back( i );
2570   }
2571 }
2572
2573 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2574 {
2575   if( index < DEFAULT_PROPERTY_COUNT )
2576   {
2577     return DEFAULT_PROPERTY_DETAILS[ index ].name;
2578   }
2579
2580   return NULL;
2581 }
2582
2583 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2584 {
2585   Property::Index index = Property::INVALID_INDEX;
2586
2587   // Look for name in default properties
2588   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2589   {
2590     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2591     if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2592     {
2593       index = i;
2594       break;
2595     }
2596   }
2597
2598   return index;
2599 }
2600
2601 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2602 {
2603   if( index < DEFAULT_PROPERTY_COUNT )
2604   {
2605     return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2606   }
2607
2608   return false;
2609 }
2610
2611 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2612 {
2613   if( index < DEFAULT_PROPERTY_COUNT )
2614   {
2615     return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2616   }
2617
2618   return false;
2619 }
2620
2621 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2622 {
2623   if( index < DEFAULT_PROPERTY_COUNT )
2624   {
2625     return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2626   }
2627
2628   return false;
2629 }
2630
2631 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2632 {
2633   if( index < DEFAULT_PROPERTY_COUNT )
2634   {
2635     return DEFAULT_PROPERTY_DETAILS[ index ].type;
2636   }
2637
2638   // index out of range...return Property::NONE
2639   return Property::NONE;
2640 }
2641
2642 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2643 {
2644   switch( index )
2645   {
2646     case Dali::Actor::Property::PARENT_ORIGIN:
2647     {
2648       SetParentOrigin( property.Get< Vector3 >() );
2649       break;
2650     }
2651
2652     case Dali::Actor::Property::PARENT_ORIGIN_X:
2653     {
2654       SetParentOriginX( property.Get< float >() );
2655       break;
2656     }
2657
2658     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2659     {
2660       SetParentOriginY( property.Get< float >() );
2661       break;
2662     }
2663
2664     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2665     {
2666       SetParentOriginZ( property.Get< float >() );
2667       break;
2668     }
2669
2670     case Dali::Actor::Property::ANCHOR_POINT:
2671     {
2672       SetAnchorPoint( property.Get< Vector3 >() );
2673       break;
2674     }
2675
2676     case Dali::Actor::Property::ANCHOR_POINT_X:
2677     {
2678       SetAnchorPointX( property.Get< float >() );
2679       break;
2680     }
2681
2682     case Dali::Actor::Property::ANCHOR_POINT_Y:
2683     {
2684       SetAnchorPointY( property.Get< float >() );
2685       break;
2686     }
2687
2688     case Dali::Actor::Property::ANCHOR_POINT_Z:
2689     {
2690       SetAnchorPointZ( property.Get< float >() );
2691       break;
2692     }
2693
2694     case Dali::Actor::Property::SIZE:
2695     {
2696       SetSize( property.Get< Vector3 >() );
2697       break;
2698     }
2699
2700     case Dali::Actor::Property::SIZE_WIDTH:
2701     {
2702       SetWidth( property.Get< float >() );
2703       break;
2704     }
2705
2706     case Dali::Actor::Property::SIZE_HEIGHT:
2707     {
2708       SetHeight( property.Get< float >() );
2709       break;
2710     }
2711
2712     case Dali::Actor::Property::SIZE_DEPTH:
2713     {
2714       SetDepth( property.Get< float >() );
2715       break;
2716     }
2717
2718     case Dali::Actor::Property::POSITION:
2719     {
2720       SetPosition( property.Get< Vector3 >() );
2721       break;
2722     }
2723
2724     case Dali::Actor::Property::POSITION_X:
2725     {
2726       SetX( property.Get< float >() );
2727       break;
2728     }
2729
2730     case Dali::Actor::Property::POSITION_Y:
2731     {
2732       SetY( property.Get< float >() );
2733       break;
2734     }
2735
2736     case Dali::Actor::Property::POSITION_Z:
2737     {
2738       SetZ( property.Get< float >() );
2739       break;
2740     }
2741
2742     case Dali::Actor::Property::ORIENTATION:
2743     {
2744       SetOrientation( property.Get< Quaternion >() );
2745       break;
2746     }
2747
2748     case Dali::Actor::Property::SCALE:
2749     {
2750       SetScale( property.Get< Vector3 >() );
2751       break;
2752     }
2753
2754     case Dali::Actor::Property::SCALE_X:
2755     {
2756       SetScaleX( property.Get< float >() );
2757       break;
2758     }
2759
2760     case Dali::Actor::Property::SCALE_Y:
2761     {
2762       SetScaleY( property.Get< float >() );
2763       break;
2764     }
2765
2766     case Dali::Actor::Property::SCALE_Z:
2767     {
2768       SetScaleZ( property.Get< float >() );
2769       break;
2770     }
2771
2772     case Dali::Actor::Property::VISIBLE:
2773     {
2774       SetVisible( property.Get< bool >() );
2775       break;
2776     }
2777
2778     case Dali::Actor::Property::COLOR:
2779     {
2780       SetColor( property.Get< Vector4 >() );
2781       break;
2782     }
2783
2784     case Dali::Actor::Property::COLOR_RED:
2785     {
2786       SetColorRed( property.Get< float >() );
2787       break;
2788     }
2789
2790     case Dali::Actor::Property::COLOR_GREEN:
2791     {
2792       SetColorGreen( property.Get< float >() );
2793       break;
2794     }
2795
2796     case Dali::Actor::Property::COLOR_BLUE:
2797     {
2798       SetColorBlue( property.Get< float >() );
2799       break;
2800     }
2801
2802     case Dali::Actor::Property::COLOR_ALPHA:
2803     {
2804       SetOpacity( property.Get< float >() );
2805       break;
2806     }
2807
2808     case Dali::Actor::Property::NAME:
2809     {
2810       SetName( property.Get< std::string >() );
2811       break;
2812     }
2813
2814     case Dali::Actor::Property::SENSITIVE:
2815     {
2816       SetSensitive( property.Get< bool >() );
2817       break;
2818     }
2819
2820     case Dali::Actor::Property::LEAVE_REQUIRED:
2821     {
2822       SetLeaveRequired( property.Get< bool >() );
2823       break;
2824     }
2825
2826     case Dali::Actor::Property::INHERIT_ORIENTATION:
2827     {
2828       SetInheritOrientation( property.Get< bool >() );
2829       break;
2830     }
2831
2832     case Dali::Actor::Property::INHERIT_SCALE:
2833     {
2834       SetInheritScale( property.Get< bool >() );
2835       break;
2836     }
2837
2838     case Dali::Actor::Property::COLOR_MODE:
2839     {
2840       SetColorMode( Scripting::GetColorMode( property.Get< std::string >() ) );
2841       break;
2842     }
2843
2844     case Dali::Actor::Property::POSITION_INHERITANCE:
2845     {
2846       SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get< std::string >() ) );
2847       break;
2848     }
2849
2850     case Dali::Actor::Property::DRAW_MODE:
2851     {
2852       SetDrawMode( Scripting::GetDrawMode( property.Get< std::string >() ) );
2853       break;
2854     }
2855
2856     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2857     {
2858       SetSizeModeFactor( property.Get< Vector3 >() );
2859       break;
2860     }
2861
2862     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2863     {
2864       SetResizePolicy( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount ), Dimension::WIDTH );
2865       break;
2866     }
2867
2868     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2869     {
2870       SetResizePolicy( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount ), Dimension::HEIGHT );
2871       break;
2872     }
2873
2874     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2875     {
2876       SetSizeScalePolicy( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount ) );
2877       break;
2878     }
2879
2880     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2881     {
2882       if( property.Get< bool >() )
2883       {
2884         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2885       }
2886       break;
2887     }
2888
2889     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2890     {
2891       if( property.Get< bool >() )
2892       {
2893         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2894       }
2895       break;
2896     }
2897
2898     case Dali::Actor::Property::PADDING:
2899     {
2900       Vector4 padding = property.Get< Vector4 >();
2901       SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2902       SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2903       break;
2904     }
2905
2906     case Dali::Actor::Property::MINIMUM_SIZE:
2907     {
2908       Vector2 size = property.Get< Vector2 >();
2909       SetMinimumSize( size.x, Dimension::WIDTH );
2910       SetMinimumSize( size.y, Dimension::HEIGHT );
2911       break;
2912     }
2913
2914     case Dali::Actor::Property::MAXIMUM_SIZE:
2915     {
2916       Vector2 size = property.Get< Vector2 >();
2917       SetMaximumSize( size.x, Dimension::WIDTH );
2918       SetMaximumSize( size.y, Dimension::HEIGHT );
2919       break;
2920     }
2921
2922     default:
2923     {
2924       // this can happen in the case of a non-animatable default property so just do nothing
2925       break;
2926     }
2927   }
2928 }
2929
2930 // TODO: This method needs to be removed
2931 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2932 {
2933   OnPropertySet( index, value );
2934
2935   switch( entry.type )
2936   {
2937     case Property::BOOLEAN:
2938     {
2939       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2940       DALI_ASSERT_DEBUG( NULL != property );
2941
2942       // property is being used in a separate thread; queue a message to set the property
2943       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2944
2945       break;
2946     }
2947
2948     case Property::FLOAT:
2949     {
2950       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2951       DALI_ASSERT_DEBUG( NULL != property );
2952
2953       // property is being used in a separate thread; queue a message to set the property
2954       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2955
2956       break;
2957     }
2958
2959     case Property::INTEGER:
2960     {
2961       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2962       DALI_ASSERT_DEBUG( NULL != property );
2963
2964       // property is being used in a separate thread; queue a message to set the property
2965       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2966
2967       break;
2968     }
2969
2970     case Property::VECTOR2:
2971     {
2972       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2973       DALI_ASSERT_DEBUG( NULL != property );
2974
2975       // property is being used in a separate thread; queue a message to set the property
2976       SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2977
2978       break;
2979     }
2980
2981     case Property::VECTOR3:
2982     {
2983       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2984       DALI_ASSERT_DEBUG( NULL != property );
2985
2986       // property is being used in a separate thread; queue a message to set the property
2987       SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2988
2989       break;
2990     }
2991
2992     case Property::VECTOR4:
2993     {
2994       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2995       DALI_ASSERT_DEBUG( NULL != property );
2996
2997       // property is being used in a separate thread; queue a message to set the property
2998       SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2999
3000       break;
3001     }
3002
3003     case Property::ROTATION:
3004     {
3005       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3006       DALI_ASSERT_DEBUG( NULL != property );
3007
3008       // property is being used in a separate thread; queue a message to set the property
3009       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
3010
3011       break;
3012     }
3013
3014     case Property::MATRIX:
3015     {
3016       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3017       DALI_ASSERT_DEBUG( NULL != property );
3018
3019       // property is being used in a separate thread; queue a message to set the property
3020       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
3021
3022       break;
3023     }
3024
3025     case Property::MATRIX3:
3026     {
3027       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3028       DALI_ASSERT_DEBUG( NULL != property );
3029
3030       // property is being used in a separate thread; queue a message to set the property
3031       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
3032
3033       break;
3034     }
3035
3036     default:
3037     {
3038       DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
3039       break;
3040     }
3041   }
3042 }
3043
3044 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3045 {
3046   Property::Value value;
3047
3048   switch( index )
3049   {
3050     case Dali::Actor::Property::PARENT_ORIGIN:
3051     {
3052       value = GetCurrentParentOrigin();
3053       break;
3054     }
3055
3056     case Dali::Actor::Property::PARENT_ORIGIN_X:
3057     {
3058       value = GetCurrentParentOrigin().x;
3059       break;
3060     }
3061
3062     case Dali::Actor::Property::PARENT_ORIGIN_Y:
3063     {
3064       value = GetCurrentParentOrigin().y;
3065       break;
3066     }
3067
3068     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3069     {
3070       value = GetCurrentParentOrigin().z;
3071       break;
3072     }
3073
3074     case Dali::Actor::Property::ANCHOR_POINT:
3075     {
3076       value = GetCurrentAnchorPoint();
3077       break;
3078     }
3079
3080     case Dali::Actor::Property::ANCHOR_POINT_X:
3081     {
3082       value = GetCurrentAnchorPoint().x;
3083       break;
3084     }
3085
3086     case Dali::Actor::Property::ANCHOR_POINT_Y:
3087     {
3088       value = GetCurrentAnchorPoint().y;
3089       break;
3090     }
3091
3092     case Dali::Actor::Property::ANCHOR_POINT_Z:
3093     {
3094       value = GetCurrentAnchorPoint().z;
3095       break;
3096     }
3097
3098     case Dali::Actor::Property::SIZE:
3099     {
3100       value = GetCurrentSize();
3101       break;
3102     }
3103
3104     case Dali::Actor::Property::SIZE_WIDTH:
3105     {
3106       value = GetCurrentSize().width;
3107       break;
3108     }
3109
3110     case Dali::Actor::Property::SIZE_HEIGHT:
3111     {
3112       value = GetCurrentSize().height;
3113       break;
3114     }
3115
3116     case Dali::Actor::Property::SIZE_DEPTH:
3117     {
3118       value = GetCurrentSize().depth;
3119       break;
3120     }
3121
3122     case Dali::Actor::Property::POSITION:
3123     {
3124       value = GetCurrentPosition();
3125       break;
3126     }
3127
3128     case Dali::Actor::Property::POSITION_X:
3129     {
3130       value = GetCurrentPosition().x;
3131       break;
3132     }
3133
3134     case Dali::Actor::Property::POSITION_Y:
3135     {
3136       value = GetCurrentPosition().y;
3137       break;
3138     }
3139
3140     case Dali::Actor::Property::POSITION_Z:
3141     {
3142       value = GetCurrentPosition().z;
3143       break;
3144     }
3145
3146     case Dali::Actor::Property::WORLD_POSITION:
3147     {
3148       value = GetCurrentWorldPosition();
3149       break;
3150     }
3151
3152     case Dali::Actor::Property::WORLD_POSITION_X:
3153     {
3154       value = GetCurrentWorldPosition().x;
3155       break;
3156     }
3157
3158     case Dali::Actor::Property::WORLD_POSITION_Y:
3159     {
3160       value = GetCurrentWorldPosition().y;
3161       break;
3162     }
3163
3164     case Dali::Actor::Property::WORLD_POSITION_Z:
3165     {
3166       value = GetCurrentWorldPosition().z;
3167       break;
3168     }
3169
3170     case Dali::Actor::Property::ORIENTATION:
3171     {
3172       value = GetCurrentOrientation();
3173       break;
3174     }
3175
3176     case Dali::Actor::Property::WORLD_ORIENTATION:
3177     {
3178       value = GetCurrentWorldOrientation();
3179       break;
3180     }
3181
3182     case Dali::Actor::Property::SCALE:
3183     {
3184       value = GetCurrentScale();
3185       break;
3186     }
3187
3188     case Dali::Actor::Property::SCALE_X:
3189     {
3190       value = GetCurrentScale().x;
3191       break;
3192     }
3193
3194     case Dali::Actor::Property::SCALE_Y:
3195     {
3196       value = GetCurrentScale().y;
3197       break;
3198     }
3199
3200     case Dali::Actor::Property::SCALE_Z:
3201     {
3202       value = GetCurrentScale().z;
3203       break;
3204     }
3205
3206     case Dali::Actor::Property::WORLD_SCALE:
3207     {
3208       value = GetCurrentWorldScale();
3209       break;
3210     }
3211
3212     case Dali::Actor::Property::VISIBLE:
3213     {
3214       value = IsVisible();
3215       break;
3216     }
3217
3218     case Dali::Actor::Property::COLOR:
3219     {
3220       value = GetCurrentColor();
3221       break;
3222     }
3223
3224     case Dali::Actor::Property::COLOR_RED:
3225     {
3226       value = GetCurrentColor().r;
3227       break;
3228     }
3229
3230     case Dali::Actor::Property::COLOR_GREEN:
3231     {
3232       value = GetCurrentColor().g;
3233       break;
3234     }
3235
3236     case Dali::Actor::Property::COLOR_BLUE:
3237     {
3238       value = GetCurrentColor().b;
3239       break;
3240     }
3241
3242     case Dali::Actor::Property::COLOR_ALPHA:
3243     {
3244       value = GetCurrentColor().a;
3245       break;
3246     }
3247
3248     case Dali::Actor::Property::WORLD_COLOR:
3249     {
3250       value = GetCurrentWorldColor();
3251       break;
3252     }
3253
3254     case Dali::Actor::Property::WORLD_MATRIX:
3255     {
3256       value = GetCurrentWorldMatrix();
3257       break;
3258     }
3259
3260     case Dali::Actor::Property::NAME:
3261     {
3262       value = GetName();
3263       break;
3264     }
3265
3266     case Dali::Actor::Property::SENSITIVE:
3267     {
3268       value = IsSensitive();
3269       break;
3270     }
3271
3272     case Dali::Actor::Property::LEAVE_REQUIRED:
3273     {
3274       value = GetLeaveRequired();
3275       break;
3276     }
3277
3278     case Dali::Actor::Property::INHERIT_ORIENTATION:
3279     {
3280       value = IsOrientationInherited();
3281       break;
3282     }
3283
3284     case Dali::Actor::Property::INHERIT_SCALE:
3285     {
3286       value = IsScaleInherited();
3287       break;
3288     }
3289
3290     case Dali::Actor::Property::COLOR_MODE:
3291     {
3292       value = Scripting::GetColorMode( GetColorMode() );
3293       break;
3294     }
3295
3296     case Dali::Actor::Property::POSITION_INHERITANCE:
3297     {
3298       value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3299       break;
3300     }
3301
3302     case Dali::Actor::Property::DRAW_MODE:
3303     {
3304       value = Scripting::GetDrawMode( GetDrawMode() );
3305       break;
3306     }
3307
3308     case Dali::Actor::Property::SIZE_MODE_FACTOR:
3309     {
3310       value = GetSizeModeFactor();
3311       break;
3312     }
3313
3314     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3315     {
3316       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount );
3317       break;
3318     }
3319
3320     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3321     {
3322       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount );
3323       break;
3324     }
3325
3326     case Dali::Actor::Property::SIZE_SCALE_POLICY:
3327     {
3328       value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount );
3329       break;
3330     }
3331
3332     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3333     {
3334       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3335       break;
3336     }
3337
3338     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3339     {
3340       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3341       break;
3342     }
3343
3344     case Dali::Actor::Property::PADDING:
3345     {
3346       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3347       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3348       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3349       break;
3350     }
3351
3352     case Dali::Actor::Property::MINIMUM_SIZE:
3353     {
3354       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3355       break;
3356     }
3357
3358     case Dali::Actor::Property::MAXIMUM_SIZE:
3359     {
3360       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3361       break;
3362     }
3363
3364     default:
3365     {
3366       DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3367       break;
3368     }
3369   }
3370
3371   return value;
3372 }
3373
3374 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3375 {
3376   return mNode;
3377 }
3378
3379 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3380 {
3381   // This method should only return an object connected to the scene-graph
3382   return OnStage() ? mNode : NULL;
3383 }
3384
3385 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3386 {
3387   DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3388
3389   const PropertyBase* property( NULL );
3390
3391   // This method should only return a property of an object connected to the scene-graph
3392   if( !OnStage() )
3393   {
3394     return property;
3395   }
3396
3397   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3398   {
3399     AnimatablePropertyMetadata* animatable = FindAnimatableProperty( index );
3400     if( !animatable )
3401     {
3402       const TypeInfo* typeInfo( GetTypeInfo() );
3403       if ( typeInfo )
3404       {
3405         if( Property::INVALID_INDEX != RegisterSceneGraphProperty( typeInfo->GetPropertyName( index ), index, Property::Value( typeInfo->GetPropertyType( index ) ) ) )
3406         {
3407           animatable = FindAnimatableProperty( index );
3408         }
3409       }
3410     }
3411     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3412
3413     property = animatable->GetSceneGraphProperty();
3414   }
3415   else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3416   {
3417     CustomPropertyMetadata* custom = FindCustomProperty( index );
3418     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3419
3420     property = custom->GetSceneGraphProperty();
3421   }
3422   else if( NULL != mNode )
3423   {
3424     switch( index )
3425     {
3426       case Dali::Actor::Property::SIZE:
3427         property = &mNode->mSize;
3428         break;
3429
3430       case Dali::Actor::Property::SIZE_WIDTH:
3431         property = &mNode->mSize;
3432         break;
3433
3434       case Dali::Actor::Property::SIZE_HEIGHT:
3435         property = &mNode->mSize;
3436         break;
3437
3438       case Dali::Actor::Property::SIZE_DEPTH:
3439         property = &mNode->mSize;
3440         break;
3441
3442       case Dali::Actor::Property::POSITION:
3443         property = &mNode->mPosition;
3444         break;
3445
3446       case Dali::Actor::Property::POSITION_X:
3447         property = &mNode->mPosition;
3448         break;
3449
3450       case Dali::Actor::Property::POSITION_Y:
3451         property = &mNode->mPosition;
3452         break;
3453
3454       case Dali::Actor::Property::POSITION_Z:
3455         property = &mNode->mPosition;
3456         break;
3457
3458       case Dali::Actor::Property::ORIENTATION:
3459         property = &mNode->mOrientation;
3460         break;
3461
3462       case Dali::Actor::Property::SCALE:
3463         property = &mNode->mScale;
3464         break;
3465
3466       case Dali::Actor::Property::SCALE_X:
3467         property = &mNode->mScale;
3468         break;
3469
3470       case Dali::Actor::Property::SCALE_Y:
3471         property = &mNode->mScale;
3472         break;
3473
3474       case Dali::Actor::Property::SCALE_Z:
3475         property = &mNode->mScale;
3476         break;
3477
3478       case Dali::Actor::Property::VISIBLE:
3479         property = &mNode->mVisible;
3480         break;
3481
3482       case Dali::Actor::Property::COLOR:
3483         property = &mNode->mColor;
3484         break;
3485
3486       case Dali::Actor::Property::COLOR_RED:
3487         property = &mNode->mColor;
3488         break;
3489
3490       case Dali::Actor::Property::COLOR_GREEN:
3491         property = &mNode->mColor;
3492         break;
3493
3494       case Dali::Actor::Property::COLOR_BLUE:
3495         property = &mNode->mColor;
3496         break;
3497
3498       case Dali::Actor::Property::COLOR_ALPHA:
3499         property = &mNode->mColor;
3500         break;
3501
3502       default:
3503         break;
3504     }
3505   }
3506
3507   return property;
3508 }
3509
3510 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3511 {
3512   const PropertyInputImpl* property( NULL );
3513
3514   // This method should only return a property of an object connected to the scene-graph
3515   if( !OnStage() )
3516   {
3517     return property;
3518   }
3519
3520   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3521   {
3522     AnimatablePropertyMetadata* animatable = FindAnimatableProperty( index );
3523     if( !animatable )
3524     {
3525       const TypeInfo* typeInfo( GetTypeInfo() );
3526       if ( typeInfo )
3527       {
3528         if( Property::INVALID_INDEX != RegisterSceneGraphProperty( typeInfo->GetPropertyName( index ), index, Property::Value( typeInfo->GetPropertyType( index ) ) ) )
3529         {
3530           animatable = FindAnimatableProperty( index );
3531         }
3532       }
3533     }
3534     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3535
3536     property = animatable->GetSceneGraphProperty();
3537   }
3538   else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3539   {
3540     CustomPropertyMetadata* custom = FindCustomProperty( index );
3541     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3542     property = custom->GetSceneGraphProperty();
3543   }
3544   else if( NULL != mNode )
3545   {
3546     switch( index )
3547     {
3548       case Dali::Actor::Property::PARENT_ORIGIN:
3549         property = &mNode->mParentOrigin;
3550         break;
3551
3552       case Dali::Actor::Property::PARENT_ORIGIN_X:
3553         property = &mNode->mParentOrigin;
3554         break;
3555
3556       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3557         property = &mNode->mParentOrigin;
3558         break;
3559
3560       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3561         property = &mNode->mParentOrigin;
3562         break;
3563
3564       case Dali::Actor::Property::ANCHOR_POINT:
3565         property = &mNode->mAnchorPoint;
3566         break;
3567
3568       case Dali::Actor::Property::ANCHOR_POINT_X:
3569         property = &mNode->mAnchorPoint;
3570         break;
3571
3572       case Dali::Actor::Property::ANCHOR_POINT_Y:
3573         property = &mNode->mAnchorPoint;
3574         break;
3575
3576       case Dali::Actor::Property::ANCHOR_POINT_Z:
3577         property = &mNode->mAnchorPoint;
3578         break;
3579
3580       case Dali::Actor::Property::SIZE:
3581         property = &mNode->mSize;
3582         break;
3583
3584       case Dali::Actor::Property::SIZE_WIDTH:
3585         property = &mNode->mSize;
3586         break;
3587
3588       case Dali::Actor::Property::SIZE_HEIGHT:
3589         property = &mNode->mSize;
3590         break;
3591
3592       case Dali::Actor::Property::SIZE_DEPTH:
3593         property = &mNode->mSize;
3594         break;
3595
3596       case Dali::Actor::Property::POSITION:
3597         property = &mNode->mPosition;
3598         break;
3599
3600       case Dali::Actor::Property::POSITION_X:
3601         property = &mNode->mPosition;
3602         break;
3603
3604       case Dali::Actor::Property::POSITION_Y:
3605         property = &mNode->mPosition;
3606         break;
3607
3608       case Dali::Actor::Property::POSITION_Z:
3609         property = &mNode->mPosition;
3610         break;
3611
3612       case Dali::Actor::Property::WORLD_POSITION:
3613         property = &mNode->mWorldPosition;
3614         break;
3615
3616       case Dali::Actor::Property::WORLD_POSITION_X:
3617         property = &mNode->mWorldPosition;
3618         break;
3619
3620       case Dali::Actor::Property::WORLD_POSITION_Y:
3621         property = &mNode->mWorldPosition;
3622         break;
3623
3624       case Dali::Actor::Property::WORLD_POSITION_Z:
3625         property = &mNode->mWorldPosition;
3626         break;
3627
3628       case Dali::Actor::Property::ORIENTATION:
3629         property = &mNode->mOrientation;
3630         break;
3631
3632       case Dali::Actor::Property::WORLD_ORIENTATION:
3633         property = &mNode->mWorldOrientation;
3634         break;
3635
3636       case Dali::Actor::Property::SCALE:
3637         property = &mNode->mScale;
3638         break;
3639
3640       case Dali::Actor::Property::SCALE_X:
3641         property = &mNode->mScale;
3642         break;
3643
3644       case Dali::Actor::Property::SCALE_Y:
3645         property = &mNode->mScale;
3646         break;
3647
3648       case Dali::Actor::Property::SCALE_Z:
3649         property = &mNode->mScale;
3650         break;
3651
3652       case Dali::Actor::Property::WORLD_SCALE:
3653         property = &mNode->mWorldScale;
3654         break;
3655
3656       case Dali::Actor::Property::VISIBLE:
3657         property = &mNode->mVisible;
3658         break;
3659
3660       case Dali::Actor::Property::COLOR:
3661         property = &mNode->mColor;
3662         break;
3663
3664       case Dali::Actor::Property::COLOR_RED:
3665         property = &mNode->mColor;
3666         break;
3667
3668       case Dali::Actor::Property::COLOR_GREEN:
3669         property = &mNode->mColor;
3670         break;
3671
3672       case Dali::Actor::Property::COLOR_BLUE:
3673         property = &mNode->mColor;
3674         break;
3675
3676       case Dali::Actor::Property::COLOR_ALPHA:
3677         property = &mNode->mColor;
3678         break;
3679
3680       case Dali::Actor::Property::WORLD_COLOR:
3681         property = &mNode->mWorldColor;
3682         break;
3683
3684       case Dali::Actor::Property::WORLD_MATRIX:
3685         property = &mNode->mWorldMatrix;
3686         break;
3687
3688       default:
3689         break;
3690     }
3691   }
3692
3693   return property;
3694 }
3695
3696 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3697 {
3698   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3699
3700   switch( index )
3701   {
3702     case Dali::Actor::Property::PARENT_ORIGIN_X:
3703     case Dali::Actor::Property::ANCHOR_POINT_X:
3704     case Dali::Actor::Property::SIZE_WIDTH:
3705     case Dali::Actor::Property::POSITION_X:
3706     case Dali::Actor::Property::WORLD_POSITION_X:
3707     case Dali::Actor::Property::SCALE_X:
3708     case Dali::Actor::Property::COLOR_RED:
3709     {
3710       componentIndex = 0;
3711       break;
3712     }
3713
3714     case Dali::Actor::Property::PARENT_ORIGIN_Y:
3715     case Dali::Actor::Property::ANCHOR_POINT_Y:
3716     case Dali::Actor::Property::SIZE_HEIGHT:
3717     case Dali::Actor::Property::POSITION_Y:
3718     case Dali::Actor::Property::WORLD_POSITION_Y:
3719     case Dali::Actor::Property::SCALE_Y:
3720     case Dali::Actor::Property::COLOR_GREEN:
3721     {
3722       componentIndex = 1;
3723       break;
3724     }
3725
3726     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3727     case Dali::Actor::Property::ANCHOR_POINT_Z:
3728     case Dali::Actor::Property::SIZE_DEPTH:
3729     case Dali::Actor::Property::POSITION_Z:
3730     case Dali::Actor::Property::WORLD_POSITION_Z:
3731     case Dali::Actor::Property::SCALE_Z:
3732     case Dali::Actor::Property::COLOR_BLUE:
3733     {
3734       componentIndex = 2;
3735       break;
3736     }
3737
3738     case Dali::Actor::Property::COLOR_ALPHA:
3739     {
3740       componentIndex = 3;
3741       break;
3742     }
3743
3744     default:
3745     {
3746       // Do nothing
3747       break;
3748     }
3749   }
3750
3751   return componentIndex;
3752 }
3753
3754 void Actor::SetParent( Actor* parent, int index )
3755 {
3756   if( parent )
3757   {
3758     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3759
3760     mParent = parent;
3761
3762     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3763          parent->OnStage() )
3764     {
3765       // Instruct each actor to create a corresponding node in the scene graph
3766       ConnectToStage( index );
3767     }
3768   }
3769   else // parent being set to NULL
3770   {
3771     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3772
3773     mParent = NULL;
3774
3775     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3776          OnStage() )
3777     {
3778       DALI_ASSERT_ALWAYS( mNode != NULL );
3779
3780       if( NULL != mNode )
3781       {
3782         // Disconnect the Node & its children from the scene-graph.
3783         DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3784       }
3785
3786       // Instruct each actor to discard pointers to the scene-graph
3787       DisconnectFromStage();
3788     }
3789   }
3790 }
3791
3792 SceneGraph::Node* Actor::CreateNode() const
3793 {
3794   return Node::New();
3795 }
3796
3797 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector< Property::Value >& attributes )
3798 {
3799   bool done = false;
3800   Actor* actor = dynamic_cast< Actor* >( object );
3801
3802   if( actor )
3803   {
3804     if( 0 == strcmp( actionName.c_str(), ACTION_SHOW ) ) // dont want to convert char* to string
3805     {
3806       actor->SetVisible( true );
3807       done = true;
3808     }
3809     else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE ) )
3810     {
3811       actor->SetVisible( false );
3812       done = true;
3813     }
3814   }
3815
3816   return done;
3817 }
3818
3819 void Actor::EnsureRelayoutData() const
3820 {
3821   // Assign relayout data.
3822   if( !mRelayoutData )
3823   {
3824     mRelayoutData = new RelayoutData();
3825   }
3826 }
3827
3828 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3829 {
3830   // Check if actor is dependent on parent
3831   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3832   {
3833     if( ( dimension & ( 1 << i ) ) )
3834     {
3835       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3836       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3837       {
3838         return true;
3839       }
3840     }
3841   }
3842
3843   return false;
3844 }
3845
3846 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3847 {
3848   // Check if actor is dependent on children
3849   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3850   {
3851     if( ( dimension & ( 1 << i ) ) )
3852     {
3853       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3854       switch( resizePolicy )
3855       {
3856         case ResizePolicy::FIT_TO_CHILDREN:
3857         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
3858         {
3859           return true;
3860         }
3861
3862         default:
3863         {
3864           break;
3865         }
3866       }
3867     }
3868   }
3869
3870   return false;
3871 }
3872
3873 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3874 {
3875   return Actor::RelayoutDependentOnChildren( dimension );
3876 }
3877
3878 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3879 {
3880   // Check each possible dimension and see if it is dependent on the input one
3881   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3882   {
3883     if( dimension & ( 1 << i ) )
3884     {
3885       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3886     }
3887   }
3888
3889   return false;
3890 }
3891
3892 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3893 {
3894   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3895   {
3896     if( dimension & ( 1 << i ) )
3897     {
3898       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3899     }
3900   }
3901 }
3902
3903 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3904 {
3905   // If more than one dimension is requested, just return the first one found
3906   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3907   {
3908     if( ( dimension & ( 1 << i ) ) )
3909     {
3910       return mRelayoutData->negotiatedDimensions[ i ];
3911     }
3912   }
3913
3914   return 0.0f;   // Default
3915 }
3916
3917 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3918 {
3919   EnsureRelayoutData();
3920
3921   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3922   {
3923     if( dimension & ( 1 << i ) )
3924     {
3925       mRelayoutData->dimensionPadding[ i ] = padding;
3926     }
3927   }
3928 }
3929
3930 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3931 {
3932   EnsureRelayoutData();
3933
3934   // If more than one dimension is requested, just return the first one found
3935   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3936   {
3937     if( ( dimension & ( 1 << i ) ) )
3938     {
3939       return mRelayoutData->dimensionPadding[ i ];
3940     }
3941   }
3942
3943   return Vector2( 0.0f, 0.0f );   // Default
3944 }
3945
3946 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3947 {
3948   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3949   {
3950     if( dimension & ( 1 << i ) )
3951     {
3952       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3953     }
3954   }
3955 }
3956
3957 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3958 {
3959   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3960   {
3961     if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3962     {
3963       return true;
3964     }
3965   }
3966
3967   return false;
3968 }
3969
3970 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3971 {
3972   // Could be overridden in derived classes.
3973   return CalculateChildSizeBase( child, dimension );
3974 }
3975
3976 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3977 {
3978   // Fill to parent, taking size mode factor into account
3979   switch( child.GetResizePolicy( dimension ) )
3980   {
3981     case ResizePolicy::FILL_TO_PARENT:
3982     {
3983       return GetLatestSize( dimension );
3984     }
3985
3986     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3987     {
3988       return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3989     }
3990
3991     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3992     {
3993       return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3994     }
3995
3996     default:
3997     {
3998       return GetLatestSize( dimension );
3999     }
4000   }
4001 }
4002
4003 float Actor::GetHeightForWidth( float width )
4004 {
4005   // Could be overridden in derived classes.
4006   float height = 0.0f;
4007
4008   const Vector3 naturalSize = GetNaturalSize();
4009   if( naturalSize.width > 0.0f )
4010   {
4011     height = naturalSize.height * width / naturalSize.width;
4012   }
4013
4014   return height;
4015 }
4016
4017 float Actor::GetWidthForHeight( float height )
4018 {
4019   // Could be overridden in derived classes.
4020   float width = 0.0f;
4021
4022   const Vector3 naturalSize = GetNaturalSize();
4023   if( naturalSize.height > 0.0f )
4024   {
4025     width = naturalSize.width * height / naturalSize.height;
4026   }
4027
4028   return width;
4029 }
4030
4031 float Actor::GetLatestSize( Dimension::Type dimension ) const
4032 {
4033   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4034 }
4035
4036 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4037 {
4038   Vector2 padding = GetPadding( dimension );
4039
4040   return GetLatestSize( dimension ) + padding.x + padding.y;
4041 }
4042
4043 float Actor::NegotiateFromParent( Dimension::Type dimension )
4044 {
4045   Actor* parent = GetParent();
4046   if( parent )
4047   {
4048     Vector2 padding( GetPadding( dimension ) );
4049     Vector2 parentPadding( parent->GetPadding( dimension ) );
4050     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4051   }
4052
4053   return 0.0f;
4054 }
4055
4056 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4057 {
4058   float maxDimensionPoint = 0.0f;
4059
4060   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4061   {
4062     Dali::Actor child = GetChildAt( i );
4063     Actor& childImpl = GetImplementation( child );
4064
4065     if( !childImpl.RelayoutDependentOnParent( dimension ) )
4066     {
4067       // Calculate the min and max points that the children range across
4068       float childPosition = GetDimensionValue( childImpl.GetTargetPosition(), dimension );
4069       float dimensionSize = childImpl.GetRelayoutSize( dimension );
4070       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4071     }
4072   }
4073
4074   return maxDimensionPoint;
4075 }
4076
4077 float Actor::GetSize( Dimension::Type dimension ) const
4078 {
4079   return GetDimensionValue( GetTargetSize(), dimension );
4080 }
4081
4082 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4083 {
4084   return GetDimensionValue( GetNaturalSize(), dimension );
4085 }
4086
4087 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4088 {
4089   switch( GetResizePolicy( dimension ) )
4090   {
4091     case ResizePolicy::USE_NATURAL_SIZE:
4092     {
4093       return GetNaturalSize( dimension );
4094     }
4095
4096     case ResizePolicy::FIXED:
4097     {
4098       return GetDimensionValue( GetPreferredSize(), dimension );
4099     }
4100
4101     case ResizePolicy::USE_ASSIGNED_SIZE:
4102     {
4103       return GetDimensionValue( maximumSize, dimension );
4104     }
4105
4106     case ResizePolicy::FILL_TO_PARENT:
4107     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4108     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4109     {
4110       return NegotiateFromParent( dimension );
4111     }
4112
4113     case ResizePolicy::FIT_TO_CHILDREN:
4114     {
4115       return NegotiateFromChildren( dimension );
4116     }
4117
4118     case ResizePolicy::DIMENSION_DEPENDENCY:
4119     {
4120       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4121
4122       // Custom rules
4123       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4124       {
4125         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4126       }
4127
4128       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4129       {
4130         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4131       }
4132
4133       break;
4134     }
4135
4136     default:
4137     {
4138       break;
4139     }
4140   }
4141
4142   return 0.0f;  // Default
4143 }
4144
4145 float Actor::ClampDimension( float size, Dimension::Type dimension )
4146 {
4147   const float minSize = GetMinimumSize( dimension );
4148   const float maxSize = GetMaximumSize( dimension );
4149
4150   return std::max( minSize, std::min( size, maxSize ) );
4151 }
4152
4153 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4154 {
4155   // Check if it needs to be negotiated
4156   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4157   {
4158     // Check that we havn't gotten into an infinite loop
4159     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4160     bool recursionFound = false;
4161     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4162     {
4163       if( *it == searchActor )
4164       {
4165         recursionFound = true;
4166         break;
4167       }
4168     }
4169
4170     if( !recursionFound )
4171     {
4172       // Record the path that we have taken
4173       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4174
4175       // Dimension dependency check
4176       for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4177       {
4178         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4179
4180         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4181         {
4182           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4183         }
4184       }
4185
4186       // Parent dependency check
4187       Actor* parent = GetParent();
4188       if( parent && RelayoutDependentOnParent( dimension ) )
4189       {
4190         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4191       }
4192
4193       // Children dependency check
4194       if( RelayoutDependentOnChildren( dimension ) )
4195       {
4196         for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4197         {
4198           Dali::Actor child = GetChildAt( i );
4199           Actor& childImpl = GetImplementation( child );
4200
4201           // Only relayout child first if it is not dependent on this actor
4202           if( !childImpl.RelayoutDependentOnParent( dimension ) )
4203           {
4204             childImpl.NegotiateDimension( dimension, allocatedSize, recursionStack );
4205           }
4206         }
4207       }
4208
4209       // For deriving classes
4210       OnCalculateRelayoutSize( dimension );
4211
4212       // All dependencies checked, calculate the size and set negotiated flag
4213       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4214
4215       SetNegotiatedDimension( newSize, dimension );
4216       SetLayoutNegotiated( true, dimension );
4217
4218       // For deriving classes
4219       OnLayoutNegotiated( newSize, dimension );
4220
4221       // This actor has been successfully processed, pop it off the recursion stack
4222       recursionStack.pop_back();
4223     }
4224     else
4225     {
4226       // TODO: Break infinite loop
4227       SetLayoutNegotiated( true, dimension );
4228     }
4229   }
4230 }
4231
4232 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4233 {
4234   // Negotiate all dimensions that require it
4235   ActorDimensionStack recursionStack;
4236
4237   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4238   {
4239     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4240
4241     // Negotiate
4242     NegotiateDimension( dimension, allocatedSize, recursionStack );
4243   }
4244 }
4245
4246 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4247 {
4248   switch( mRelayoutData->sizeSetPolicy )
4249   {
4250     case SizeScalePolicy::USE_SIZE_SET:
4251     {
4252       return size;
4253     }
4254
4255     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4256     {
4257       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4258       const Vector3 naturalSize = GetNaturalSize();
4259       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4260       {
4261         const float sizeRatio = size.width / size.height;
4262         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4263
4264         if( naturalSizeRatio < sizeRatio )
4265         {
4266           return Vector2( naturalSizeRatio * size.height, size.height );
4267         }
4268         else if( naturalSizeRatio > sizeRatio )
4269         {
4270           return Vector2( size.width, size.width / naturalSizeRatio );
4271         }
4272         else
4273         {
4274           return size;
4275         }
4276       }
4277
4278       break;
4279     }
4280
4281     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4282     {
4283       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4284       const Vector3 naturalSize = GetNaturalSize();
4285       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4286       {
4287         const float sizeRatio = size.width / size.height;
4288         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4289
4290         if( naturalSizeRatio < sizeRatio )
4291         {
4292           return Vector2( size.width, size.width / naturalSizeRatio );
4293         }
4294         else if( naturalSizeRatio > sizeRatio )
4295         {
4296           return Vector2( naturalSizeRatio * size.height, size.height );
4297         }
4298         else
4299         {
4300           return size;
4301         }
4302       }
4303     }
4304
4305     default:
4306     {
4307       break;
4308     }
4309   }
4310
4311   return size;
4312 }
4313
4314 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4315 {
4316   // Do the set actor size
4317   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4318
4319   // Adjust for size set policy
4320   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4321
4322   // Lock the flag to stop recursive relayouts on set size
4323   mRelayoutData->insideRelayout = true;
4324   SetSize( negotiatedSize );
4325   mRelayoutData->insideRelayout = false;
4326
4327   // Clear flags for all dimensions
4328   SetLayoutDirty( false );
4329
4330   // Give deriving classes a chance to respond
4331   OnRelayout( negotiatedSize, container );
4332
4333   if( !mOnRelayoutSignal.Empty() )
4334   {
4335     Dali::Actor handle( this );
4336     mOnRelayoutSignal.Emit( handle );
4337   }
4338 }
4339
4340 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4341 {
4342   // Do the negotiation
4343   NegotiateDimensions( allocatedSize );
4344
4345   // Set the actor size
4346   SetNegotiatedSize( container );
4347
4348   // Negotiate down to children
4349   const Vector2 newBounds = GetTargetSize().GetVectorXY();
4350
4351   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4352   {
4353     Dali::Actor child = GetChildAt( i );
4354
4355     // Only relayout if required
4356     if( GetImplementation( child ).RelayoutRequired() )
4357     {
4358       container.Add( child, newBounds );
4359     }
4360   }
4361 }
4362
4363 void Actor::RelayoutRequest( Dimension::Type dimension )
4364 {
4365   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4366   if( relayoutController )
4367   {
4368     Dali::Actor self( this );
4369     relayoutController->RequestRelayout( self, dimension );
4370   }
4371 }
4372
4373 void Actor::PropagateRelayoutFlags()
4374 {
4375   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4376   if( relayoutController )
4377   {
4378     Dali::Actor self( this );
4379     relayoutController->PropagateFlags( self );
4380   }
4381 }
4382
4383 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4384 {
4385 }
4386
4387 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4388 {
4389 }
4390
4391 void Actor::SetPreferredSize( const Vector2& size )
4392 {
4393   EnsureRelayoutData();
4394
4395   if( size.width > 0.0f )
4396   {
4397     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4398   }
4399
4400   if( size.height > 0.0f )
4401   {
4402     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4403   }
4404
4405   mRelayoutData->preferredSize = size;
4406
4407   RelayoutRequest();
4408 }
4409
4410 Vector2 Actor::GetPreferredSize() const
4411 {
4412   EnsureRelayoutData();
4413
4414   return mRelayoutData->preferredSize;
4415 }
4416
4417 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4418 {
4419   EnsureRelayoutData();
4420
4421   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4422   {
4423     if( dimension & ( 1 << i ) )
4424     {
4425       mRelayoutData->minimumSize[ i ] = size;
4426     }
4427   }
4428
4429   RelayoutRequest();
4430 }
4431
4432 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4433 {
4434   EnsureRelayoutData();
4435
4436   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4437   {
4438     if( dimension & ( 1 << i ) )
4439     {
4440       return mRelayoutData->minimumSize[ i ];
4441     }
4442   }
4443
4444   return 0.0f;  // Default
4445 }
4446
4447 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4448 {
4449   EnsureRelayoutData();
4450
4451   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4452   {
4453     if( dimension & ( 1 << i ) )
4454     {
4455       mRelayoutData->maximumSize[ i ] = size;
4456     }
4457   }
4458
4459   RelayoutRequest();
4460 }
4461
4462 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4463 {
4464   EnsureRelayoutData();
4465
4466   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4467   {
4468     if( dimension & ( 1 << i ) )
4469     {
4470       return mRelayoutData->maximumSize[ i ];
4471     }
4472   }
4473
4474   return 0.0f;  // Default
4475 }
4476
4477 } // namespace Internal
4478
4479 } // namespace Dali