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