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