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