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