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