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