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