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