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