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