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