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