Added sibling order property to the actor's property table
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/actors/actor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cmath>
23 #include <algorithm>
24 #include <cfloat>
25
26 // INTERNAL INCLUDES
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/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   DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1891   return mTouchedSignal;
1892 }
1893
1894 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1895 {
1896   return mTouchSignal;
1897 }
1898
1899 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1900 {
1901   return mHoveredSignal;
1902 }
1903
1904 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1905 {
1906   return mWheelEventSignal;
1907 }
1908
1909 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1910 {
1911   return mOnStageSignal;
1912 }
1913
1914 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1915 {
1916   return mOffStageSignal;
1917 }
1918
1919 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1920 {
1921   return mOnRelayoutSignal;
1922 }
1923
1924 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1925 {
1926   bool connected( true );
1927   Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1928
1929   if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1930   {
1931     actor->TouchedSignal().Connect( tracker, functor );
1932   }
1933   else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1934   {
1935     actor->HoveredSignal().Connect( tracker, functor );
1936   }
1937   else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1938   {
1939     actor->WheelEventSignal().Connect( tracker, functor );
1940   }
1941   else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1942   {
1943     actor->OnStageSignal().Connect( tracker, functor );
1944   }
1945   else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1946   {
1947     actor->OffStageSignal().Connect( tracker, functor );
1948   }
1949   else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1950   {
1951     actor->OnRelayoutSignal().Connect( tracker, functor );
1952   }
1953   else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1954   {
1955     actor->TouchSignal().Connect( tracker, functor );
1956   }
1957   else
1958   {
1959     // signalName does not match any signal
1960     connected = false;
1961   }
1962
1963   return connected;
1964 }
1965
1966 Actor::Actor( DerivedType derivedType )
1967 : mParent( NULL ),
1968   mChildren( NULL ),
1969   mRenderers( NULL ),
1970   mNode( NULL ),
1971   mParentOrigin( NULL ),
1972   mAnchorPoint( NULL ),
1973   mRelayoutData( NULL ),
1974   mGestureData( NULL ),
1975   mTargetSize( 0.0f, 0.0f, 0.0f ),
1976   mName(),
1977   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1978   mDepth( 0u ),
1979   mSiblingOrder(0u),
1980   mIsRoot( ROOT_LAYER == derivedType ),
1981   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1982   mIsOnStage( false ),
1983   mSensitive( true ),
1984   mLeaveRequired( false ),
1985   mKeyboardFocusable( false ),
1986   mDerivedRequiresTouch( false ),
1987   mDerivedRequiresHover( false ),
1988   mDerivedRequiresWheelEvent( false ),
1989   mOnStageSignalled( false ),
1990   mInsideOnSizeSet( false ),
1991   mInheritPosition( true ),
1992   mInheritOrientation( true ),
1993   mInheritScale( true ),
1994   mDrawMode( DrawMode::NORMAL ),
1995   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1996   mColorMode( Node::DEFAULT_COLOR_MODE ),
1997   mClippingMode( ClippingMode::DISABLED ),
1998   mIsBatchParent( false )
1999 {
2000 }
2001
2002 void Actor::Initialize()
2003 {
2004   // Node creation
2005   SceneGraph::Node* node = CreateNode();
2006
2007   AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2008   mNode = node; // Keep raw-pointer to Node
2009
2010   OnInitialize();
2011
2012   GetEventThreadServices().RegisterObject( this );
2013 }
2014
2015 Actor::~Actor()
2016 {
2017   // Remove mParent pointers from children even if we're destroying core,
2018   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2019   if( mChildren )
2020   {
2021     ActorConstIter endIter = mChildren->end();
2022     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2023     {
2024       (*iter)->SetParent( NULL );
2025     }
2026   }
2027   delete mChildren;
2028   delete mRenderers;
2029
2030   // Guard to allow handle destruction after Core has been destroyed
2031   if( EventThreadServices::IsCoreRunning() )
2032   {
2033     if( NULL != mNode )
2034     {
2035       DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2036       mNode = NULL; // Node is about to be destroyed
2037     }
2038
2039     GetEventThreadServices().UnregisterObject( this );
2040   }
2041
2042   // Cleanup optional gesture data
2043   delete mGestureData;
2044
2045   // Cleanup optional parent origin and anchor
2046   delete mParentOrigin;
2047   delete mAnchorPoint;
2048
2049   // Delete optional relayout data
2050   if( mRelayoutData )
2051   {
2052     delete mRelayoutData;
2053   }
2054 }
2055
2056 void Actor::ConnectToStage( unsigned int parentDepth )
2057 {
2058   // This container is used instead of walking the Actor hierarchy.
2059   // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2060   ActorContainer connectionList;
2061
2062   // This stage is atomic i.e. not interrupted by user callbacks.
2063   RecursiveConnectToStage( connectionList, parentDepth + 1 );
2064
2065   // Notify applications about the newly connected actors.
2066   const ActorIter endIter = connectionList.end();
2067   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2068   {
2069     (*iter)->NotifyStageConnection();
2070   }
2071
2072   RelayoutRequest();
2073 }
2074
2075 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2076 {
2077   DALI_ASSERT_ALWAYS( !OnStage() );
2078
2079   mIsOnStage = true;
2080   mDepth = depth;
2081   SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2082
2083   ConnectToSceneGraph();
2084
2085   // Notification for internal derived classes
2086   OnStageConnectionInternal();
2087
2088   // This stage is atomic; avoid emitting callbacks until all Actors are connected
2089   connectionList.push_back( ActorPtr( this ) );
2090
2091   // Recursively connect children
2092   if( mChildren )
2093   {
2094     ActorConstIter endIter = mChildren->end();
2095     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2096     {
2097       (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2098     }
2099   }
2100 }
2101
2102 /**
2103  * This method is called when the Actor is connected to the Stage.
2104  * The parent must have added its Node to the scene-graph.
2105  * The child must connect its Node to the parent's Node.
2106  * This is recursive; the child calls ConnectToStage() for its children.
2107  */
2108 void Actor::ConnectToSceneGraph()
2109 {
2110   DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2111
2112   if( NULL != mNode )
2113   {
2114     // Reparent Node in next Update
2115     ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2116   }
2117
2118   unsigned int rendererCount( GetRendererCount() );
2119   for( unsigned int i(0); i<rendererCount; ++i )
2120   {
2121     GetRendererAt(i)->Connect();
2122   }
2123
2124   // Request relayout on all actors that are added to the scenegraph
2125   RelayoutRequest();
2126
2127   // Notification for Object::Observers
2128   OnSceneObjectAdd();
2129 }
2130
2131 void Actor::NotifyStageConnection()
2132 {
2133   // Actors can be removed (in a callback), before the on-stage stage is reported.
2134   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2135   if( OnStage() && !mOnStageSignalled )
2136   {
2137     // Notification for external (CustomActor) derived classes
2138     OnStageConnectionExternal( mDepth );
2139
2140     if( !mOnStageSignal.Empty() )
2141     {
2142       Dali::Actor handle( this );
2143       mOnStageSignal.Emit( handle );
2144     }
2145
2146     // Guard against Remove during callbacks
2147     if( OnStage() )
2148     {
2149       mOnStageSignalled = true; // signal required next time Actor is removed
2150     }
2151   }
2152 }
2153
2154 void Actor::DisconnectFromStage()
2155 {
2156   // This container is used instead of walking the Actor hierachy.
2157   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2158   ActorContainer disconnectionList;
2159
2160   // This stage is atomic i.e. not interrupted by user callbacks
2161   RecursiveDisconnectFromStage( disconnectionList );
2162
2163   // Notify applications about the newly disconnected actors.
2164   const ActorIter endIter = disconnectionList.end();
2165   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2166   {
2167     (*iter)->NotifyStageDisconnection();
2168   }
2169 }
2170
2171 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2172 {
2173   DALI_ASSERT_ALWAYS( OnStage() );
2174
2175   // Recursively disconnect children
2176   if( mChildren )
2177   {
2178     ActorConstIter endIter = mChildren->end();
2179     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2180     {
2181       (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2182     }
2183   }
2184
2185   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2186   disconnectionList.push_back( ActorPtr( this ) );
2187
2188   // Notification for internal derived classes
2189   OnStageDisconnectionInternal();
2190
2191   DisconnectFromSceneGraph();
2192
2193   mIsOnStage = false;
2194 }
2195
2196 /**
2197  * This method is called by an actor or its parent, before a node removal message is sent.
2198  * This is recursive; the child calls DisconnectFromStage() for its children.
2199  */
2200 void Actor::DisconnectFromSceneGraph()
2201 {
2202   // Notification for Object::Observers
2203   OnSceneObjectRemove();
2204
2205   unsigned int rendererCount( GetRendererCount() );
2206   for( unsigned int i(0); i<rendererCount; ++i )
2207   {
2208     GetRendererAt(i)->Disconnect();
2209   }
2210 }
2211
2212 void Actor::NotifyStageDisconnection()
2213 {
2214   // Actors can be added (in a callback), before the off-stage state is reported.
2215   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2216   // only do this step if there is a stage, i.e. Core is not being shut down
2217   if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2218   {
2219     // Notification for external (CustomeActor) derived classes
2220     OnStageDisconnectionExternal();
2221
2222     if( !mOffStageSignal.Empty() )
2223     {
2224       Dali::Actor handle( this );
2225       mOffStageSignal.Emit( handle );
2226     }
2227
2228     // Guard against Add during callbacks
2229     if( !OnStage() )
2230     {
2231       mOnStageSignalled = false; // signal required next time Actor is added
2232     }
2233   }
2234 }
2235
2236 bool Actor::IsNodeConnected() const
2237 {
2238   bool connected( false );
2239
2240   if( OnStage() && ( NULL != mNode ) )
2241   {
2242     if( IsRoot() || mNode->GetParent() )
2243     {
2244       connected = true;
2245     }
2246   }
2247
2248   return connected;
2249 }
2250
2251 unsigned int Actor::GetDefaultPropertyCount() const
2252 {
2253   return DEFAULT_PROPERTY_COUNT;
2254 }
2255
2256 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2257 {
2258   indices.Reserve( DEFAULT_PROPERTY_COUNT );
2259
2260   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2261   {
2262     indices.PushBack( i );
2263   }
2264 }
2265
2266 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2267 {
2268   if( index < DEFAULT_PROPERTY_COUNT )
2269   {
2270     return DEFAULT_PROPERTY_DETAILS[ index ].name;
2271   }
2272
2273   return NULL;
2274 }
2275
2276 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2277 {
2278   Property::Index index = Property::INVALID_INDEX;
2279
2280   // Look for name in default properties
2281   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2282   {
2283     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2284     if( 0 == name.compare( property->name ) )
2285     {
2286       index = i;
2287       break;
2288     }
2289   }
2290
2291   return index;
2292 }
2293
2294 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2295 {
2296   if( index < DEFAULT_PROPERTY_COUNT )
2297   {
2298     return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2299   }
2300
2301   return false;
2302 }
2303
2304 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2305 {
2306   if( index < DEFAULT_PROPERTY_COUNT )
2307   {
2308     return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2309   }
2310
2311   return false;
2312 }
2313
2314 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2315 {
2316   if( index < DEFAULT_PROPERTY_COUNT )
2317   {
2318     return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2319   }
2320
2321   return false;
2322 }
2323
2324 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2325 {
2326   if( index < DEFAULT_PROPERTY_COUNT )
2327   {
2328     return DEFAULT_PROPERTY_DETAILS[ index ].type;
2329   }
2330
2331   // index out of range...return Property::NONE
2332   return Property::NONE;
2333 }
2334
2335 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2336 {
2337   switch( index )
2338   {
2339     case Dali::Actor::Property::PARENT_ORIGIN:
2340     {
2341       Property::Type type = property.GetType();
2342       if( type == Property::VECTOR3 )
2343       {
2344         SetParentOrigin( property.Get< Vector3 >() );
2345       }
2346       else if ( type == Property::STRING )
2347       {
2348         std::string parentOriginString;
2349         property.Get( parentOriginString );
2350         Vector3 parentOrigin;
2351         if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2352         {
2353           SetParentOrigin( parentOrigin );
2354         }
2355       }
2356       break;
2357     }
2358
2359     case Dali::Actor::Property::PARENT_ORIGIN_X:
2360     {
2361       SetParentOriginX( property.Get< float >() );
2362       break;
2363     }
2364
2365     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2366     {
2367       SetParentOriginY( property.Get< float >() );
2368       break;
2369     }
2370
2371     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2372     {
2373       SetParentOriginZ( property.Get< float >() );
2374       break;
2375     }
2376
2377     case Dali::Actor::Property::ANCHOR_POINT:
2378     {
2379       Property::Type type = property.GetType();
2380       if( type == Property::VECTOR3 )
2381       {
2382         SetAnchorPoint( property.Get< Vector3 >() );
2383       }
2384       else if ( type == Property::STRING )
2385       {
2386         std::string anchorPointString;
2387         property.Get( anchorPointString );
2388         Vector3 anchor;
2389         if( GetAnchorPointConstant( anchorPointString, anchor ) )
2390         {
2391           SetAnchorPoint( anchor );
2392         }
2393       }
2394       break;
2395     }
2396
2397     case Dali::Actor::Property::ANCHOR_POINT_X:
2398     {
2399       SetAnchorPointX( property.Get< float >() );
2400       break;
2401     }
2402
2403     case Dali::Actor::Property::ANCHOR_POINT_Y:
2404     {
2405       SetAnchorPointY( property.Get< float >() );
2406       break;
2407     }
2408
2409     case Dali::Actor::Property::ANCHOR_POINT_Z:
2410     {
2411       SetAnchorPointZ( property.Get< float >() );
2412       break;
2413     }
2414
2415     case Dali::Actor::Property::SIZE:
2416     {
2417       SetSize( property.Get< Vector3 >() );
2418       break;
2419     }
2420
2421     case Dali::Actor::Property::SIZE_WIDTH:
2422     {
2423       SetWidth( property.Get< float >() );
2424       break;
2425     }
2426
2427     case Dali::Actor::Property::SIZE_HEIGHT:
2428     {
2429       SetHeight( property.Get< float >() );
2430       break;
2431     }
2432
2433     case Dali::Actor::Property::SIZE_DEPTH:
2434     {
2435       SetDepth( property.Get< float >() );
2436       break;
2437     }
2438
2439     case Dali::Actor::Property::POSITION:
2440     {
2441       SetPosition( property.Get< Vector3 >() );
2442       break;
2443     }
2444
2445     case Dali::Actor::Property::POSITION_X:
2446     {
2447       SetX( property.Get< float >() );
2448       break;
2449     }
2450
2451     case Dali::Actor::Property::POSITION_Y:
2452     {
2453       SetY( property.Get< float >() );
2454       break;
2455     }
2456
2457     case Dali::Actor::Property::POSITION_Z:
2458     {
2459       SetZ( property.Get< float >() );
2460       break;
2461     }
2462
2463     case Dali::Actor::Property::ORIENTATION:
2464     {
2465       SetOrientation( property.Get< Quaternion >() );
2466       break;
2467     }
2468
2469     case Dali::Actor::Property::SCALE:
2470     {
2471       SetScale( property.Get< Vector3 >() );
2472       break;
2473     }
2474
2475     case Dali::Actor::Property::SCALE_X:
2476     {
2477       SetScaleX( property.Get< float >() );
2478       break;
2479     }
2480
2481     case Dali::Actor::Property::SCALE_Y:
2482     {
2483       SetScaleY( property.Get< float >() );
2484       break;
2485     }
2486
2487     case Dali::Actor::Property::SCALE_Z:
2488     {
2489       SetScaleZ( property.Get< float >() );
2490       break;
2491     }
2492
2493     case Dali::Actor::Property::VISIBLE:
2494     {
2495       SetVisible( property.Get< bool >() );
2496       break;
2497     }
2498
2499     case Dali::Actor::Property::COLOR:
2500     {
2501       SetColor( property.Get< Vector4 >() );
2502       break;
2503     }
2504
2505     case Dali::Actor::Property::COLOR_RED:
2506     {
2507       SetColorRed( property.Get< float >() );
2508       break;
2509     }
2510
2511     case Dali::Actor::Property::COLOR_GREEN:
2512     {
2513       SetColorGreen( property.Get< float >() );
2514       break;
2515     }
2516
2517     case Dali::Actor::Property::COLOR_BLUE:
2518     {
2519       SetColorBlue( property.Get< float >() );
2520       break;
2521     }
2522
2523     case Dali::Actor::Property::COLOR_ALPHA:
2524     {
2525       SetOpacity( property.Get< float >() );
2526       break;
2527     }
2528
2529     case Dali::Actor::Property::NAME:
2530     {
2531       SetName( property.Get< std::string >() );
2532       break;
2533     }
2534
2535     case Dali::Actor::Property::SENSITIVE:
2536     {
2537       SetSensitive( property.Get< bool >() );
2538       break;
2539     }
2540
2541     case Dali::Actor::Property::LEAVE_REQUIRED:
2542     {
2543       SetLeaveRequired( property.Get< bool >() );
2544       break;
2545     }
2546
2547     case Dali::Actor::Property::INHERIT_POSITION:
2548     {
2549       SetInheritPosition( property.Get< bool >() );
2550       break;
2551     }
2552
2553     case Dali::Actor::Property::INHERIT_ORIENTATION:
2554     {
2555       SetInheritOrientation( property.Get< bool >() );
2556       break;
2557     }
2558
2559     case Dali::Actor::Property::INHERIT_SCALE:
2560     {
2561       SetInheritScale( property.Get< bool >() );
2562       break;
2563     }
2564
2565     case Dali::Actor::Property::COLOR_MODE:
2566     {
2567       ColorMode mode;
2568       if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2569       {
2570         SetColorMode( mode );
2571       }
2572       break;
2573     }
2574
2575     case Dali::Actor::Property::POSITION_INHERITANCE:
2576     {
2577       PositionInheritanceMode mode;
2578       if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2579       {
2580         SetPositionInheritanceMode( mode );
2581       }
2582       break;
2583     }
2584
2585     case Dali::Actor::Property::DRAW_MODE:
2586     {
2587       DrawMode::Type mode;
2588       if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2589       {
2590         SetDrawMode( mode );
2591       }
2592       break;
2593     }
2594
2595     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2596     {
2597       SetSizeModeFactor( property.Get< Vector3 >() );
2598       break;
2599     }
2600
2601     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2602     {
2603       ResizePolicy::Type type;
2604       if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2605       {
2606         SetResizePolicy( type, Dimension::WIDTH );
2607       }
2608       break;
2609     }
2610
2611     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2612     {
2613       ResizePolicy::Type type;
2614       if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2615       {
2616         SetResizePolicy( type, Dimension::HEIGHT );
2617       }
2618       break;
2619     }
2620
2621     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2622     {
2623       SizeScalePolicy::Type type;
2624       if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2625       {
2626         SetSizeScalePolicy( type );
2627       }
2628       break;
2629     }
2630
2631     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2632     {
2633       if( property.Get< bool >() )
2634       {
2635         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2636       }
2637       break;
2638     }
2639
2640     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2641     {
2642       if( property.Get< bool >() )
2643       {
2644         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2645       }
2646       break;
2647     }
2648
2649     case Dali::Actor::Property::PADDING:
2650     {
2651       Vector4 padding = property.Get< Vector4 >();
2652       SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2653       SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2654       break;
2655     }
2656
2657     case Dali::Actor::Property::MINIMUM_SIZE:
2658     {
2659       Vector2 size = property.Get< Vector2 >();
2660       SetMinimumSize( size.x, Dimension::WIDTH );
2661       SetMinimumSize( size.y, Dimension::HEIGHT );
2662       break;
2663     }
2664
2665     case Dali::Actor::Property::MAXIMUM_SIZE:
2666     {
2667       Vector2 size = property.Get< Vector2 >();
2668       SetMaximumSize( size.x, Dimension::WIDTH );
2669       SetMaximumSize( size.y, Dimension::HEIGHT );
2670       break;
2671     }
2672
2673     case Dali::DevelActor::Property::BATCH_PARENT:
2674     {
2675       bool value;
2676
2677       if( property.Get( value ) )
2678       {
2679         if( value != mIsBatchParent )
2680         {
2681           mIsBatchParent = value;
2682           SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2683         }
2684       }
2685       break;
2686     }
2687
2688     case Dali::DevelActor::Property::SIBLING_ORDER:
2689     {
2690       int value;
2691
2692       if( property.Get( value ) )
2693       {
2694         if( static_cast<unsigned int>(value) != mSiblingOrder )
2695         {
2696           mSiblingOrder = value;
2697           if( mIsOnStage )
2698           {
2699             SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2700           }
2701         }
2702       }
2703       break;
2704     }
2705
2706     case Dali::Actor::Property::CLIPPING_MODE:
2707     {
2708       ClippingMode::Type convertedValue = mClippingMode;
2709       if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2710       {
2711         mClippingMode = convertedValue;
2712         if( NULL != mNode )
2713         {
2714           SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2715         }
2716       }
2717       break;
2718     }
2719
2720     default:
2721     {
2722       // this can happen in the case of a non-animatable default property so just do nothing
2723       break;
2724     }
2725   }
2726 }
2727
2728 // TODO: This method needs to be removed
2729 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2730 {
2731   switch( entry.GetType() )
2732   {
2733     case Property::BOOLEAN:
2734     {
2735       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2736       DALI_ASSERT_DEBUG( NULL != property );
2737
2738       // property is being used in a separate thread; queue a message to set the property
2739       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2740
2741       break;
2742     }
2743
2744     case Property::INTEGER:
2745     {
2746       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2747       DALI_ASSERT_DEBUG( NULL != property );
2748
2749       // property is being used in a separate thread; queue a message to set the property
2750       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2751
2752       break;
2753     }
2754
2755     case Property::FLOAT:
2756     {
2757       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2758       DALI_ASSERT_DEBUG( NULL != property );
2759
2760       // property is being used in a separate thread; queue a message to set the property
2761       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2762
2763       break;
2764     }
2765
2766     case Property::VECTOR2:
2767     {
2768       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2769       DALI_ASSERT_DEBUG( NULL != property );
2770
2771       // property is being used in a separate thread; queue a message to set the property
2772       if(entry.componentIndex == 0)
2773       {
2774         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2775       }
2776       else if(entry.componentIndex == 1)
2777       {
2778         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2779       }
2780       else
2781       {
2782         SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2783       }
2784
2785       break;
2786     }
2787
2788     case Property::VECTOR3:
2789     {
2790       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2791       DALI_ASSERT_DEBUG( NULL != property );
2792
2793       // property is being used in a separate thread; queue a message to set the property
2794       if(entry.componentIndex == 0)
2795       {
2796         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2797       }
2798       else if(entry.componentIndex == 1)
2799       {
2800         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2801       }
2802       else if(entry.componentIndex == 2)
2803       {
2804         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2805       }
2806       else
2807       {
2808         SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2809       }
2810
2811       break;
2812     }
2813
2814     case Property::VECTOR4:
2815     {
2816       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2817       DALI_ASSERT_DEBUG( NULL != property );
2818
2819       // property is being used in a separate thread; queue a message to set the property
2820       if(entry.componentIndex == 0)
2821       {
2822         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2823       }
2824       else if(entry.componentIndex == 1)
2825       {
2826         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2827       }
2828       else if(entry.componentIndex == 2)
2829       {
2830         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2831       }
2832       else if(entry.componentIndex == 3)
2833       {
2834         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2835       }
2836       else
2837       {
2838         SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2839       }
2840
2841       break;
2842     }
2843
2844     case Property::ROTATION:
2845     {
2846       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2847       DALI_ASSERT_DEBUG( NULL != property );
2848
2849       // property is being used in a separate thread; queue a message to set the property
2850       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
2851
2852       break;
2853     }
2854
2855     case Property::MATRIX:
2856     {
2857       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2858       DALI_ASSERT_DEBUG( NULL != property );
2859
2860       // property is being used in a separate thread; queue a message to set the property
2861       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
2862
2863       break;
2864     }
2865
2866     case Property::MATRIX3:
2867     {
2868       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2869       DALI_ASSERT_DEBUG( NULL != property );
2870
2871       // property is being used in a separate thread; queue a message to set the property
2872       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
2873
2874       break;
2875     }
2876
2877     default:
2878     {
2879       // nothing to do for other types
2880     }
2881   } // entry.GetType
2882 }
2883
2884 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2885 {
2886   Property::Value value;
2887
2888   if( index >= DEFAULT_PROPERTY_COUNT )
2889   {
2890     return value;
2891   }
2892
2893   switch( index )
2894   {
2895     case Dali::Actor::Property::PARENT_ORIGIN:
2896     {
2897       value = GetCurrentParentOrigin();
2898       break;
2899     }
2900
2901     case Dali::Actor::Property::PARENT_ORIGIN_X:
2902     {
2903       value = GetCurrentParentOrigin().x;
2904       break;
2905     }
2906
2907     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2908     {
2909       value = GetCurrentParentOrigin().y;
2910       break;
2911     }
2912
2913     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2914     {
2915       value = GetCurrentParentOrigin().z;
2916       break;
2917     }
2918
2919     case Dali::Actor::Property::ANCHOR_POINT:
2920     {
2921       value = GetCurrentAnchorPoint();
2922       break;
2923     }
2924
2925     case Dali::Actor::Property::ANCHOR_POINT_X:
2926     {
2927       value = GetCurrentAnchorPoint().x;
2928       break;
2929     }
2930
2931     case Dali::Actor::Property::ANCHOR_POINT_Y:
2932     {
2933       value = GetCurrentAnchorPoint().y;
2934       break;
2935     }
2936
2937     case Dali::Actor::Property::ANCHOR_POINT_Z:
2938     {
2939       value = GetCurrentAnchorPoint().z;
2940       break;
2941     }
2942
2943     case Dali::Actor::Property::SIZE:
2944     {
2945       value = GetTargetSize();
2946       break;
2947     }
2948
2949     case Dali::Actor::Property::SIZE_WIDTH:
2950     {
2951       value = GetTargetSize().width;
2952       break;
2953     }
2954
2955     case Dali::Actor::Property::SIZE_HEIGHT:
2956     {
2957       value = GetTargetSize().height;
2958       break;
2959     }
2960
2961     case Dali::Actor::Property::SIZE_DEPTH:
2962     {
2963       value = GetTargetSize().depth;
2964       break;
2965     }
2966
2967     case Dali::Actor::Property::POSITION:
2968     {
2969       value = GetTargetPosition();
2970       break;
2971     }
2972
2973     case Dali::Actor::Property::POSITION_X:
2974     {
2975       value = GetTargetPosition().x;
2976       break;
2977     }
2978
2979     case Dali::Actor::Property::POSITION_Y:
2980     {
2981       value = GetTargetPosition().y;
2982       break;
2983     }
2984
2985     case Dali::Actor::Property::POSITION_Z:
2986     {
2987       value = GetTargetPosition().z;
2988       break;
2989     }
2990
2991     case Dali::Actor::Property::WORLD_POSITION:
2992     {
2993       value = GetCurrentWorldPosition();
2994       break;
2995     }
2996
2997     case Dali::Actor::Property::WORLD_POSITION_X:
2998     {
2999       value = GetCurrentWorldPosition().x;
3000       break;
3001     }
3002
3003     case Dali::Actor::Property::WORLD_POSITION_Y:
3004     {
3005       value = GetCurrentWorldPosition().y;
3006       break;
3007     }
3008
3009     case Dali::Actor::Property::WORLD_POSITION_Z:
3010     {
3011       value = GetCurrentWorldPosition().z;
3012       break;
3013     }
3014
3015     case Dali::Actor::Property::ORIENTATION:
3016     {
3017       value = GetCurrentOrientation();
3018       break;
3019     }
3020
3021     case Dali::Actor::Property::WORLD_ORIENTATION:
3022     {
3023       value = GetCurrentWorldOrientation();
3024       break;
3025     }
3026
3027     case Dali::Actor::Property::SCALE:
3028     {
3029       value = GetCurrentScale();
3030       break;
3031     }
3032
3033     case Dali::Actor::Property::SCALE_X:
3034     {
3035       value = GetCurrentScale().x;
3036       break;
3037     }
3038
3039     case Dali::Actor::Property::SCALE_Y:
3040     {
3041       value = GetCurrentScale().y;
3042       break;
3043     }
3044
3045     case Dali::Actor::Property::SCALE_Z:
3046     {
3047       value = GetCurrentScale().z;
3048       break;
3049     }
3050
3051     case Dali::Actor::Property::WORLD_SCALE:
3052     {
3053       value = GetCurrentWorldScale();
3054       break;
3055     }
3056
3057     case Dali::Actor::Property::VISIBLE:
3058     {
3059       value = IsVisible();
3060       break;
3061     }
3062
3063     case Dali::Actor::Property::COLOR:
3064     {
3065       value = GetCurrentColor();
3066       break;
3067     }
3068
3069     case Dali::Actor::Property::COLOR_RED:
3070     {
3071       value = GetCurrentColor().r;
3072       break;
3073     }
3074
3075     case Dali::Actor::Property::COLOR_GREEN:
3076     {
3077       value = GetCurrentColor().g;
3078       break;
3079     }
3080
3081     case Dali::Actor::Property::COLOR_BLUE:
3082     {
3083       value = GetCurrentColor().b;
3084       break;
3085     }
3086
3087     case Dali::Actor::Property::COLOR_ALPHA:
3088     {
3089       value = GetCurrentColor().a;
3090       break;
3091     }
3092
3093     case Dali::Actor::Property::WORLD_COLOR:
3094     {
3095       value = GetCurrentWorldColor();
3096       break;
3097     }
3098
3099     case Dali::Actor::Property::WORLD_MATRIX:
3100     {
3101       value = GetCurrentWorldMatrix();
3102       break;
3103     }
3104
3105     case Dali::Actor::Property::NAME:
3106     {
3107       value = GetName();
3108       break;
3109     }
3110
3111     case Dali::Actor::Property::SENSITIVE:
3112     {
3113       value = IsSensitive();
3114       break;
3115     }
3116
3117     case Dali::Actor::Property::LEAVE_REQUIRED:
3118     {
3119       value = GetLeaveRequired();
3120       break;
3121     }
3122
3123     case Dali::Actor::Property::INHERIT_POSITION:
3124     {
3125       value = IsPositionInherited();
3126       break;
3127     }
3128
3129     case Dali::Actor::Property::INHERIT_ORIENTATION:
3130     {
3131       value = IsOrientationInherited();
3132       break;
3133     }
3134
3135     case Dali::Actor::Property::INHERIT_SCALE:
3136     {
3137       value = IsScaleInherited();
3138       break;
3139     }
3140
3141     case Dali::Actor::Property::COLOR_MODE:
3142     {
3143       value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3144       break;
3145     }
3146
3147     case Dali::Actor::Property::POSITION_INHERITANCE:
3148     {
3149       value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3150       break;
3151     }
3152
3153     case Dali::Actor::Property::DRAW_MODE:
3154     {
3155       value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3156       break;
3157     }
3158
3159     case Dali::Actor::Property::SIZE_MODE_FACTOR:
3160     {
3161       value = GetSizeModeFactor();
3162       break;
3163     }
3164
3165     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3166     {
3167       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3168       break;
3169     }
3170
3171     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3172     {
3173       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3174       break;
3175     }
3176
3177     case Dali::Actor::Property::SIZE_SCALE_POLICY:
3178     {
3179       value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3180       break;
3181     }
3182
3183     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3184     {
3185       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3186       break;
3187     }
3188
3189     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3190     {
3191       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3192       break;
3193     }
3194
3195     case Dali::Actor::Property::PADDING:
3196     {
3197       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3198       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3199       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3200       break;
3201     }
3202
3203     case Dali::Actor::Property::MINIMUM_SIZE:
3204     {
3205       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3206       break;
3207     }
3208
3209     case Dali::Actor::Property::MAXIMUM_SIZE:
3210     {
3211       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3212       break;
3213     }
3214
3215     case Dali::DevelActor::Property::BATCH_PARENT:
3216     {
3217       value = mIsBatchParent;
3218       break;
3219     }
3220
3221     case Dali::DevelActor::Property::SIBLING_ORDER:
3222     {
3223       value = static_cast<int>(mSiblingOrder);
3224       break;
3225     }
3226
3227     case Dali::Actor::Property::CLIPPING_MODE:
3228     {
3229       value = mClippingMode;
3230       break;
3231     }
3232   }
3233
3234   return value;
3235 }
3236
3237 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3238 {
3239   return mNode;
3240 }
3241
3242 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3243 {
3244   // This method should only return an object connected to the scene-graph
3245   return OnStage() ? mNode : NULL;
3246 }
3247
3248 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3249 {
3250   DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3251
3252   const PropertyBase* property( NULL );
3253
3254   // This method should only return a property of an object connected to the scene-graph
3255   if( !OnStage() )
3256   {
3257     return property;
3258   }
3259
3260   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3261   {
3262     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3263     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3264
3265     property = animatable->GetSceneGraphProperty();
3266   }
3267   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3268             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3269   {
3270     CustomPropertyMetadata* custom = FindCustomProperty( index );
3271     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3272
3273     property = custom->GetSceneGraphProperty();
3274   }
3275   else if( NULL != mNode )
3276   {
3277     switch( index )
3278     {
3279       case Dali::Actor::Property::SIZE:
3280         property = &mNode->mSize;
3281         break;
3282
3283       case Dali::Actor::Property::SIZE_WIDTH:
3284         property = &mNode->mSize;
3285         break;
3286
3287       case Dali::Actor::Property::SIZE_HEIGHT:
3288         property = &mNode->mSize;
3289         break;
3290
3291       case Dali::Actor::Property::SIZE_DEPTH:
3292         property = &mNode->mSize;
3293         break;
3294
3295       case Dali::Actor::Property::POSITION:
3296         property = &mNode->mPosition;
3297         break;
3298
3299       case Dali::Actor::Property::POSITION_X:
3300         property = &mNode->mPosition;
3301         break;
3302
3303       case Dali::Actor::Property::POSITION_Y:
3304         property = &mNode->mPosition;
3305         break;
3306
3307       case Dali::Actor::Property::POSITION_Z:
3308         property = &mNode->mPosition;
3309         break;
3310
3311       case Dali::Actor::Property::ORIENTATION:
3312         property = &mNode->mOrientation;
3313         break;
3314
3315       case Dali::Actor::Property::SCALE:
3316         property = &mNode->mScale;
3317         break;
3318
3319       case Dali::Actor::Property::SCALE_X:
3320         property = &mNode->mScale;
3321         break;
3322
3323       case Dali::Actor::Property::SCALE_Y:
3324         property = &mNode->mScale;
3325         break;
3326
3327       case Dali::Actor::Property::SCALE_Z:
3328         property = &mNode->mScale;
3329         break;
3330
3331       case Dali::Actor::Property::VISIBLE:
3332         property = &mNode->mVisible;
3333         break;
3334
3335       case Dali::Actor::Property::COLOR:
3336         property = &mNode->mColor;
3337         break;
3338
3339       case Dali::Actor::Property::COLOR_RED:
3340         property = &mNode->mColor;
3341         break;
3342
3343       case Dali::Actor::Property::COLOR_GREEN:
3344         property = &mNode->mColor;
3345         break;
3346
3347       case Dali::Actor::Property::COLOR_BLUE:
3348         property = &mNode->mColor;
3349         break;
3350
3351       case Dali::Actor::Property::COLOR_ALPHA:
3352         property = &mNode->mColor;
3353         break;
3354
3355       default:
3356         break;
3357     }
3358   }
3359
3360   return property;
3361 }
3362
3363 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3364 {
3365   const PropertyInputImpl* property( NULL );
3366
3367   // This method should only return a property of an object connected to the scene-graph
3368   if( !OnStage() )
3369   {
3370     return property;
3371   }
3372
3373   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3374   {
3375     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3376     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3377
3378     property = animatable->GetSceneGraphProperty();
3379   }
3380   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3381             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3382   {
3383     CustomPropertyMetadata* custom = FindCustomProperty( index );
3384     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3385     property = custom->GetSceneGraphProperty();
3386   }
3387   else if( NULL != mNode )
3388   {
3389     switch( index )
3390     {
3391       case Dali::Actor::Property::PARENT_ORIGIN:
3392         property = &mNode->mParentOrigin;
3393         break;
3394
3395       case Dali::Actor::Property::PARENT_ORIGIN_X:
3396         property = &mNode->mParentOrigin;
3397         break;
3398
3399       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3400         property = &mNode->mParentOrigin;
3401         break;
3402
3403       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3404         property = &mNode->mParentOrigin;
3405         break;
3406
3407       case Dali::Actor::Property::ANCHOR_POINT:
3408         property = &mNode->mAnchorPoint;
3409         break;
3410
3411       case Dali::Actor::Property::ANCHOR_POINT_X:
3412         property = &mNode->mAnchorPoint;
3413         break;
3414
3415       case Dali::Actor::Property::ANCHOR_POINT_Y:
3416         property = &mNode->mAnchorPoint;
3417         break;
3418
3419       case Dali::Actor::Property::ANCHOR_POINT_Z:
3420         property = &mNode->mAnchorPoint;
3421         break;
3422
3423       case Dali::Actor::Property::SIZE:
3424         property = &mNode->mSize;
3425         break;
3426
3427       case Dali::Actor::Property::SIZE_WIDTH:
3428         property = &mNode->mSize;
3429         break;
3430
3431       case Dali::Actor::Property::SIZE_HEIGHT:
3432         property = &mNode->mSize;
3433         break;
3434
3435       case Dali::Actor::Property::SIZE_DEPTH:
3436         property = &mNode->mSize;
3437         break;
3438
3439       case Dali::Actor::Property::POSITION:
3440         property = &mNode->mPosition;
3441         break;
3442
3443       case Dali::Actor::Property::POSITION_X:
3444         property = &mNode->mPosition;
3445         break;
3446
3447       case Dali::Actor::Property::POSITION_Y:
3448         property = &mNode->mPosition;
3449         break;
3450
3451       case Dali::Actor::Property::POSITION_Z:
3452         property = &mNode->mPosition;
3453         break;
3454
3455       case Dali::Actor::Property::WORLD_POSITION:
3456         property = &mNode->mWorldPosition;
3457         break;
3458
3459       case Dali::Actor::Property::WORLD_POSITION_X:
3460         property = &mNode->mWorldPosition;
3461         break;
3462
3463       case Dali::Actor::Property::WORLD_POSITION_Y:
3464         property = &mNode->mWorldPosition;
3465         break;
3466
3467       case Dali::Actor::Property::WORLD_POSITION_Z:
3468         property = &mNode->mWorldPosition;
3469         break;
3470
3471       case Dali::Actor::Property::ORIENTATION:
3472         property = &mNode->mOrientation;
3473         break;
3474
3475       case Dali::Actor::Property::WORLD_ORIENTATION:
3476         property = &mNode->mWorldOrientation;
3477         break;
3478
3479       case Dali::Actor::Property::SCALE:
3480         property = &mNode->mScale;
3481         break;
3482
3483       case Dali::Actor::Property::SCALE_X:
3484         property = &mNode->mScale;
3485         break;
3486
3487       case Dali::Actor::Property::SCALE_Y:
3488         property = &mNode->mScale;
3489         break;
3490
3491       case Dali::Actor::Property::SCALE_Z:
3492         property = &mNode->mScale;
3493         break;
3494
3495       case Dali::Actor::Property::WORLD_SCALE:
3496         property = &mNode->mWorldScale;
3497         break;
3498
3499       case Dali::Actor::Property::VISIBLE:
3500         property = &mNode->mVisible;
3501         break;
3502
3503       case Dali::Actor::Property::COLOR:
3504         property = &mNode->mColor;
3505         break;
3506
3507       case Dali::Actor::Property::COLOR_RED:
3508         property = &mNode->mColor;
3509         break;
3510
3511       case Dali::Actor::Property::COLOR_GREEN:
3512         property = &mNode->mColor;
3513         break;
3514
3515       case Dali::Actor::Property::COLOR_BLUE:
3516         property = &mNode->mColor;
3517         break;
3518
3519       case Dali::Actor::Property::COLOR_ALPHA:
3520         property = &mNode->mColor;
3521         break;
3522
3523       case Dali::Actor::Property::WORLD_COLOR:
3524         property = &mNode->mWorldColor;
3525         break;
3526
3527       case Dali::Actor::Property::WORLD_MATRIX:
3528         property = &mNode->mWorldMatrix;
3529         break;
3530
3531       default:
3532         break;
3533     }
3534   }
3535
3536   return property;
3537 }
3538
3539 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3540 {
3541   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3542
3543   if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3544   {
3545     // check whether the animatable property is registered already, if not then register one.
3546     AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3547     if( animatableProperty )
3548     {
3549       componentIndex = animatableProperty->componentIndex;
3550     }
3551   }
3552   else
3553   {
3554     switch( index )
3555     {
3556       case Dali::Actor::Property::PARENT_ORIGIN_X:
3557       case Dali::Actor::Property::ANCHOR_POINT_X:
3558       case Dali::Actor::Property::SIZE_WIDTH:
3559       case Dali::Actor::Property::POSITION_X:
3560       case Dali::Actor::Property::WORLD_POSITION_X:
3561       case Dali::Actor::Property::SCALE_X:
3562       case Dali::Actor::Property::COLOR_RED:
3563       {
3564         componentIndex = 0;
3565         break;
3566       }
3567
3568       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3569       case Dali::Actor::Property::ANCHOR_POINT_Y:
3570       case Dali::Actor::Property::SIZE_HEIGHT:
3571       case Dali::Actor::Property::POSITION_Y:
3572       case Dali::Actor::Property::WORLD_POSITION_Y:
3573       case Dali::Actor::Property::SCALE_Y:
3574       case Dali::Actor::Property::COLOR_GREEN:
3575       {
3576         componentIndex = 1;
3577         break;
3578       }
3579
3580       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3581       case Dali::Actor::Property::ANCHOR_POINT_Z:
3582       case Dali::Actor::Property::SIZE_DEPTH:
3583       case Dali::Actor::Property::POSITION_Z:
3584       case Dali::Actor::Property::WORLD_POSITION_Z:
3585       case Dali::Actor::Property::SCALE_Z:
3586       case Dali::Actor::Property::COLOR_BLUE:
3587       {
3588         componentIndex = 2;
3589         break;
3590       }
3591
3592       case Dali::Actor::Property::COLOR_ALPHA:
3593       {
3594         componentIndex = 3;
3595         break;
3596       }
3597
3598       default:
3599       {
3600         // Do nothing
3601         break;
3602       }
3603     }
3604   }
3605
3606   return componentIndex;
3607 }
3608
3609 void Actor::SetParent( Actor* parent )
3610 {
3611   if( parent )
3612   {
3613     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3614
3615     mParent = parent;
3616
3617     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3618          parent->OnStage() )
3619     {
3620       // Instruct each actor to create a corresponding node in the scene graph
3621       ConnectToStage( parent->GetHierarchyDepth() );
3622     }
3623
3624     // Resolve the name and index for the child properties if any
3625     ResolveChildProperties();
3626   }
3627   else // parent being set to NULL
3628   {
3629     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3630
3631     mParent = NULL;
3632
3633     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3634          OnStage() )
3635     {
3636       DALI_ASSERT_ALWAYS( mNode != NULL );
3637
3638       if( NULL != mNode )
3639       {
3640         // Disconnect the Node & its children from the scene-graph.
3641         DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3642       }
3643
3644       // Instruct each actor to discard pointers to the scene-graph
3645       DisconnectFromStage();
3646     }
3647   }
3648 }
3649
3650 SceneGraph::Node* Actor::CreateNode() const
3651 {
3652   return Node::New();
3653 }
3654
3655 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3656 {
3657   bool done = false;
3658   Actor* actor = dynamic_cast< Actor* >( object );
3659
3660   if( actor )
3661   {
3662     if( 0 == actionName.compare( ACTION_SHOW ) )
3663     {
3664       actor->SetVisible( true );
3665       done = true;
3666     }
3667     else if( 0 == actionName.compare( ACTION_HIDE ) )
3668     {
3669       actor->SetVisible( false );
3670       done = true;
3671     }
3672   }
3673
3674   return done;
3675 }
3676
3677 void Actor::EnsureRelayoutData()
3678 {
3679   // Assign relayout data.
3680   if( !mRelayoutData )
3681   {
3682     mRelayoutData = new RelayoutData();
3683   }
3684 }
3685
3686 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3687 {
3688   // Check if actor is dependent on parent
3689   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3690   {
3691     if( ( dimension & ( 1 << i ) ) )
3692     {
3693       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3694       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3695       {
3696         return true;
3697       }
3698     }
3699   }
3700
3701   return false;
3702 }
3703
3704 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3705 {
3706   // Check if actor is dependent on children
3707   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3708   {
3709     if( ( dimension & ( 1 << i ) ) )
3710     {
3711       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3712       switch( resizePolicy )
3713       {
3714         case ResizePolicy::FIT_TO_CHILDREN:
3715         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
3716         {
3717           return true;
3718         }
3719
3720         default:
3721         {
3722           break;
3723         }
3724       }
3725     }
3726   }
3727
3728   return false;
3729 }
3730
3731 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3732 {
3733   return Actor::RelayoutDependentOnChildren( dimension );
3734 }
3735
3736 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3737 {
3738   // Check each possible dimension and see if it is dependent on the input one
3739   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3740   {
3741     if( dimension & ( 1 << i ) )
3742     {
3743       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3744     }
3745   }
3746
3747   return false;
3748 }
3749
3750 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3751 {
3752   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3753   {
3754     if( dimension & ( 1 << i ) )
3755     {
3756       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3757     }
3758   }
3759 }
3760
3761 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3762 {
3763   // If more than one dimension is requested, just return the first one found
3764   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3765   {
3766     if( ( dimension & ( 1 << i ) ) )
3767     {
3768       return mRelayoutData->negotiatedDimensions[ i ];
3769     }
3770   }
3771
3772   return 0.0f;   // Default
3773 }
3774
3775 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3776 {
3777   EnsureRelayoutData();
3778
3779   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3780   {
3781     if( dimension & ( 1 << i ) )
3782     {
3783       mRelayoutData->dimensionPadding[ i ] = padding;
3784     }
3785   }
3786 }
3787
3788 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3789 {
3790   if ( mRelayoutData )
3791   {
3792     // If more than one dimension is requested, just return the first one found
3793     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3794     {
3795       if( ( dimension & ( 1 << i ) ) )
3796       {
3797         return mRelayoutData->dimensionPadding[ i ];
3798       }
3799     }
3800   }
3801
3802   return GetDefaultDimensionPadding();
3803 }
3804
3805 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3806 {
3807   EnsureRelayoutData();
3808
3809   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3810   {
3811     if( dimension & ( 1 << i ) )
3812     {
3813       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3814     }
3815   }
3816 }
3817
3818 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3819 {
3820   if ( mRelayoutData )
3821   {
3822     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3823     {
3824       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3825       {
3826         return true;
3827       }
3828     }
3829   }
3830
3831   return false;
3832 }
3833
3834 float Actor::GetHeightForWidthBase( float width )
3835 {
3836   float height = 0.0f;
3837
3838   const Vector3 naturalSize = GetNaturalSize();
3839   if( naturalSize.width > 0.0f )
3840   {
3841     height = naturalSize.height * width / naturalSize.width;
3842   }
3843   else // we treat 0 as 1:1 aspect ratio
3844   {
3845     height = width;
3846   }
3847
3848   return height;
3849 }
3850
3851 float Actor::GetWidthForHeightBase( float height )
3852 {
3853   float width = 0.0f;
3854
3855   const Vector3 naturalSize = GetNaturalSize();
3856   if( naturalSize.height > 0.0f )
3857   {
3858     width = naturalSize.width * height / naturalSize.height;
3859   }
3860   else // we treat 0 as 1:1 aspect ratio
3861   {
3862     width = height;
3863   }
3864
3865   return width;
3866 }
3867
3868 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3869 {
3870   // Fill to parent, taking size mode factor into account
3871   switch( child.GetResizePolicy( dimension ) )
3872   {
3873     case ResizePolicy::FILL_TO_PARENT:
3874     {
3875       return GetLatestSize( dimension );
3876     }
3877
3878     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3879     {
3880       return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3881     }
3882
3883     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3884     {
3885       return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3886     }
3887
3888     default:
3889     {
3890       return GetLatestSize( dimension );
3891     }
3892   }
3893 }
3894
3895 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3896 {
3897   // Can be overridden in derived class
3898   return CalculateChildSizeBase( child, dimension );
3899 }
3900
3901 float Actor::GetHeightForWidth( float width )
3902 {
3903   // Can be overridden in derived class
3904   return GetHeightForWidthBase( width );
3905 }
3906
3907 float Actor::GetWidthForHeight( float height )
3908 {
3909   // Can be overridden in derived class
3910   return GetWidthForHeightBase( height );
3911 }
3912
3913 float Actor::GetLatestSize( Dimension::Type dimension ) const
3914 {
3915   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3916 }
3917
3918 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3919 {
3920   Vector2 padding = GetPadding( dimension );
3921
3922   return GetLatestSize( dimension ) + padding.x + padding.y;
3923 }
3924
3925 float Actor::NegotiateFromParent( Dimension::Type dimension )
3926 {
3927   Actor* parent = GetParent();
3928   if( parent )
3929   {
3930     Vector2 padding( GetPadding( dimension ) );
3931     Vector2 parentPadding( parent->GetPadding( dimension ) );
3932     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3933   }
3934
3935   return 0.0f;
3936 }
3937
3938 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3939 {
3940   float maxDimensionPoint = 0.0f;
3941
3942   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3943   {
3944     ActorPtr child = GetChildAt( i );
3945
3946     if( !child->RelayoutDependentOnParent( dimension ) )
3947     {
3948       // Calculate the min and max points that the children range across
3949       float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3950       float dimensionSize = child->GetRelayoutSize( dimension );
3951       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3952     }
3953   }
3954
3955   return maxDimensionPoint;
3956 }
3957
3958 float Actor::GetSize( Dimension::Type dimension ) const
3959 {
3960   return GetDimensionValue( GetTargetSize(), dimension );
3961 }
3962
3963 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3964 {
3965   return GetDimensionValue( GetNaturalSize(), dimension );
3966 }
3967
3968 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3969 {
3970   switch( GetResizePolicy( dimension ) )
3971   {
3972     case ResizePolicy::USE_NATURAL_SIZE:
3973     {
3974       return GetNaturalSize( dimension );
3975     }
3976
3977     case ResizePolicy::FIXED:
3978     {
3979       return GetDimensionValue( GetPreferredSize(), dimension );
3980     }
3981
3982     case ResizePolicy::USE_ASSIGNED_SIZE:
3983     {
3984       return GetDimensionValue( maximumSize, dimension );
3985     }
3986
3987     case ResizePolicy::FILL_TO_PARENT:
3988     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3989     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3990     {
3991       return NegotiateFromParent( dimension );
3992     }
3993
3994     case ResizePolicy::FIT_TO_CHILDREN:
3995     {
3996       return NegotiateFromChildren( dimension );
3997     }
3998
3999     case ResizePolicy::DIMENSION_DEPENDENCY:
4000     {
4001       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4002
4003       // Custom rules
4004       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4005       {
4006         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4007       }
4008
4009       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4010       {
4011         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4012       }
4013
4014       break;
4015     }
4016
4017     default:
4018     {
4019       break;
4020     }
4021   }
4022
4023   return 0.0f;  // Default
4024 }
4025
4026 float Actor::ClampDimension( float size, Dimension::Type dimension )
4027 {
4028   const float minSize = GetMinimumSize( dimension );
4029   const float maxSize = GetMaximumSize( dimension );
4030
4031   return std::max( minSize, std::min( size, maxSize ) );
4032 }
4033
4034 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4035 {
4036   // Check if it needs to be negotiated
4037   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4038   {
4039     // Check that we havn't gotten into an infinite loop
4040     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4041     bool recursionFound = false;
4042     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4043     {
4044       if( *it == searchActor )
4045       {
4046         recursionFound = true;
4047         break;
4048       }
4049     }
4050
4051     if( !recursionFound )
4052     {
4053       // Record the path that we have taken
4054       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4055
4056       // Dimension dependency check
4057       for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4058       {
4059         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4060
4061         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4062         {
4063           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4064         }
4065       }
4066
4067       // Parent dependency check
4068       Actor* parent = GetParent();
4069       if( parent && RelayoutDependentOnParent( dimension ) )
4070       {
4071         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4072       }
4073
4074       // Children dependency check
4075       if( RelayoutDependentOnChildren( dimension ) )
4076       {
4077         for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4078         {
4079           ActorPtr child = GetChildAt( i );
4080
4081           // Only relayout child first if it is not dependent on this actor
4082           if( !child->RelayoutDependentOnParent( dimension ) )
4083           {
4084             child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4085           }
4086         }
4087       }
4088
4089       // For deriving classes
4090       OnCalculateRelayoutSize( dimension );
4091
4092       // All dependencies checked, calculate the size and set negotiated flag
4093       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4094
4095       SetNegotiatedDimension( newSize, dimension );
4096       SetLayoutNegotiated( true, dimension );
4097
4098       // For deriving classes
4099       OnLayoutNegotiated( newSize, dimension );
4100
4101       // This actor has been successfully processed, pop it off the recursion stack
4102       recursionStack.pop_back();
4103     }
4104     else
4105     {
4106       // TODO: Break infinite loop
4107       SetLayoutNegotiated( true, dimension );
4108     }
4109   }
4110 }
4111
4112 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4113 {
4114   // Negotiate all dimensions that require it
4115   ActorDimensionStack recursionStack;
4116
4117   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4118   {
4119     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4120
4121     // Negotiate
4122     NegotiateDimension( dimension, allocatedSize, recursionStack );
4123   }
4124 }
4125
4126 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4127 {
4128   switch( mRelayoutData->sizeSetPolicy )
4129   {
4130     case SizeScalePolicy::USE_SIZE_SET:
4131     {
4132       return size;
4133     }
4134
4135     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4136     {
4137       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4138       const Vector3 naturalSize = GetNaturalSize();
4139       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4140       {
4141         const float sizeRatio = size.width / size.height;
4142         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4143
4144         if( naturalSizeRatio < sizeRatio )
4145         {
4146           return Vector2( naturalSizeRatio * size.height, size.height );
4147         }
4148         else if( naturalSizeRatio > sizeRatio )
4149         {
4150           return Vector2( size.width, size.width / naturalSizeRatio );
4151         }
4152         else
4153         {
4154           return size;
4155         }
4156       }
4157
4158       break;
4159     }
4160
4161     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4162     {
4163       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4164       const Vector3 naturalSize = GetNaturalSize();
4165       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4166       {
4167         const float sizeRatio = size.width / size.height;
4168         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4169
4170         if( naturalSizeRatio < sizeRatio )
4171         {
4172           return Vector2( size.width, size.width / naturalSizeRatio );
4173         }
4174         else if( naturalSizeRatio > sizeRatio )
4175         {
4176           return Vector2( naturalSizeRatio * size.height, size.height );
4177         }
4178         else
4179         {
4180           return size;
4181         }
4182       }
4183       break;
4184     }
4185
4186     default:
4187     {
4188       break;
4189     }
4190   }
4191
4192   return size;
4193 }
4194
4195 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4196 {
4197   // Do the set actor size
4198   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4199
4200   // Adjust for size set policy
4201   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4202
4203   // Lock the flag to stop recursive relayouts on set size
4204   mRelayoutData->insideRelayout = true;
4205   SetSize( negotiatedSize );
4206   mRelayoutData->insideRelayout = false;
4207
4208   // Clear flags for all dimensions
4209   SetLayoutDirty( false );
4210
4211   // Give deriving classes a chance to respond
4212   OnRelayout( negotiatedSize, container );
4213
4214   if( !mOnRelayoutSignal.Empty() )
4215   {
4216     Dali::Actor handle( this );
4217     mOnRelayoutSignal.Emit( handle );
4218   }
4219 }
4220
4221 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4222 {
4223   // Force a size negotiation for actors that has assigned size during relayout
4224   // This is required as otherwise the flags that force a relayout will not
4225   // necessarilly be set. This will occur if the actor has already been laid out.
4226   // The dirty flags are then cleared. Then if the actor is added back into the
4227   // relayout container afterwards, the dirty flags would still be clear...
4228   // causing a relayout to be skipped. Here we force any actors added to the
4229   // container to be relayed out.
4230   if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4231   {
4232     SetLayoutNegotiated(false, Dimension::WIDTH);
4233   }
4234   if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4235   {
4236     SetLayoutNegotiated(false, Dimension::HEIGHT);
4237   }
4238
4239   // Do the negotiation
4240   NegotiateDimensions( allocatedSize );
4241
4242   // Set the actor size
4243   SetNegotiatedSize( container );
4244
4245   // Negotiate down to children
4246   const Vector2 newBounds = GetTargetSize().GetVectorXY();
4247
4248   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4249   {
4250     ActorPtr child = GetChildAt( i );
4251
4252     // Forces children that have already been laid out to be relayed out
4253     // if they have assigned size during relayout.
4254     if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4255     {
4256       child->SetLayoutNegotiated(false, Dimension::WIDTH);
4257       child->SetLayoutDirty(true, Dimension::WIDTH);
4258     }
4259     if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4260     {
4261       child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4262       child->SetLayoutDirty(true, Dimension::HEIGHT);
4263     }
4264
4265     // Only relayout if required
4266     if( child->RelayoutRequired() )
4267     {
4268       container.Add( Dali::Actor( child.Get() ), newBounds );
4269     }
4270   }
4271 }
4272
4273 void Actor::RelayoutRequest( Dimension::Type dimension )
4274 {
4275   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4276   if( relayoutController )
4277   {
4278     Dali::Actor self( this );
4279     relayoutController->RequestRelayout( self, dimension );
4280   }
4281 }
4282
4283 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4284 {
4285 }
4286
4287 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4288 {
4289 }
4290
4291 void Actor::SetPreferredSize( const Vector2& size )
4292 {
4293   EnsureRelayoutData();
4294
4295   if( size.width > 0.0f )
4296   {
4297     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4298   }
4299
4300   if( size.height > 0.0f )
4301   {
4302     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4303   }
4304
4305   mRelayoutData->preferredSize = size;
4306
4307   RelayoutRequest();
4308 }
4309
4310 Vector2 Actor::GetPreferredSize() const
4311 {
4312   if ( mRelayoutData )
4313   {
4314     return Vector2( mRelayoutData->preferredSize );
4315   }
4316
4317   return GetDefaultPreferredSize();
4318 }
4319
4320 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4321 {
4322   EnsureRelayoutData();
4323
4324   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4325   {
4326     if( dimension & ( 1 << i ) )
4327     {
4328       mRelayoutData->minimumSize[ i ] = size;
4329     }
4330   }
4331
4332   RelayoutRequest();
4333 }
4334
4335 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4336 {
4337   if ( mRelayoutData )
4338   {
4339     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4340     {
4341       if( dimension & ( 1 << i ) )
4342       {
4343         return mRelayoutData->minimumSize[ i ];
4344       }
4345     }
4346   }
4347
4348   return 0.0f;  // Default
4349 }
4350
4351 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4352 {
4353   EnsureRelayoutData();
4354
4355   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4356   {
4357     if( dimension & ( 1 << i ) )
4358     {
4359       mRelayoutData->maximumSize[ i ] = size;
4360     }
4361   }
4362
4363   RelayoutRequest();
4364 }
4365
4366 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4367 {
4368   if ( mRelayoutData )
4369   {
4370     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4371     {
4372       if( dimension & ( 1 << i ) )
4373       {
4374         return mRelayoutData->maximumSize[ i ];
4375       }
4376     }
4377   }
4378
4379   return FLT_MAX;  // Default
4380 }
4381
4382 Object* Actor::GetParentObject() const
4383 {
4384   return mParent;
4385 }
4386
4387 } // namespace Internal
4388
4389 } // namespace Dali