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