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