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