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