Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
1 /*
2  * Copyright (c) 2017 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/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.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       negotiatedDimensions[ i ] = 0.0f;
105       dimensionNegotiated[ i ] = false;
106       dimensionDirty[ i ] = false;
107       dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
108       dimensionPadding[ i ] = GetDefaultDimensionPadding();
109       minimumSize[ i ] = 0.0f;
110       maximumSize[ i ] = FLT_MAX;
111     }
112   }
113
114   ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ];      ///< Resize policies
115
116   Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ];  ///< A list of dimension dependencies
117
118   Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ];         ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
119
120   float negotiatedDimensions[ Dimension::DIMENSION_COUNT ];       ///< Storage for when a dimension is negotiated but before set on actor
121
122   float minimumSize[ Dimension::DIMENSION_COUNT ];                ///< The minimum size an actor can be
123   float maximumSize[ Dimension::DIMENSION_COUNT ];                ///< The maximum size an actor can be
124
125   bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ];         ///< Has the dimension been negotiated
126   bool dimensionDirty[ Dimension::DIMENSION_COUNT ];              ///< Flags indicating whether the layout dimension is dirty or not
127
128   Vector3 sizeModeFactor;                              ///< Factor of size used for certain SizeModes
129
130   Vector2 preferredSize;                               ///< The preferred size of the actor
131
132   SizeScalePolicy::Type sizeSetPolicy :3;            ///< Policy to apply when setting size. Enough room for the enum
133
134   bool relayoutEnabled :1;                   ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
135   bool insideRelayout :1;                    ///< Locking flag to prevent recursive relayouts on size set
136 };
137
138 namespace // unnamed namespace
139 {
140
141 // Properties
142
143 /**
144  * We want to discourage the use of property strings (minimize string comparisons),
145  * particularly for the default properties.
146  *              Name                  Type   writable animatable constraint-input  enum for index-checking
147  */
148 DALI_PROPERTY_TABLE_BEGIN
149 DALI_PROPERTY( "parentOrigin",        VECTOR3,  true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN )
150 DALI_PROPERTY( "parentOriginX",       FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_X )
151 DALI_PROPERTY( "parentOriginY",       FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_Y )
152 DALI_PROPERTY( "parentOriginZ",       FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_Z )
153 DALI_PROPERTY( "anchorPoint",         VECTOR3,  true,  false, true,  Dali::Actor::Property::ANCHOR_POINT )
154 DALI_PROPERTY( "anchorPointX",        FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_X )
155 DALI_PROPERTY( "anchorPointY",        FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_Y )
156 DALI_PROPERTY( "anchorPointZ",        FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_Z )
157 DALI_PROPERTY( "size",                VECTOR3,  true,  true,  true,  Dali::Actor::Property::SIZE )
158 DALI_PROPERTY( "sizeWidth",           FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_WIDTH )
159 DALI_PROPERTY( "sizeHeight",          FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_HEIGHT )
160 DALI_PROPERTY( "sizeDepth",           FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_DEPTH )
161 DALI_PROPERTY( "position",            VECTOR3,  true,  true,  true,  Dali::Actor::Property::POSITION )
162 DALI_PROPERTY( "positionX",           FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_X )
163 DALI_PROPERTY( "positionY",           FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_Y )
164 DALI_PROPERTY( "positionZ",           FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_Z )
165 DALI_PROPERTY( "worldPosition",       VECTOR3,  false, false, true,  Dali::Actor::Property::WORLD_POSITION )
166 DALI_PROPERTY( "worldPositionX",      FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_X )
167 DALI_PROPERTY( "worldPositionY",      FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_Y )
168 DALI_PROPERTY( "worldPositionZ",      FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_Z )
169 DALI_PROPERTY( "orientation",         ROTATION, true,  true,  true,  Dali::Actor::Property::ORIENTATION )
170 DALI_PROPERTY( "worldOrientation",    ROTATION, false, false, true,  Dali::Actor::Property::WORLD_ORIENTATION )
171 DALI_PROPERTY( "scale",               VECTOR3,  true,  true,  true,  Dali::Actor::Property::SCALE )
172 DALI_PROPERTY( "scaleX",              FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_X )
173 DALI_PROPERTY( "scaleY",              FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_Y )
174 DALI_PROPERTY( "scaleZ",              FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_Z )
175 DALI_PROPERTY( "worldScale",          VECTOR3,  false, false, true,  Dali::Actor::Property::WORLD_SCALE )
176 DALI_PROPERTY( "visible",             BOOLEAN,  true,  true,  true,  Dali::Actor::Property::VISIBLE )
177 DALI_PROPERTY( "color",               VECTOR4,  true,  true,  true,  Dali::Actor::Property::COLOR )
178 DALI_PROPERTY( "colorRed",            FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_RED )
179 DALI_PROPERTY( "colorGreen",          FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_GREEN )
180 DALI_PROPERTY( "colorBlue",           FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_BLUE )
181 DALI_PROPERTY( "colorAlpha",          FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_ALPHA )
182 DALI_PROPERTY( "worldColor",          VECTOR4,  false, false, true,  Dali::Actor::Property::WORLD_COLOR )
183 DALI_PROPERTY( "worldMatrix",         MATRIX,   false, false, true,  Dali::Actor::Property::WORLD_MATRIX )
184 DALI_PROPERTY( "name",                STRING,   true,  false, false, Dali::Actor::Property::NAME )
185 DALI_PROPERTY( "sensitive",           BOOLEAN,  true,  false, false, Dali::Actor::Property::SENSITIVE )
186 DALI_PROPERTY( "leaveRequired",       BOOLEAN,  true,  false, false, Dali::Actor::Property::LEAVE_REQUIRED )
187 DALI_PROPERTY( "inheritOrientation",  BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
188 DALI_PROPERTY( "inheritScale",        BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_SCALE )
189 DALI_PROPERTY( "colorMode",           STRING,   true,  false, false, Dali::Actor::Property::COLOR_MODE )
190 DALI_PROPERTY( "positionInheritance", STRING,   true,  false, false, Dali::Actor::Property::POSITION_INHERITANCE )
191 DALI_PROPERTY( "drawMode",            STRING,   true,  false, false, Dali::Actor::Property::DRAW_MODE )
192 DALI_PROPERTY( "sizeModeFactor",      VECTOR3,  true,  false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
193 DALI_PROPERTY( "widthResizePolicy",   STRING,   true,  false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
194 DALI_PROPERTY( "heightResizePolicy",  STRING,   true,  false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
195 DALI_PROPERTY( "sizeScalePolicy",     STRING,   true,  false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
196 DALI_PROPERTY( "widthForHeight",      BOOLEAN,  true,  false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
197 DALI_PROPERTY( "heightForWidth",      BOOLEAN,  true,  false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
198 DALI_PROPERTY( "padding",             VECTOR4,  true,  false, false, Dali::Actor::Property::PADDING )
199 DALI_PROPERTY( "minimumSize",         VECTOR2,  true,  false, false, Dali::Actor::Property::MINIMUM_SIZE )
200 DALI_PROPERTY( "maximumSize",         VECTOR2,  true,  false, false, Dali::Actor::Property::MAXIMUM_SIZE )
201 DALI_PROPERTY( "inheritPosition",     BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_POSITION )
202 DALI_PROPERTY( "clippingMode",        STRING,   true,  false, false, Dali::Actor::Property::CLIPPING_MODE )
203 DALI_PROPERTY( "batchParent",         BOOLEAN,  true,  false, false, Dali::DevelActor::Property::BATCH_PARENT )
204 DALI_PROPERTY( "siblingOrder",        INTEGER,  true,  false, false, Dali::DevelActor::Property::SIBLING_ORDER )
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       mRelayoutData->resizePolicies[ i ] = policy;
1299     }
1300   }
1301
1302   if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1303   {
1304     if( dimension & Dimension::WIDTH )
1305     {
1306       SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1307     }
1308
1309     if( dimension & Dimension::HEIGHT )
1310     {
1311       SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1312     }
1313   }
1314
1315   // If calling SetResizePolicy, assume we want relayout enabled
1316   SetRelayoutEnabled( true );
1317
1318   OnSetResizePolicy( policy, dimension );
1319
1320   // Trigger relayout on this control
1321   RelayoutRequest();
1322 }
1323
1324 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1325 {
1326   if ( mRelayoutData )
1327   {
1328     // If more than one dimension is requested, just return the first one found
1329     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1330     {
1331       if( ( dimension & ( 1 << i ) ) )
1332       {
1333         return mRelayoutData->resizePolicies[ i ];
1334       }
1335     }
1336   }
1337
1338   return ResizePolicy::DEFAULT;
1339 }
1340
1341 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1342 {
1343   EnsureRelayoutData();
1344
1345   mRelayoutData->sizeSetPolicy = policy;
1346 }
1347
1348 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1349 {
1350   if ( mRelayoutData )
1351   {
1352     return mRelayoutData->sizeSetPolicy;
1353   }
1354
1355   return DEFAULT_SIZE_SCALE_POLICY;
1356 }
1357
1358 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1359 {
1360   EnsureRelayoutData();
1361
1362   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1363   {
1364     if( dimension & ( 1 << i ) )
1365     {
1366       mRelayoutData->dimensionDependencies[ i ] = dependency;
1367     }
1368   }
1369 }
1370
1371 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1372 {
1373   if ( mRelayoutData )
1374   {
1375     // If more than one dimension is requested, just return the first one found
1376     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1377     {
1378       if( ( dimension & ( 1 << i ) ) )
1379       {
1380         return mRelayoutData->dimensionDependencies[ i ];
1381       }
1382     }
1383   }
1384
1385   return Dimension::ALL_DIMENSIONS;   // Default
1386 }
1387
1388 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1389 {
1390   // If relayout data has not been allocated yet and the client is requesting
1391   // to disable it, do nothing
1392   if( mRelayoutData || relayoutEnabled )
1393   {
1394     EnsureRelayoutData();
1395
1396     DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1397
1398     mRelayoutData->relayoutEnabled = relayoutEnabled;
1399   }
1400 }
1401
1402 bool Actor::IsRelayoutEnabled() const
1403 {
1404   // Assume that if relayout data has not been allocated yet then
1405   // relayout is disabled
1406   return mRelayoutData && mRelayoutData->relayoutEnabled;
1407 }
1408
1409 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1410 {
1411   EnsureRelayoutData();
1412
1413   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1414   {
1415     if( dimension & ( 1 << i ) )
1416     {
1417       mRelayoutData->dimensionDirty[ i ] = dirty;
1418     }
1419   }
1420 }
1421
1422 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1423 {
1424   if ( mRelayoutData )
1425   {
1426     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1427     {
1428       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1429       {
1430         return true;
1431       }
1432     }
1433   }
1434
1435   return false;
1436 }
1437
1438 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1439 {
1440   return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1441 }
1442
1443 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1444 {
1445   return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1446 }
1447
1448 unsigned int Actor::AddRenderer( Renderer& renderer )
1449 {
1450   if( !mRenderers )
1451   {
1452     mRenderers = new RendererContainer;
1453   }
1454
1455   unsigned int index = mRenderers->size();
1456   RendererPtr rendererPtr = RendererPtr( &renderer );
1457   mRenderers->push_back( rendererPtr );
1458   AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1459
1460   if( mIsOnStage)
1461   {
1462     rendererPtr->Connect();
1463   }
1464
1465   return index;
1466 }
1467
1468 unsigned int Actor::GetRendererCount() const
1469 {
1470   unsigned int rendererCount(0);
1471   if( mRenderers )
1472   {
1473     rendererCount = mRenderers->size();
1474   }
1475
1476   return rendererCount;
1477 }
1478
1479 RendererPtr Actor::GetRendererAt( unsigned int index )
1480 {
1481   RendererPtr renderer;
1482   if( index < GetRendererCount() )
1483   {
1484     renderer = ( *mRenderers )[ index ];
1485   }
1486
1487   return renderer;
1488 }
1489
1490 void Actor::RemoveRenderer( Renderer& renderer )
1491 {
1492   if( mRenderers )
1493   {
1494     RendererIter end = mRenderers->end();
1495     for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1496     {
1497       if( (*iter).Get() == &renderer )
1498       {
1499         mRenderers->erase( iter );
1500         RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1501         break;
1502       }
1503     }
1504   }
1505 }
1506
1507 void Actor::RemoveRenderer( unsigned int index )
1508 {
1509   if( index < GetRendererCount() )
1510   {
1511     RendererPtr renderer = ( *mRenderers )[ index ];
1512     RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1513     mRenderers->erase( mRenderers->begin()+index );
1514   }
1515 }
1516
1517 bool Actor::IsOverlay() const
1518 {
1519   return ( DrawMode::OVERLAY_2D == mDrawMode );
1520 }
1521
1522 void Actor::SetDrawMode( DrawMode::Type drawMode )
1523 {
1524   // this flag is not animatable so keep the value
1525   mDrawMode = drawMode;
1526   if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1527   {
1528     // mNode is being used in a separate thread; queue a message to set the value
1529     SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1530   }
1531 }
1532
1533 DrawMode::Type Actor::GetDrawMode() const
1534 {
1535   return mDrawMode;
1536 }
1537
1538 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1539 {
1540   // only valid when on-stage
1541   StagePtr stage = Stage::GetCurrent();
1542   if( stage && OnStage() )
1543   {
1544     const RenderTaskList& taskList = stage->GetRenderTaskList();
1545
1546     Vector2 converted( screenX, screenY );
1547
1548     // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1549     const int taskCount = taskList.GetTaskCount();
1550     for( int i = taskCount - 1; i >= 0; --i )
1551     {
1552       Dali::RenderTask task = taskList.GetTask( i );
1553       if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1554       {
1555         // found a task where this conversion was ok so return
1556         return true;
1557       }
1558     }
1559   }
1560   return false;
1561 }
1562
1563 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1564 {
1565   bool retval = false;
1566   // only valid when on-stage
1567   if( OnStage() )
1568   {
1569     CameraActor* camera = renderTask.GetCameraActor();
1570     if( camera )
1571     {
1572       Viewport viewport;
1573       renderTask.GetViewport( viewport );
1574
1575       // need to translate coordinates to render tasks coordinate space
1576       Vector2 converted( screenX, screenY );
1577       if( renderTask.TranslateCoordinates( converted ) )
1578       {
1579         retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1580       }
1581     }
1582   }
1583   return retval;
1584 }
1585
1586 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1587 {
1588   // Early-out if mNode is NULL
1589   if( !OnStage() )
1590   {
1591     return false;
1592   }
1593
1594   // Get the ModelView matrix
1595   Matrix modelView;
1596   Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1597
1598   // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1599   Matrix invertedMvp( false/*don't init*/);
1600   Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1601   bool success = invertedMvp.Invert();
1602
1603   // Convert to GL coordinates
1604   Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1605
1606   Vector4 nearPos;
1607   if( success )
1608   {
1609     success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1610   }
1611
1612   Vector4 farPos;
1613   if( success )
1614   {
1615     screenPos.z = 1.0f;
1616     success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1617   }
1618
1619   if( success )
1620   {
1621     Vector4 local;
1622     if( XyPlaneIntersect( nearPos, farPos, local ) )
1623     {
1624       Vector3 size = GetCurrentSize();
1625       localX = local.x + size.x * 0.5f;
1626       localY = local.y + size.y * 0.5f;
1627     }
1628     else
1629     {
1630       success = false;
1631     }
1632   }
1633
1634   return success;
1635 }
1636
1637 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1638 {
1639   /*
1640    http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1641
1642    Mathematical Formulation
1643
1644    Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1645
1646    ( p - c ) dot ( p - c ) = r^2
1647
1648    Given a ray with a point of origin 'o', and a direction vector 'd':
1649
1650    ray(t) = o + td, t >= 0
1651
1652    we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1653
1654    (o + td - c ) dot ( o + td - c ) = r^2
1655
1656    To solve for t we first expand the above into a more recognisable quadratic equation form
1657
1658    ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1659
1660    or
1661
1662    At2 + Bt + C = 0
1663
1664    where
1665
1666    A = d dot d
1667    B = 2( o - c ) dot d
1668    C = ( o - c ) dot ( o - c ) - r^2
1669
1670    which can be solved using a standard quadratic formula.
1671
1672    Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1673
1674    Practical Simplification
1675
1676    In a renderer, we often differentiate between world space and object space. In the object space
1677    of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1678    into object space, the mathematical solution presented above can be simplified significantly.
1679
1680    If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1681
1682    p dot p = r^2
1683
1684    and we can find the t at which the (transformed) ray intersects the sphere by
1685
1686    ( o + td ) dot ( o + td ) = r^2
1687
1688    According to the reasoning above, we expand the above quadratic equation into the general form
1689
1690    At2 + Bt + C = 0
1691
1692    which now has coefficients:
1693
1694    A = d dot d
1695    B = 2( d dot o )
1696    C = o dot o - r^2
1697    */
1698
1699   // Early out if mNode is NULL
1700   if( !mNode )
1701   {
1702     return false;
1703   }
1704
1705   BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1706
1707   // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1708   const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1709   Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1710
1711   // Compute the radius is not needed, square radius it's enough.
1712   const Vector3& size( mNode->GetSize( bufferIndex ) );
1713
1714   // Scale the sphere.
1715   const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1716
1717   const float width = size.width * scale.width;
1718   const float height = size.height * scale.height;
1719
1720   float squareSphereRadius = 0.5f * ( width * width + height * height );
1721
1722   float a = rayDir.Dot( rayDir );                                       // a
1723   float b2 = rayDir.Dot( rayOriginLocal );                              // b/2
1724   float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius;  // c
1725
1726   return ( b2 * b2 - a * c ) >= 0.f;
1727 }
1728
1729 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1730 {
1731   bool hit = false;
1732
1733   if( OnStage() && NULL != mNode )
1734   {
1735     // Transforms the ray to the local reference system.
1736     // Calculate the inverse of Model matrix
1737     Matrix invModelMatrix( false/*don't init*/);
1738
1739     BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1740     invModelMatrix = mNode->GetWorldMatrix(0);
1741     invModelMatrix.Invert();
1742
1743     Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1744     Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1745
1746     // Test with the actor's XY plane (Normal = 0 0 1 1).
1747
1748     float a = -rayOriginLocal.z;
1749     float b = rayDirLocal.z;
1750
1751     if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1752     {
1753       // Ray travels distance * rayDirLocal to intersect with plane.
1754       distance = a / b;
1755
1756       const Vector3& size = mNode->GetSize( bufferIndex );
1757
1758       hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1759       hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1760
1761       // Test with the actor's geometry.
1762       hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1763     }
1764   }
1765
1766   return hit;
1767 }
1768
1769 void Actor::SetLeaveRequired( bool required )
1770 {
1771   mLeaveRequired = required;
1772 }
1773
1774 bool Actor::GetLeaveRequired() const
1775 {
1776   return mLeaveRequired;
1777 }
1778
1779 void Actor::SetKeyboardFocusable( bool focusable )
1780 {
1781   mKeyboardFocusable = focusable;
1782 }
1783
1784 bool Actor::IsKeyboardFocusable() const
1785 {
1786   return mKeyboardFocusable;
1787 }
1788
1789 bool Actor::GetTouchRequired() const
1790 {
1791   return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1792 }
1793
1794 bool Actor::GetHoverRequired() const
1795 {
1796   return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1797 }
1798
1799 bool Actor::GetWheelEventRequired() const
1800 {
1801   return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1802 }
1803
1804 bool Actor::IsHittable() const
1805 {
1806   return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1807 }
1808
1809 ActorGestureData& Actor::GetGestureData()
1810 {
1811   // Likely scenario is that once gesture-data is created for this actor, the actor will require
1812   // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1813   if( NULL == mGestureData )
1814   {
1815     mGestureData = new ActorGestureData;
1816   }
1817   return *mGestureData;
1818 }
1819
1820 bool Actor::IsGestureRequred( Gesture::Type type ) const
1821 {
1822   return mGestureData && mGestureData->IsGestureRequred( type );
1823 }
1824
1825 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1826 {
1827   bool consumed = false;
1828
1829   if( !mTouchSignal.Empty() )
1830   {
1831     Dali::Actor handle( this );
1832     consumed = mTouchSignal.Emit( handle, touch );
1833   }
1834
1835   if( !mTouchedSignal.Empty() )
1836   {
1837     Dali::Actor handle( this );
1838     consumed |= mTouchedSignal.Emit( handle, event );
1839   }
1840
1841   if( !consumed )
1842   {
1843     // Notification for derived classes
1844     consumed = OnTouchEvent( event ); // TODO
1845   }
1846
1847   return consumed;
1848 }
1849
1850 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1851 {
1852   bool consumed = false;
1853
1854   if( !mHoveredSignal.Empty() )
1855   {
1856     Dali::Actor handle( this );
1857     consumed = mHoveredSignal.Emit( handle, event );
1858   }
1859
1860   if( !consumed )
1861   {
1862     // Notification for derived classes
1863     consumed = OnHoverEvent( event );
1864   }
1865
1866   return consumed;
1867 }
1868
1869 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1870 {
1871   bool consumed = false;
1872
1873   if( !mWheelEventSignal.Empty() )
1874   {
1875     Dali::Actor handle( this );
1876     consumed = mWheelEventSignal.Emit( handle, event );
1877   }
1878
1879   if( !consumed )
1880   {
1881     // Notification for derived classes
1882     consumed = OnWheelEvent( event );
1883   }
1884
1885   return consumed;
1886 }
1887
1888 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1889 {
1890   return mTouchedSignal;
1891 }
1892
1893 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1894 {
1895   return mTouchSignal;
1896 }
1897
1898 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1899 {
1900   return mHoveredSignal;
1901 }
1902
1903 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1904 {
1905   return mWheelEventSignal;
1906 }
1907
1908 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1909 {
1910   return mOnStageSignal;
1911 }
1912
1913 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1914 {
1915   return mOffStageSignal;
1916 }
1917
1918 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1919 {
1920   return mOnRelayoutSignal;
1921 }
1922
1923 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1924 {
1925   bool connected( true );
1926   Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1927
1928   if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1929   {
1930     actor->TouchedSignal().Connect( tracker, functor );
1931   }
1932   else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1933   {
1934     actor->HoveredSignal().Connect( tracker, functor );
1935   }
1936   else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1937   {
1938     actor->WheelEventSignal().Connect( tracker, functor );
1939   }
1940   else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1941   {
1942     actor->OnStageSignal().Connect( tracker, functor );
1943   }
1944   else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1945   {
1946     actor->OffStageSignal().Connect( tracker, functor );
1947   }
1948   else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1949   {
1950     actor->OnRelayoutSignal().Connect( tracker, functor );
1951   }
1952   else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1953   {
1954     actor->TouchSignal().Connect( tracker, functor );
1955   }
1956   else
1957   {
1958     // signalName does not match any signal
1959     connected = false;
1960   }
1961
1962   return connected;
1963 }
1964
1965 Actor::Actor( DerivedType derivedType )
1966 : mParent( NULL ),
1967   mChildren( NULL ),
1968   mRenderers( NULL ),
1969   mNode( NULL ),
1970   mParentOrigin( NULL ),
1971   mAnchorPoint( NULL ),
1972   mRelayoutData( NULL ),
1973   mGestureData( NULL ),
1974   mTargetSize( 0.0f, 0.0f, 0.0f ),
1975   mName(),
1976   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1977   mDepth( 0u ),
1978   mSiblingOrder(0u),
1979   mIsRoot( ROOT_LAYER == derivedType ),
1980   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1981   mIsOnStage( false ),
1982   mSensitive( true ),
1983   mLeaveRequired( false ),
1984   mKeyboardFocusable( false ),
1985   mDerivedRequiresTouch( false ),
1986   mDerivedRequiresHover( false ),
1987   mDerivedRequiresWheelEvent( false ),
1988   mOnStageSignalled( false ),
1989   mInsideOnSizeSet( false ),
1990   mInheritPosition( true ),
1991   mInheritOrientation( true ),
1992   mInheritScale( true ),
1993   mDrawMode( DrawMode::NORMAL ),
1994   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1995   mColorMode( Node::DEFAULT_COLOR_MODE ),
1996   mClippingMode( ClippingMode::DISABLED ),
1997   mIsBatchParent( false )
1998 {
1999 }
2000
2001 void Actor::Initialize()
2002 {
2003   // Node creation
2004   SceneGraph::Node* node = CreateNode();
2005
2006   AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2007   mNode = node; // Keep raw-pointer to Node
2008
2009   OnInitialize();
2010
2011   GetEventThreadServices().RegisterObject( this );
2012 }
2013
2014 Actor::~Actor()
2015 {
2016   // Remove mParent pointers from children even if we're destroying core,
2017   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2018   if( mChildren )
2019   {
2020     ActorConstIter endIter = mChildren->end();
2021     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2022     {
2023       (*iter)->SetParent( NULL );
2024     }
2025   }
2026   delete mChildren;
2027   delete mRenderers;
2028
2029   // Guard to allow handle destruction after Core has been destroyed
2030   if( EventThreadServices::IsCoreRunning() )
2031   {
2032     if( NULL != mNode )
2033     {
2034       DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2035       mNode = NULL; // Node is about to be destroyed
2036     }
2037
2038     GetEventThreadServices().UnregisterObject( this );
2039   }
2040
2041   // Cleanup optional gesture data
2042   delete mGestureData;
2043
2044   // Cleanup optional parent origin and anchor
2045   delete mParentOrigin;
2046   delete mAnchorPoint;
2047
2048   // Delete optional relayout data
2049   if( mRelayoutData )
2050   {
2051     delete mRelayoutData;
2052   }
2053 }
2054
2055 void Actor::ConnectToStage( unsigned int parentDepth )
2056 {
2057   // This container is used instead of walking the Actor hierarchy.
2058   // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2059   ActorContainer connectionList;
2060
2061   // This stage is atomic i.e. not interrupted by user callbacks.
2062   RecursiveConnectToStage( connectionList, parentDepth + 1 );
2063
2064   // Notify applications about the newly connected actors.
2065   const ActorIter endIter = connectionList.end();
2066   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2067   {
2068     (*iter)->NotifyStageConnection();
2069   }
2070
2071   RelayoutRequest();
2072 }
2073
2074 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2075 {
2076   DALI_ASSERT_ALWAYS( !OnStage() );
2077
2078   mIsOnStage = true;
2079   mDepth = depth;
2080   SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2081
2082   ConnectToSceneGraph();
2083
2084   // Notification for internal derived classes
2085   OnStageConnectionInternal();
2086
2087   // This stage is atomic; avoid emitting callbacks until all Actors are connected
2088   connectionList.push_back( ActorPtr( this ) );
2089
2090   // Recursively connect children
2091   if( mChildren )
2092   {
2093     ActorConstIter endIter = mChildren->end();
2094     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2095     {
2096       (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2097     }
2098   }
2099 }
2100
2101 /**
2102  * This method is called when the Actor is connected to the Stage.
2103  * The parent must have added its Node to the scene-graph.
2104  * The child must connect its Node to the parent's Node.
2105  * This is recursive; the child calls ConnectToStage() for its children.
2106  */
2107 void Actor::ConnectToSceneGraph()
2108 {
2109   DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2110
2111   if( NULL != mNode )
2112   {
2113     // Reparent Node in next Update
2114     ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2115   }
2116
2117   unsigned int rendererCount( GetRendererCount() );
2118   for( unsigned int i(0); i<rendererCount; ++i )
2119   {
2120     GetRendererAt(i)->Connect();
2121   }
2122
2123   // Request relayout on all actors that are added to the scenegraph
2124   RelayoutRequest();
2125
2126   // Notification for Object::Observers
2127   OnSceneObjectAdd();
2128 }
2129
2130 void Actor::NotifyStageConnection()
2131 {
2132   // Actors can be removed (in a callback), before the on-stage stage is reported.
2133   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2134   if( OnStage() && !mOnStageSignalled )
2135   {
2136     // Notification for external (CustomActor) derived classes
2137     OnStageConnectionExternal( mDepth );
2138
2139     if( !mOnStageSignal.Empty() )
2140     {
2141       Dali::Actor handle( this );
2142       mOnStageSignal.Emit( handle );
2143     }
2144
2145     // Guard against Remove during callbacks
2146     if( OnStage() )
2147     {
2148       mOnStageSignalled = true; // signal required next time Actor is removed
2149     }
2150   }
2151 }
2152
2153 void Actor::DisconnectFromStage()
2154 {
2155   // This container is used instead of walking the Actor hierachy.
2156   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2157   ActorContainer disconnectionList;
2158
2159   // This stage is atomic i.e. not interrupted by user callbacks
2160   RecursiveDisconnectFromStage( disconnectionList );
2161
2162   // Notify applications about the newly disconnected actors.
2163   const ActorIter endIter = disconnectionList.end();
2164   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2165   {
2166     (*iter)->NotifyStageDisconnection();
2167   }
2168 }
2169
2170 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2171 {
2172   DALI_ASSERT_ALWAYS( OnStage() );
2173
2174   // Recursively disconnect children
2175   if( mChildren )
2176   {
2177     ActorConstIter endIter = mChildren->end();
2178     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2179     {
2180       (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2181     }
2182   }
2183
2184   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2185   disconnectionList.push_back( ActorPtr( this ) );
2186
2187   // Notification for internal derived classes
2188   OnStageDisconnectionInternal();
2189
2190   DisconnectFromSceneGraph();
2191
2192   mIsOnStage = false;
2193 }
2194
2195 /**
2196  * This method is called by an actor or its parent, before a node removal message is sent.
2197  * This is recursive; the child calls DisconnectFromStage() for its children.
2198  */
2199 void Actor::DisconnectFromSceneGraph()
2200 {
2201   // Notification for Object::Observers
2202   OnSceneObjectRemove();
2203
2204   unsigned int rendererCount( GetRendererCount() );
2205   for( unsigned int i(0); i<rendererCount; ++i )
2206   {
2207     GetRendererAt(i)->Disconnect();
2208   }
2209 }
2210
2211 void Actor::NotifyStageDisconnection()
2212 {
2213   // Actors can be added (in a callback), before the off-stage state is reported.
2214   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2215   // only do this step if there is a stage, i.e. Core is not being shut down
2216   if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2217   {
2218     // Notification for external (CustomeActor) derived classes
2219     OnStageDisconnectionExternal();
2220
2221     if( !mOffStageSignal.Empty() )
2222     {
2223       Dali::Actor handle( this );
2224       mOffStageSignal.Emit( handle );
2225     }
2226
2227     // Guard against Add during callbacks
2228     if( !OnStage() )
2229     {
2230       mOnStageSignalled = false; // signal required next time Actor is added
2231     }
2232   }
2233 }
2234
2235 bool Actor::IsNodeConnected() const
2236 {
2237   bool connected( false );
2238
2239   if( OnStage() && ( NULL != mNode ) )
2240   {
2241     if( IsRoot() || mNode->GetParent() )
2242     {
2243       connected = true;
2244     }
2245   }
2246
2247   return connected;
2248 }
2249
2250 unsigned int Actor::GetDefaultPropertyCount() const
2251 {
2252   return DEFAULT_PROPERTY_COUNT;
2253 }
2254
2255 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2256 {
2257   indices.Reserve( DEFAULT_PROPERTY_COUNT );
2258
2259   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2260   {
2261     indices.PushBack( i );
2262   }
2263 }
2264
2265 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2266 {
2267   if( index < DEFAULT_PROPERTY_COUNT )
2268   {
2269     return DEFAULT_PROPERTY_DETAILS[ index ].name;
2270   }
2271
2272   return NULL;
2273 }
2274
2275 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2276 {
2277   Property::Index index = Property::INVALID_INDEX;
2278
2279   // Look for name in default properties
2280   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2281   {
2282     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2283     if( 0 == name.compare( property->name ) )
2284     {
2285       index = i;
2286       break;
2287     }
2288   }
2289
2290   return index;
2291 }
2292
2293 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2294 {
2295   if( index < DEFAULT_PROPERTY_COUNT )
2296   {
2297     return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2298   }
2299
2300   return false;
2301 }
2302
2303 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2304 {
2305   if( index < DEFAULT_PROPERTY_COUNT )
2306   {
2307     return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2308   }
2309
2310   return false;
2311 }
2312
2313 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2314 {
2315   if( index < DEFAULT_PROPERTY_COUNT )
2316   {
2317     return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2318   }
2319
2320   return false;
2321 }
2322
2323 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2324 {
2325   if( index < DEFAULT_PROPERTY_COUNT )
2326   {
2327     return DEFAULT_PROPERTY_DETAILS[ index ].type;
2328   }
2329
2330   // index out of range...return Property::NONE
2331   return Property::NONE;
2332 }
2333
2334 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2335 {
2336   switch( index )
2337   {
2338     case Dali::Actor::Property::PARENT_ORIGIN:
2339     {
2340       Property::Type type = property.GetType();
2341       if( type == Property::VECTOR3 )
2342       {
2343         SetParentOrigin( property.Get< Vector3 >() );
2344       }
2345       else if ( type == Property::STRING )
2346       {
2347         std::string parentOriginString;
2348         property.Get( parentOriginString );
2349         Vector3 parentOrigin;
2350         if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2351         {
2352           SetParentOrigin( parentOrigin );
2353         }
2354       }
2355       break;
2356     }
2357
2358     case Dali::Actor::Property::PARENT_ORIGIN_X:
2359     {
2360       SetParentOriginX( property.Get< float >() );
2361       break;
2362     }
2363
2364     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2365     {
2366       SetParentOriginY( property.Get< float >() );
2367       break;
2368     }
2369
2370     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2371     {
2372       SetParentOriginZ( property.Get< float >() );
2373       break;
2374     }
2375
2376     case Dali::Actor::Property::ANCHOR_POINT:
2377     {
2378       Property::Type type = property.GetType();
2379       if( type == Property::VECTOR3 )
2380       {
2381         SetAnchorPoint( property.Get< Vector3 >() );
2382       }
2383       else if ( type == Property::STRING )
2384       {
2385         std::string anchorPointString;
2386         property.Get( anchorPointString );
2387         Vector3 anchor;
2388         if( GetAnchorPointConstant( anchorPointString, anchor ) )
2389         {
2390           SetAnchorPoint( anchor );
2391         }
2392       }
2393       break;
2394     }
2395
2396     case Dali::Actor::Property::ANCHOR_POINT_X:
2397     {
2398       SetAnchorPointX( property.Get< float >() );
2399       break;
2400     }
2401
2402     case Dali::Actor::Property::ANCHOR_POINT_Y:
2403     {
2404       SetAnchorPointY( property.Get< float >() );
2405       break;
2406     }
2407
2408     case Dali::Actor::Property::ANCHOR_POINT_Z:
2409     {
2410       SetAnchorPointZ( property.Get< float >() );
2411       break;
2412     }
2413
2414     case Dali::Actor::Property::SIZE:
2415     {
2416       SetSize( property.Get< Vector3 >() );
2417       break;
2418     }
2419
2420     case Dali::Actor::Property::SIZE_WIDTH:
2421     {
2422       SetWidth( property.Get< float >() );
2423       break;
2424     }
2425
2426     case Dali::Actor::Property::SIZE_HEIGHT:
2427     {
2428       SetHeight( property.Get< float >() );
2429       break;
2430     }
2431
2432     case Dali::Actor::Property::SIZE_DEPTH:
2433     {
2434       SetDepth( property.Get< float >() );
2435       break;
2436     }
2437
2438     case Dali::Actor::Property::POSITION:
2439     {
2440       SetPosition( property.Get< Vector3 >() );
2441       break;
2442     }
2443
2444     case Dali::Actor::Property::POSITION_X:
2445     {
2446       SetX( property.Get< float >() );
2447       break;
2448     }
2449
2450     case Dali::Actor::Property::POSITION_Y:
2451     {
2452       SetY( property.Get< float >() );
2453       break;
2454     }
2455
2456     case Dali::Actor::Property::POSITION_Z:
2457     {
2458       SetZ( property.Get< float >() );
2459       break;
2460     }
2461
2462     case Dali::Actor::Property::ORIENTATION:
2463     {
2464       SetOrientation( property.Get< Quaternion >() );
2465       break;
2466     }
2467
2468     case Dali::Actor::Property::SCALE:
2469     {
2470       SetScale( property.Get< Vector3 >() );
2471       break;
2472     }
2473
2474     case Dali::Actor::Property::SCALE_X:
2475     {
2476       SetScaleX( property.Get< float >() );
2477       break;
2478     }
2479
2480     case Dali::Actor::Property::SCALE_Y:
2481     {
2482       SetScaleY( property.Get< float >() );
2483       break;
2484     }
2485
2486     case Dali::Actor::Property::SCALE_Z:
2487     {
2488       SetScaleZ( property.Get< float >() );
2489       break;
2490     }
2491
2492     case Dali::Actor::Property::VISIBLE:
2493     {
2494       SetVisible( property.Get< bool >() );
2495       break;
2496     }
2497
2498     case Dali::Actor::Property::COLOR:
2499     {
2500       SetColor( property.Get< Vector4 >() );
2501       break;
2502     }
2503
2504     case Dali::Actor::Property::COLOR_RED:
2505     {
2506       SetColorRed( property.Get< float >() );
2507       break;
2508     }
2509
2510     case Dali::Actor::Property::COLOR_GREEN:
2511     {
2512       SetColorGreen( property.Get< float >() );
2513       break;
2514     }
2515
2516     case Dali::Actor::Property::COLOR_BLUE:
2517     {
2518       SetColorBlue( property.Get< float >() );
2519       break;
2520     }
2521
2522     case Dali::Actor::Property::COLOR_ALPHA:
2523     {
2524       SetOpacity( property.Get< float >() );
2525       break;
2526     }
2527
2528     case Dali::Actor::Property::NAME:
2529     {
2530       SetName( property.Get< std::string >() );
2531       break;
2532     }
2533
2534     case Dali::Actor::Property::SENSITIVE:
2535     {
2536       SetSensitive( property.Get< bool >() );
2537       break;
2538     }
2539
2540     case Dali::Actor::Property::LEAVE_REQUIRED:
2541     {
2542       SetLeaveRequired( property.Get< bool >() );
2543       break;
2544     }
2545
2546     case Dali::Actor::Property::INHERIT_POSITION:
2547     {
2548       SetInheritPosition( property.Get< bool >() );
2549       break;
2550     }
2551
2552     case Dali::Actor::Property::INHERIT_ORIENTATION:
2553     {
2554       SetInheritOrientation( property.Get< bool >() );
2555       break;
2556     }
2557
2558     case Dali::Actor::Property::INHERIT_SCALE:
2559     {
2560       SetInheritScale( property.Get< bool >() );
2561       break;
2562     }
2563
2564     case Dali::Actor::Property::COLOR_MODE:
2565     {
2566       ColorMode mode = mColorMode;
2567       if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2568       {
2569         SetColorMode( mode );
2570       }
2571       break;
2572     }
2573
2574     case Dali::Actor::Property::POSITION_INHERITANCE:
2575     {
2576       PositionInheritanceMode mode = mPositionInheritanceMode;
2577       if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2578       {
2579         SetPositionInheritanceMode( mode );
2580       }
2581       break;
2582     }
2583
2584     case Dali::Actor::Property::DRAW_MODE:
2585     {
2586       DrawMode::Type mode = mDrawMode;
2587       if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2588       {
2589         SetDrawMode( mode );
2590       }
2591       break;
2592     }
2593
2594     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2595     {
2596       SetSizeModeFactor( property.Get< Vector3 >() );
2597       break;
2598     }
2599
2600     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2601     {
2602       ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2603       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2604       {
2605         SetResizePolicy( type, Dimension::WIDTH );
2606       }
2607       break;
2608     }
2609
2610     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2611     {
2612       ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2613       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2614       {
2615         SetResizePolicy( type, Dimension::HEIGHT );
2616       }
2617       break;
2618     }
2619
2620     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2621     {
2622       SizeScalePolicy::Type type;
2623       if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2624       {
2625         SetSizeScalePolicy( type );
2626       }
2627       break;
2628     }
2629
2630     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2631     {
2632       if( property.Get< bool >() )
2633       {
2634         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2635       }
2636       break;
2637     }
2638
2639     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2640     {
2641       if( property.Get< bool >() )
2642       {
2643         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2644       }
2645       break;
2646     }
2647
2648     case Dali::Actor::Property::PADDING:
2649     {
2650       Vector4 padding = property.Get< Vector4 >();
2651       SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2652       SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2653       break;
2654     }
2655
2656     case Dali::Actor::Property::MINIMUM_SIZE:
2657     {
2658       Vector2 size = property.Get< Vector2 >();
2659       SetMinimumSize( size.x, Dimension::WIDTH );
2660       SetMinimumSize( size.y, Dimension::HEIGHT );
2661       break;
2662     }
2663
2664     case Dali::Actor::Property::MAXIMUM_SIZE:
2665     {
2666       Vector2 size = property.Get< Vector2 >();
2667       SetMaximumSize( size.x, Dimension::WIDTH );
2668       SetMaximumSize( size.y, Dimension::HEIGHT );
2669       break;
2670     }
2671
2672     case Dali::DevelActor::Property::BATCH_PARENT:
2673     {
2674       bool value;
2675
2676       if( property.Get( value ) )
2677       {
2678         if( value != mIsBatchParent )
2679         {
2680           mIsBatchParent = value;
2681           SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2682         }
2683       }
2684       break;
2685     }
2686
2687     case Dali::DevelActor::Property::SIBLING_ORDER:
2688     {
2689       int value;
2690
2691       if( property.Get( value ) )
2692       {
2693         if( static_cast<unsigned int>(value) != mSiblingOrder )
2694         {
2695           mSiblingOrder = value;
2696           if( mIsOnStage )
2697           {
2698             SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2699           }
2700         }
2701       }
2702       break;
2703     }
2704
2705     case Dali::Actor::Property::CLIPPING_MODE:
2706     {
2707       ClippingMode::Type convertedValue = mClippingMode;
2708       if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2709       {
2710         mClippingMode = convertedValue;
2711         if( NULL != mNode )
2712         {
2713           SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2714         }
2715       }
2716       break;
2717     }
2718
2719     default:
2720     {
2721       // this can happen in the case of a non-animatable default property so just do nothing
2722       break;
2723     }
2724   }
2725 }
2726
2727 // TODO: This method needs to be removed
2728 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2729 {
2730   switch( entry.GetType() )
2731   {
2732     case Property::BOOLEAN:
2733     {
2734       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2735       DALI_ASSERT_DEBUG( NULL != property );
2736
2737       // property is being used in a separate thread; queue a message to set the property
2738       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2739
2740       break;
2741     }
2742
2743     case Property::INTEGER:
2744     {
2745       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2746       DALI_ASSERT_DEBUG( NULL != property );
2747
2748       // property is being used in a separate thread; queue a message to set the property
2749       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2750
2751       break;
2752     }
2753
2754     case Property::FLOAT:
2755     {
2756       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2757       DALI_ASSERT_DEBUG( NULL != property );
2758
2759       // property is being used in a separate thread; queue a message to set the property
2760       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2761
2762       break;
2763     }
2764
2765     case Property::VECTOR2:
2766     {
2767       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2768       DALI_ASSERT_DEBUG( NULL != property );
2769
2770       // property is being used in a separate thread; queue a message to set the property
2771       if(entry.componentIndex == 0)
2772       {
2773         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2774       }
2775       else if(entry.componentIndex == 1)
2776       {
2777         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2778       }
2779       else
2780       {
2781         SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2782       }
2783
2784       break;
2785     }
2786
2787     case Property::VECTOR3:
2788     {
2789       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2790       DALI_ASSERT_DEBUG( NULL != property );
2791
2792       // property is being used in a separate thread; queue a message to set the property
2793       if(entry.componentIndex == 0)
2794       {
2795         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2796       }
2797       else if(entry.componentIndex == 1)
2798       {
2799         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2800       }
2801       else if(entry.componentIndex == 2)
2802       {
2803         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2804       }
2805       else
2806       {
2807         SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2808       }
2809
2810       break;
2811     }
2812
2813     case Property::VECTOR4:
2814     {
2815       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2816       DALI_ASSERT_DEBUG( NULL != property );
2817
2818       // property is being used in a separate thread; queue a message to set the property
2819       if(entry.componentIndex == 0)
2820       {
2821         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2822       }
2823       else if(entry.componentIndex == 1)
2824       {
2825         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2826       }
2827       else if(entry.componentIndex == 2)
2828       {
2829         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2830       }
2831       else if(entry.componentIndex == 3)
2832       {
2833         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2834       }
2835       else
2836       {
2837         SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2838       }
2839
2840       break;
2841     }
2842
2843     case Property::ROTATION:
2844     {
2845       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2846       DALI_ASSERT_DEBUG( NULL != property );
2847
2848       // property is being used in a separate thread; queue a message to set the property
2849       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
2850
2851       break;
2852     }
2853
2854     case Property::MATRIX:
2855     {
2856       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2857       DALI_ASSERT_DEBUG( NULL != property );
2858
2859       // property is being used in a separate thread; queue a message to set the property
2860       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
2861
2862       break;
2863     }
2864
2865     case Property::MATRIX3:
2866     {
2867       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2868       DALI_ASSERT_DEBUG( NULL != property );
2869
2870       // property is being used in a separate thread; queue a message to set the property
2871       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
2872
2873       break;
2874     }
2875
2876     default:
2877     {
2878       // nothing to do for other types
2879     }
2880   } // entry.GetType
2881 }
2882
2883 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2884 {
2885   Property::Value value;
2886
2887   if( index >= DEFAULT_PROPERTY_COUNT )
2888   {
2889     return value;
2890   }
2891
2892   switch( index )
2893   {
2894     case Dali::Actor::Property::PARENT_ORIGIN:
2895     {
2896       value = GetCurrentParentOrigin();
2897       break;
2898     }
2899
2900     case Dali::Actor::Property::PARENT_ORIGIN_X:
2901     {
2902       value = GetCurrentParentOrigin().x;
2903       break;
2904     }
2905
2906     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2907     {
2908       value = GetCurrentParentOrigin().y;
2909       break;
2910     }
2911
2912     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2913     {
2914       value = GetCurrentParentOrigin().z;
2915       break;
2916     }
2917
2918     case Dali::Actor::Property::ANCHOR_POINT:
2919     {
2920       value = GetCurrentAnchorPoint();
2921       break;
2922     }
2923
2924     case Dali::Actor::Property::ANCHOR_POINT_X:
2925     {
2926       value = GetCurrentAnchorPoint().x;
2927       break;
2928     }
2929
2930     case Dali::Actor::Property::ANCHOR_POINT_Y:
2931     {
2932       value = GetCurrentAnchorPoint().y;
2933       break;
2934     }
2935
2936     case Dali::Actor::Property::ANCHOR_POINT_Z:
2937     {
2938       value = GetCurrentAnchorPoint().z;
2939       break;
2940     }
2941
2942     case Dali::Actor::Property::SIZE:
2943     {
2944       value = GetTargetSize();
2945       break;
2946     }
2947
2948     case Dali::Actor::Property::SIZE_WIDTH:
2949     {
2950       value = GetTargetSize().width;
2951       break;
2952     }
2953
2954     case Dali::Actor::Property::SIZE_HEIGHT:
2955     {
2956       value = GetTargetSize().height;
2957       break;
2958     }
2959
2960     case Dali::Actor::Property::SIZE_DEPTH:
2961     {
2962       value = GetTargetSize().depth;
2963       break;
2964     }
2965
2966     case Dali::Actor::Property::POSITION:
2967     {
2968       value = GetTargetPosition();
2969       break;
2970     }
2971
2972     case Dali::Actor::Property::POSITION_X:
2973     {
2974       value = GetTargetPosition().x;
2975       break;
2976     }
2977
2978     case Dali::Actor::Property::POSITION_Y:
2979     {
2980       value = GetTargetPosition().y;
2981       break;
2982     }
2983
2984     case Dali::Actor::Property::POSITION_Z:
2985     {
2986       value = GetTargetPosition().z;
2987       break;
2988     }
2989
2990     case Dali::Actor::Property::WORLD_POSITION:
2991     {
2992       value = GetCurrentWorldPosition();
2993       break;
2994     }
2995
2996     case Dali::Actor::Property::WORLD_POSITION_X:
2997     {
2998       value = GetCurrentWorldPosition().x;
2999       break;
3000     }
3001
3002     case Dali::Actor::Property::WORLD_POSITION_Y:
3003     {
3004       value = GetCurrentWorldPosition().y;
3005       break;
3006     }
3007
3008     case Dali::Actor::Property::WORLD_POSITION_Z:
3009     {
3010       value = GetCurrentWorldPosition().z;
3011       break;
3012     }
3013
3014     case Dali::Actor::Property::ORIENTATION:
3015     {
3016       value = GetCurrentOrientation();
3017       break;
3018     }
3019
3020     case Dali::Actor::Property::WORLD_ORIENTATION:
3021     {
3022       value = GetCurrentWorldOrientation();
3023       break;
3024     }
3025
3026     case Dali::Actor::Property::SCALE:
3027     {
3028       value = GetCurrentScale();
3029       break;
3030     }
3031
3032     case Dali::Actor::Property::SCALE_X:
3033     {
3034       value = GetCurrentScale().x;
3035       break;
3036     }
3037
3038     case Dali::Actor::Property::SCALE_Y:
3039     {
3040       value = GetCurrentScale().y;
3041       break;
3042     }
3043
3044     case Dali::Actor::Property::SCALE_Z:
3045     {
3046       value = GetCurrentScale().z;
3047       break;
3048     }
3049
3050     case Dali::Actor::Property::WORLD_SCALE:
3051     {
3052       value = GetCurrentWorldScale();
3053       break;
3054     }
3055
3056     case Dali::Actor::Property::VISIBLE:
3057     {
3058       value = IsVisible();
3059       break;
3060     }
3061
3062     case Dali::Actor::Property::COLOR:
3063     {
3064       value = GetCurrentColor();
3065       break;
3066     }
3067
3068     case Dali::Actor::Property::COLOR_RED:
3069     {
3070       value = GetCurrentColor().r;
3071       break;
3072     }
3073
3074     case Dali::Actor::Property::COLOR_GREEN:
3075     {
3076       value = GetCurrentColor().g;
3077       break;
3078     }
3079
3080     case Dali::Actor::Property::COLOR_BLUE:
3081     {
3082       value = GetCurrentColor().b;
3083       break;
3084     }
3085
3086     case Dali::Actor::Property::COLOR_ALPHA:
3087     {
3088       value = GetCurrentColor().a;
3089       break;
3090     }
3091
3092     case Dali::Actor::Property::WORLD_COLOR:
3093     {
3094       value = GetCurrentWorldColor();
3095       break;
3096     }
3097
3098     case Dali::Actor::Property::WORLD_MATRIX:
3099     {
3100       value = GetCurrentWorldMatrix();
3101       break;
3102     }
3103
3104     case Dali::Actor::Property::NAME:
3105     {
3106       value = GetName();
3107       break;
3108     }
3109
3110     case Dali::Actor::Property::SENSITIVE:
3111     {
3112       value = IsSensitive();
3113       break;
3114     }
3115
3116     case Dali::Actor::Property::LEAVE_REQUIRED:
3117     {
3118       value = GetLeaveRequired();
3119       break;
3120     }
3121
3122     case Dali::Actor::Property::INHERIT_POSITION:
3123     {
3124       value = IsPositionInherited();
3125       break;
3126     }
3127
3128     case Dali::Actor::Property::INHERIT_ORIENTATION:
3129     {
3130       value = IsOrientationInherited();
3131       break;
3132     }
3133
3134     case Dali::Actor::Property::INHERIT_SCALE:
3135     {
3136       value = IsScaleInherited();
3137       break;
3138     }
3139
3140     case Dali::Actor::Property::COLOR_MODE:
3141     {
3142       value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3143       break;
3144     }
3145
3146     case Dali::Actor::Property::POSITION_INHERITANCE:
3147     {
3148       value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3149       break;
3150     }
3151
3152     case Dali::Actor::Property::DRAW_MODE:
3153     {
3154       value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3155       break;
3156     }
3157
3158     case Dali::Actor::Property::SIZE_MODE_FACTOR:
3159     {
3160       value = GetSizeModeFactor();
3161       break;
3162     }
3163
3164     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3165     {
3166       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3167       break;
3168     }
3169
3170     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3171     {
3172       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3173       break;
3174     }
3175
3176     case Dali::Actor::Property::SIZE_SCALE_POLICY:
3177     {
3178       value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3179       break;
3180     }
3181
3182     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3183     {
3184       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3185       break;
3186     }
3187
3188     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3189     {
3190       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3191       break;
3192     }
3193
3194     case Dali::Actor::Property::PADDING:
3195     {
3196       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3197       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3198       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3199       break;
3200     }
3201
3202     case Dali::Actor::Property::MINIMUM_SIZE:
3203     {
3204       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3205       break;
3206     }
3207
3208     case Dali::Actor::Property::MAXIMUM_SIZE:
3209     {
3210       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3211       break;
3212     }
3213
3214     case Dali::DevelActor::Property::BATCH_PARENT:
3215     {
3216       value = mIsBatchParent;
3217       break;
3218     }
3219
3220     case Dali::DevelActor::Property::SIBLING_ORDER:
3221     {
3222       value = static_cast<int>(mSiblingOrder);
3223       break;
3224     }
3225
3226     case Dali::Actor::Property::CLIPPING_MODE:
3227     {
3228       value = mClippingMode;
3229       break;
3230     }
3231   }
3232
3233   return value;
3234 }
3235
3236 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3237 {
3238   return mNode;
3239 }
3240
3241 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3242 {
3243   // This method should only return an object connected to the scene-graph
3244   return OnStage() ? mNode : NULL;
3245 }
3246
3247 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3248 {
3249   DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3250
3251   const PropertyBase* property( NULL );
3252
3253   // This method should only return a property of an object connected to the scene-graph
3254   if( !OnStage() )
3255   {
3256     return property;
3257   }
3258
3259   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3260   {
3261     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3262     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3263
3264     property = animatable->GetSceneGraphProperty();
3265   }
3266   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3267             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3268   {
3269     CustomPropertyMetadata* custom = FindCustomProperty( index );
3270     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3271
3272     property = custom->GetSceneGraphProperty();
3273   }
3274   else if( NULL != mNode )
3275   {
3276     switch( index )
3277     {
3278       case Dali::Actor::Property::SIZE:
3279         property = &mNode->mSize;
3280         break;
3281
3282       case Dali::Actor::Property::SIZE_WIDTH:
3283         property = &mNode->mSize;
3284         break;
3285
3286       case Dali::Actor::Property::SIZE_HEIGHT:
3287         property = &mNode->mSize;
3288         break;
3289
3290       case Dali::Actor::Property::SIZE_DEPTH:
3291         property = &mNode->mSize;
3292         break;
3293
3294       case Dali::Actor::Property::POSITION:
3295         property = &mNode->mPosition;
3296         break;
3297
3298       case Dali::Actor::Property::POSITION_X:
3299         property = &mNode->mPosition;
3300         break;
3301
3302       case Dali::Actor::Property::POSITION_Y:
3303         property = &mNode->mPosition;
3304         break;
3305
3306       case Dali::Actor::Property::POSITION_Z:
3307         property = &mNode->mPosition;
3308         break;
3309
3310       case Dali::Actor::Property::ORIENTATION:
3311         property = &mNode->mOrientation;
3312         break;
3313
3314       case Dali::Actor::Property::SCALE:
3315         property = &mNode->mScale;
3316         break;
3317
3318       case Dali::Actor::Property::SCALE_X:
3319         property = &mNode->mScale;
3320         break;
3321
3322       case Dali::Actor::Property::SCALE_Y:
3323         property = &mNode->mScale;
3324         break;
3325
3326       case Dali::Actor::Property::SCALE_Z:
3327         property = &mNode->mScale;
3328         break;
3329
3330       case Dali::Actor::Property::VISIBLE:
3331         property = &mNode->mVisible;
3332         break;
3333
3334       case Dali::Actor::Property::COLOR:
3335         property = &mNode->mColor;
3336         break;
3337
3338       case Dali::Actor::Property::COLOR_RED:
3339         property = &mNode->mColor;
3340         break;
3341
3342       case Dali::Actor::Property::COLOR_GREEN:
3343         property = &mNode->mColor;
3344         break;
3345
3346       case Dali::Actor::Property::COLOR_BLUE:
3347         property = &mNode->mColor;
3348         break;
3349
3350       case Dali::Actor::Property::COLOR_ALPHA:
3351         property = &mNode->mColor;
3352         break;
3353
3354       default:
3355         break;
3356     }
3357   }
3358
3359   return property;
3360 }
3361
3362 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3363 {
3364   const PropertyInputImpl* property( NULL );
3365
3366   // This method should only return a property of an object connected to the scene-graph
3367   if( !OnStage() )
3368   {
3369     return property;
3370   }
3371
3372   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3373   {
3374     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3375     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3376
3377     property = animatable->GetSceneGraphProperty();
3378   }
3379   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3380             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3381   {
3382     CustomPropertyMetadata* custom = FindCustomProperty( index );
3383     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3384     property = custom->GetSceneGraphProperty();
3385   }
3386   else if( NULL != mNode )
3387   {
3388     switch( index )
3389     {
3390       case Dali::Actor::Property::PARENT_ORIGIN:
3391         property = &mNode->mParentOrigin;
3392         break;
3393
3394       case Dali::Actor::Property::PARENT_ORIGIN_X:
3395         property = &mNode->mParentOrigin;
3396         break;
3397
3398       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3399         property = &mNode->mParentOrigin;
3400         break;
3401
3402       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3403         property = &mNode->mParentOrigin;
3404         break;
3405
3406       case Dali::Actor::Property::ANCHOR_POINT:
3407         property = &mNode->mAnchorPoint;
3408         break;
3409
3410       case Dali::Actor::Property::ANCHOR_POINT_X:
3411         property = &mNode->mAnchorPoint;
3412         break;
3413
3414       case Dali::Actor::Property::ANCHOR_POINT_Y:
3415         property = &mNode->mAnchorPoint;
3416         break;
3417
3418       case Dali::Actor::Property::ANCHOR_POINT_Z:
3419         property = &mNode->mAnchorPoint;
3420         break;
3421
3422       case Dali::Actor::Property::SIZE:
3423         property = &mNode->mSize;
3424         break;
3425
3426       case Dali::Actor::Property::SIZE_WIDTH:
3427         property = &mNode->mSize;
3428         break;
3429
3430       case Dali::Actor::Property::SIZE_HEIGHT:
3431         property = &mNode->mSize;
3432         break;
3433
3434       case Dali::Actor::Property::SIZE_DEPTH:
3435         property = &mNode->mSize;
3436         break;
3437
3438       case Dali::Actor::Property::POSITION:
3439         property = &mNode->mPosition;
3440         break;
3441
3442       case Dali::Actor::Property::POSITION_X:
3443         property = &mNode->mPosition;
3444         break;
3445
3446       case Dali::Actor::Property::POSITION_Y:
3447         property = &mNode->mPosition;
3448         break;
3449
3450       case Dali::Actor::Property::POSITION_Z:
3451         property = &mNode->mPosition;
3452         break;
3453
3454       case Dali::Actor::Property::WORLD_POSITION:
3455         property = &mNode->mWorldPosition;
3456         break;
3457
3458       case Dali::Actor::Property::WORLD_POSITION_X:
3459         property = &mNode->mWorldPosition;
3460         break;
3461
3462       case Dali::Actor::Property::WORLD_POSITION_Y:
3463         property = &mNode->mWorldPosition;
3464         break;
3465
3466       case Dali::Actor::Property::WORLD_POSITION_Z:
3467         property = &mNode->mWorldPosition;
3468         break;
3469
3470       case Dali::Actor::Property::ORIENTATION:
3471         property = &mNode->mOrientation;
3472         break;
3473
3474       case Dali::Actor::Property::WORLD_ORIENTATION:
3475         property = &mNode->mWorldOrientation;
3476         break;
3477
3478       case Dali::Actor::Property::SCALE:
3479         property = &mNode->mScale;
3480         break;
3481
3482       case Dali::Actor::Property::SCALE_X:
3483         property = &mNode->mScale;
3484         break;
3485
3486       case Dali::Actor::Property::SCALE_Y:
3487         property = &mNode->mScale;
3488         break;
3489
3490       case Dali::Actor::Property::SCALE_Z:
3491         property = &mNode->mScale;
3492         break;
3493
3494       case Dali::Actor::Property::WORLD_SCALE:
3495         property = &mNode->mWorldScale;
3496         break;
3497
3498       case Dali::Actor::Property::VISIBLE:
3499         property = &mNode->mVisible;
3500         break;
3501
3502       case Dali::Actor::Property::COLOR:
3503         property = &mNode->mColor;
3504         break;
3505
3506       case Dali::Actor::Property::COLOR_RED:
3507         property = &mNode->mColor;
3508         break;
3509
3510       case Dali::Actor::Property::COLOR_GREEN:
3511         property = &mNode->mColor;
3512         break;
3513
3514       case Dali::Actor::Property::COLOR_BLUE:
3515         property = &mNode->mColor;
3516         break;
3517
3518       case Dali::Actor::Property::COLOR_ALPHA:
3519         property = &mNode->mColor;
3520         break;
3521
3522       case Dali::Actor::Property::WORLD_COLOR:
3523         property = &mNode->mWorldColor;
3524         break;
3525
3526       case Dali::Actor::Property::WORLD_MATRIX:
3527         property = &mNode->mWorldMatrix;
3528         break;
3529
3530       default:
3531         break;
3532     }
3533   }
3534
3535   return property;
3536 }
3537
3538 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3539 {
3540   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3541
3542   if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3543   {
3544     // check whether the animatable property is registered already, if not then register one.
3545     AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3546     if( animatableProperty )
3547     {
3548       componentIndex = animatableProperty->componentIndex;
3549     }
3550   }
3551   else
3552   {
3553     switch( index )
3554     {
3555       case Dali::Actor::Property::PARENT_ORIGIN_X:
3556       case Dali::Actor::Property::ANCHOR_POINT_X:
3557       case Dali::Actor::Property::SIZE_WIDTH:
3558       case Dali::Actor::Property::POSITION_X:
3559       case Dali::Actor::Property::WORLD_POSITION_X:
3560       case Dali::Actor::Property::SCALE_X:
3561       case Dali::Actor::Property::COLOR_RED:
3562       {
3563         componentIndex = 0;
3564         break;
3565       }
3566
3567       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3568       case Dali::Actor::Property::ANCHOR_POINT_Y:
3569       case Dali::Actor::Property::SIZE_HEIGHT:
3570       case Dali::Actor::Property::POSITION_Y:
3571       case Dali::Actor::Property::WORLD_POSITION_Y:
3572       case Dali::Actor::Property::SCALE_Y:
3573       case Dali::Actor::Property::COLOR_GREEN:
3574       {
3575         componentIndex = 1;
3576         break;
3577       }
3578
3579       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3580       case Dali::Actor::Property::ANCHOR_POINT_Z:
3581       case Dali::Actor::Property::SIZE_DEPTH:
3582       case Dali::Actor::Property::POSITION_Z:
3583       case Dali::Actor::Property::WORLD_POSITION_Z:
3584       case Dali::Actor::Property::SCALE_Z:
3585       case Dali::Actor::Property::COLOR_BLUE:
3586       {
3587         componentIndex = 2;
3588         break;
3589       }
3590
3591       case Dali::Actor::Property::COLOR_ALPHA:
3592       {
3593         componentIndex = 3;
3594         break;
3595       }
3596
3597       default:
3598       {
3599         // Do nothing
3600         break;
3601       }
3602     }
3603   }
3604
3605   return componentIndex;
3606 }
3607
3608 void Actor::SetParent( Actor* parent )
3609 {
3610   if( parent )
3611   {
3612     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3613
3614     mParent = parent;
3615
3616     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3617          parent->OnStage() )
3618     {
3619       // Instruct each actor to create a corresponding node in the scene graph
3620       ConnectToStage( parent->GetHierarchyDepth() );
3621     }
3622
3623     // Resolve the name and index for the child properties if any
3624     ResolveChildProperties();
3625   }
3626   else // parent being set to NULL
3627   {
3628     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3629
3630     mParent = NULL;
3631
3632     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3633          OnStage() )
3634     {
3635       DALI_ASSERT_ALWAYS( mNode != NULL );
3636
3637       if( NULL != mNode )
3638       {
3639         // Disconnect the Node & its children from the scene-graph.
3640         DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3641       }
3642
3643       // Instruct each actor to discard pointers to the scene-graph
3644       DisconnectFromStage();
3645     }
3646   }
3647 }
3648
3649 SceneGraph::Node* Actor::CreateNode() const
3650 {
3651   return Node::New();
3652 }
3653
3654 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3655 {
3656   bool done = false;
3657   Actor* actor = dynamic_cast< Actor* >( object );
3658
3659   if( actor )
3660   {
3661     if( 0 == actionName.compare( ACTION_SHOW ) )
3662     {
3663       actor->SetVisible( true );
3664       done = true;
3665     }
3666     else if( 0 == actionName.compare( ACTION_HIDE ) )
3667     {
3668       actor->SetVisible( false );
3669       done = true;
3670     }
3671   }
3672
3673   return done;
3674 }
3675
3676 void Actor::EnsureRelayoutData()
3677 {
3678   // Assign relayout data.
3679   if( !mRelayoutData )
3680   {
3681     mRelayoutData = new RelayoutData();
3682   }
3683 }
3684
3685 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3686 {
3687   // Check if actor is dependent on parent
3688   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3689   {
3690     if( ( dimension & ( 1 << i ) ) )
3691     {
3692       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3693       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3694       {
3695         return true;
3696       }
3697     }
3698   }
3699
3700   return false;
3701 }
3702
3703 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3704 {
3705   // Check if actor is dependent on children
3706   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3707   {
3708     if( ( dimension & ( 1 << i ) ) )
3709     {
3710       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3711       switch( resizePolicy )
3712       {
3713         case ResizePolicy::FIT_TO_CHILDREN:
3714         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
3715         {
3716           return true;
3717         }
3718
3719         default:
3720         {
3721           break;
3722         }
3723       }
3724     }
3725   }
3726
3727   return false;
3728 }
3729
3730 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3731 {
3732   return Actor::RelayoutDependentOnChildren( dimension );
3733 }
3734
3735 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3736 {
3737   // Check each possible dimension and see if it is dependent on the input one
3738   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3739   {
3740     if( dimension & ( 1 << i ) )
3741     {
3742       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3743     }
3744   }
3745
3746   return false;
3747 }
3748
3749 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3750 {
3751   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3752   {
3753     if( dimension & ( 1 << i ) )
3754     {
3755       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3756     }
3757   }
3758 }
3759
3760 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3761 {
3762   // If more than one dimension is requested, just return the first one found
3763   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3764   {
3765     if( ( dimension & ( 1 << i ) ) )
3766     {
3767       return mRelayoutData->negotiatedDimensions[ i ];
3768     }
3769   }
3770
3771   return 0.0f;   // Default
3772 }
3773
3774 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3775 {
3776   EnsureRelayoutData();
3777
3778   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3779   {
3780     if( dimension & ( 1 << i ) )
3781     {
3782       mRelayoutData->dimensionPadding[ i ] = padding;
3783     }
3784   }
3785 }
3786
3787 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3788 {
3789   if ( mRelayoutData )
3790   {
3791     // If more than one dimension is requested, just return the first one found
3792     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3793     {
3794       if( ( dimension & ( 1 << i ) ) )
3795       {
3796         return mRelayoutData->dimensionPadding[ i ];
3797       }
3798     }
3799   }
3800
3801   return GetDefaultDimensionPadding();
3802 }
3803
3804 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3805 {
3806   EnsureRelayoutData();
3807
3808   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3809   {
3810     if( dimension & ( 1 << i ) )
3811     {
3812       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3813     }
3814   }
3815 }
3816
3817 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3818 {
3819   if ( mRelayoutData )
3820   {
3821     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3822     {
3823       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3824       {
3825         return true;
3826       }
3827     }
3828   }
3829
3830   return false;
3831 }
3832
3833 float Actor::GetHeightForWidthBase( float width )
3834 {
3835   float height = 0.0f;
3836
3837   const Vector3 naturalSize = GetNaturalSize();
3838   if( naturalSize.width > 0.0f )
3839   {
3840     height = naturalSize.height * width / naturalSize.width;
3841   }
3842   else // we treat 0 as 1:1 aspect ratio
3843   {
3844     height = width;
3845   }
3846
3847   return height;
3848 }
3849
3850 float Actor::GetWidthForHeightBase( float height )
3851 {
3852   float width = 0.0f;
3853
3854   const Vector3 naturalSize = GetNaturalSize();
3855   if( naturalSize.height > 0.0f )
3856   {
3857     width = naturalSize.width * height / naturalSize.height;
3858   }
3859   else // we treat 0 as 1:1 aspect ratio
3860   {
3861     width = height;
3862   }
3863
3864   return width;
3865 }
3866
3867 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3868 {
3869   // Fill to parent, taking size mode factor into account
3870   switch( child.GetResizePolicy( dimension ) )
3871   {
3872     case ResizePolicy::FILL_TO_PARENT:
3873     {
3874       return GetLatestSize( dimension );
3875     }
3876
3877     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3878     {
3879       return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3880     }
3881
3882     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3883     {
3884       return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3885     }
3886
3887     default:
3888     {
3889       return GetLatestSize( dimension );
3890     }
3891   }
3892 }
3893
3894 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3895 {
3896   // Can be overridden in derived class
3897   return CalculateChildSizeBase( child, dimension );
3898 }
3899
3900 float Actor::GetHeightForWidth( float width )
3901 {
3902   // Can be overridden in derived class
3903   return GetHeightForWidthBase( width );
3904 }
3905
3906 float Actor::GetWidthForHeight( float height )
3907 {
3908   // Can be overridden in derived class
3909   return GetWidthForHeightBase( height );
3910 }
3911
3912 float Actor::GetLatestSize( Dimension::Type dimension ) const
3913 {
3914   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3915 }
3916
3917 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3918 {
3919   Vector2 padding = GetPadding( dimension );
3920
3921   return GetLatestSize( dimension ) + padding.x + padding.y;
3922 }
3923
3924 float Actor::NegotiateFromParent( Dimension::Type dimension )
3925 {
3926   Actor* parent = GetParent();
3927   if( parent )
3928   {
3929     Vector2 padding( GetPadding( dimension ) );
3930     Vector2 parentPadding( parent->GetPadding( dimension ) );
3931     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3932   }
3933
3934   return 0.0f;
3935 }
3936
3937 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3938 {
3939   float maxDimensionPoint = 0.0f;
3940
3941   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3942   {
3943     ActorPtr child = GetChildAt( i );
3944
3945     if( !child->RelayoutDependentOnParent( dimension ) )
3946     {
3947       // Calculate the min and max points that the children range across
3948       float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3949       float dimensionSize = child->GetRelayoutSize( dimension );
3950       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3951     }
3952   }
3953
3954   return maxDimensionPoint;
3955 }
3956
3957 float Actor::GetSize( Dimension::Type dimension ) const
3958 {
3959   return GetDimensionValue( GetTargetSize(), dimension );
3960 }
3961
3962 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3963 {
3964   return GetDimensionValue( GetNaturalSize(), dimension );
3965 }
3966
3967 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3968 {
3969   switch( GetResizePolicy( dimension ) )
3970   {
3971     case ResizePolicy::USE_NATURAL_SIZE:
3972     {
3973       return GetNaturalSize( dimension );
3974     }
3975
3976     case ResizePolicy::FIXED:
3977     {
3978       return GetDimensionValue( GetPreferredSize(), dimension );
3979     }
3980
3981     case ResizePolicy::USE_ASSIGNED_SIZE:
3982     {
3983       return GetDimensionValue( maximumSize, dimension );
3984     }
3985
3986     case ResizePolicy::FILL_TO_PARENT:
3987     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3988     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3989     {
3990       return NegotiateFromParent( dimension );
3991     }
3992
3993     case ResizePolicy::FIT_TO_CHILDREN:
3994     {
3995       return NegotiateFromChildren( dimension );
3996     }
3997
3998     case ResizePolicy::DIMENSION_DEPENDENCY:
3999     {
4000       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4001
4002       // Custom rules
4003       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4004       {
4005         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4006       }
4007
4008       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4009       {
4010         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4011       }
4012
4013       break;
4014     }
4015
4016     default:
4017     {
4018       break;
4019     }
4020   }
4021
4022   return 0.0f;  // Default
4023 }
4024
4025 float Actor::ClampDimension( float size, Dimension::Type dimension )
4026 {
4027   const float minSize = GetMinimumSize( dimension );
4028   const float maxSize = GetMaximumSize( dimension );
4029
4030   return std::max( minSize, std::min( size, maxSize ) );
4031 }
4032
4033 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4034 {
4035   // Check if it needs to be negotiated
4036   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4037   {
4038     // Check that we havn't gotten into an infinite loop
4039     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4040     bool recursionFound = false;
4041     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4042     {
4043       if( *it == searchActor )
4044       {
4045         recursionFound = true;
4046         break;
4047       }
4048     }
4049
4050     if( !recursionFound )
4051     {
4052       // Record the path that we have taken
4053       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4054
4055       // Dimension dependency check
4056       for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4057       {
4058         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4059
4060         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4061         {
4062           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4063         }
4064       }
4065
4066       // Parent dependency check
4067       Actor* parent = GetParent();
4068       if( parent && RelayoutDependentOnParent( dimension ) )
4069       {
4070         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4071       }
4072
4073       // Children dependency check
4074       if( RelayoutDependentOnChildren( dimension ) )
4075       {
4076         for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4077         {
4078           ActorPtr child = GetChildAt( i );
4079
4080           // Only relayout child first if it is not dependent on this actor
4081           if( !child->RelayoutDependentOnParent( dimension ) )
4082           {
4083             child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4084           }
4085         }
4086       }
4087
4088       // For deriving classes
4089       OnCalculateRelayoutSize( dimension );
4090
4091       // All dependencies checked, calculate the size and set negotiated flag
4092       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4093
4094       SetNegotiatedDimension( newSize, dimension );
4095       SetLayoutNegotiated( true, dimension );
4096
4097       // For deriving classes
4098       OnLayoutNegotiated( newSize, dimension );
4099
4100       // This actor has been successfully processed, pop it off the recursion stack
4101       recursionStack.pop_back();
4102     }
4103     else
4104     {
4105       // TODO: Break infinite loop
4106       SetLayoutNegotiated( true, dimension );
4107     }
4108   }
4109 }
4110
4111 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4112 {
4113   // Negotiate all dimensions that require it
4114   ActorDimensionStack recursionStack;
4115
4116   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4117   {
4118     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4119
4120     // Negotiate
4121     NegotiateDimension( dimension, allocatedSize, recursionStack );
4122   }
4123 }
4124
4125 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4126 {
4127   switch( mRelayoutData->sizeSetPolicy )
4128   {
4129     case SizeScalePolicy::USE_SIZE_SET:
4130     {
4131       return size;
4132     }
4133
4134     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4135     {
4136       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4137       const Vector3 naturalSize = GetNaturalSize();
4138       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4139       {
4140         const float sizeRatio = size.width / size.height;
4141         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4142
4143         if( naturalSizeRatio < sizeRatio )
4144         {
4145           return Vector2( naturalSizeRatio * size.height, size.height );
4146         }
4147         else if( naturalSizeRatio > sizeRatio )
4148         {
4149           return Vector2( size.width, size.width / naturalSizeRatio );
4150         }
4151         else
4152         {
4153           return size;
4154         }
4155       }
4156
4157       break;
4158     }
4159
4160     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4161     {
4162       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4163       const Vector3 naturalSize = GetNaturalSize();
4164       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4165       {
4166         const float sizeRatio = size.width / size.height;
4167         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4168
4169         if( naturalSizeRatio < sizeRatio )
4170         {
4171           return Vector2( size.width, size.width / naturalSizeRatio );
4172         }
4173         else if( naturalSizeRatio > sizeRatio )
4174         {
4175           return Vector2( naturalSizeRatio * size.height, size.height );
4176         }
4177         else
4178         {
4179           return size;
4180         }
4181       }
4182       break;
4183     }
4184
4185     default:
4186     {
4187       break;
4188     }
4189   }
4190
4191   return size;
4192 }
4193
4194 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4195 {
4196   // Do the set actor size
4197   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4198
4199   // Adjust for size set policy
4200   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4201
4202   // Lock the flag to stop recursive relayouts on set size
4203   mRelayoutData->insideRelayout = true;
4204   SetSize( negotiatedSize );
4205   mRelayoutData->insideRelayout = false;
4206
4207   // Clear flags for all dimensions
4208   SetLayoutDirty( false );
4209
4210   // Give deriving classes a chance to respond
4211   OnRelayout( negotiatedSize, container );
4212
4213   if( !mOnRelayoutSignal.Empty() )
4214   {
4215     Dali::Actor handle( this );
4216     mOnRelayoutSignal.Emit( handle );
4217   }
4218 }
4219
4220 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4221 {
4222   // Force a size negotiation for actors that has assigned size during relayout
4223   // This is required as otherwise the flags that force a relayout will not
4224   // necessarilly be set. This will occur if the actor has already been laid out.
4225   // The dirty flags are then cleared. Then if the actor is added back into the
4226   // relayout container afterwards, the dirty flags would still be clear...
4227   // causing a relayout to be skipped. Here we force any actors added to the
4228   // container to be relayed out.
4229   if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4230   {
4231     SetLayoutNegotiated(false, Dimension::WIDTH);
4232   }
4233   if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4234   {
4235     SetLayoutNegotiated(false, Dimension::HEIGHT);
4236   }
4237
4238   // Do the negotiation
4239   NegotiateDimensions( allocatedSize );
4240
4241   // Set the actor size
4242   SetNegotiatedSize( container );
4243
4244   // Negotiate down to children
4245   const Vector2 newBounds = GetTargetSize().GetVectorXY();
4246
4247   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4248   {
4249     ActorPtr child = GetChildAt( i );
4250
4251     // Forces children that have already been laid out to be relayed out
4252     // if they have assigned size during relayout.
4253     if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4254     {
4255       child->SetLayoutNegotiated(false, Dimension::WIDTH);
4256       child->SetLayoutDirty(true, Dimension::WIDTH);
4257     }
4258     if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4259     {
4260       child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4261       child->SetLayoutDirty(true, Dimension::HEIGHT);
4262     }
4263
4264     // Only relayout if required
4265     if( child->RelayoutRequired() )
4266     {
4267       container.Add( Dali::Actor( child.Get() ), newBounds );
4268     }
4269   }
4270 }
4271
4272 void Actor::RelayoutRequest( Dimension::Type dimension )
4273 {
4274   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4275   if( relayoutController )
4276   {
4277     Dali::Actor self( this );
4278     relayoutController->RequestRelayout( self, dimension );
4279   }
4280 }
4281
4282 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4283 {
4284 }
4285
4286 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4287 {
4288 }
4289
4290 void Actor::SetPreferredSize( const Vector2& size )
4291 {
4292   EnsureRelayoutData();
4293
4294   if( size.width > 0.0f )
4295   {
4296     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4297   }
4298
4299   if( size.height > 0.0f )
4300   {
4301     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4302   }
4303
4304   mRelayoutData->preferredSize = size;
4305
4306   RelayoutRequest();
4307 }
4308
4309 Vector2 Actor::GetPreferredSize() const
4310 {
4311   if ( mRelayoutData )
4312   {
4313     return Vector2( mRelayoutData->preferredSize );
4314   }
4315
4316   return GetDefaultPreferredSize();
4317 }
4318
4319 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4320 {
4321   EnsureRelayoutData();
4322
4323   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4324   {
4325     if( dimension & ( 1 << i ) )
4326     {
4327       mRelayoutData->minimumSize[ i ] = size;
4328     }
4329   }
4330
4331   RelayoutRequest();
4332 }
4333
4334 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4335 {
4336   if ( mRelayoutData )
4337   {
4338     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4339     {
4340       if( dimension & ( 1 << i ) )
4341       {
4342         return mRelayoutData->minimumSize[ i ];
4343       }
4344     }
4345   }
4346
4347   return 0.0f;  // Default
4348 }
4349
4350 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4351 {
4352   EnsureRelayoutData();
4353
4354   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4355   {
4356     if( dimension & ( 1 << i ) )
4357     {
4358       mRelayoutData->maximumSize[ i ] = size;
4359     }
4360   }
4361
4362   RelayoutRequest();
4363 }
4364
4365 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4366 {
4367   if ( mRelayoutData )
4368   {
4369     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4370     {
4371       if( dimension & ( 1 << i ) )
4372       {
4373         return mRelayoutData->maximumSize[ i ];
4374       }
4375     }
4376   }
4377
4378   return FLT_MAX;  // Default
4379 }
4380
4381 Object* Actor::GetParentObject() const
4382 {
4383   return mParent;
4384 }
4385
4386 } // namespace Internal
4387
4388 } // namespace Dali