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