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