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