b387d334e4575ff8cb0df6319124b7d71cc6c9b4
[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-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/common/scene-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/animation/constraint-impl.h>
48 #include <dali/internal/event/common/projection.h>
49 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
50 #include <dali/internal/update/common/animatable-property.h>
51 #include <dali/internal/update/nodes/node-messages.h>
52 #include <dali/internal/update/nodes/node-declarations.h>
53 #include <dali/internal/update/animation/scene-graph-constraint.h>
54 #include <dali/internal/event/events/actor-gesture-data.h>
55 #include <dali/internal/common/message.h>
56 #include <dali/integration-api/debug.h>
57
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::PropertyBase;
61
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
64 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
65 #endif
66
67 namespace Dali
68 {
69
70 namespace Internal
71 {
72
73 namespace
74 {
75 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
76 inline const Vector3& GetDefaultSizeModeFactor()
77 {
78   return Vector3::ONE;
79 }
80
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultPreferredSize()
83 {
84   return Vector2::ZERO;
85 }
86
87 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
88 inline const Vector2& GetDefaultDimensionPadding()
89 {
90   return Vector2::ZERO;
91 }
92
93 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
94
95 } // unnamed namespace
96
97 /**
98  * Struct to collect relayout variables
99  */
100 struct Actor::RelayoutData
101 {
102   RelayoutData()
103     : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
104   {
105     // Set size negotiation defaults
106     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
107     {
108       resizePolicies[ i ] = ResizePolicy::DEFAULT;
109       useAssignedSize[ i ] = false;
110       negotiatedDimensions[ i ] = 0.0f;
111       dimensionNegotiated[ i ] = false;
112       dimensionDirty[ i ] = false;
113       dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
114       dimensionPadding[ i ] = GetDefaultDimensionPadding();
115       minimumSize[ i ] = 0.0f;
116       maximumSize[ i ] = FLT_MAX;
117     }
118   }
119
120   ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ];      ///< Resize policies
121   bool useAssignedSize[ Dimension::DIMENSION_COUNT ];                   ///< The flag to specify whether the size should be assigned to the actor
122
123   Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ];  ///< A list of dimension dependencies
124
125   Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ];         ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
126
127   float negotiatedDimensions[ Dimension::DIMENSION_COUNT ];       ///< Storage for when a dimension is negotiated but before set on actor
128
129   float minimumSize[ Dimension::DIMENSION_COUNT ];                ///< The minimum size an actor can be
130   float maximumSize[ Dimension::DIMENSION_COUNT ];                ///< The maximum size an actor can be
131
132   bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ];         ///< Has the dimension been negotiated
133   bool dimensionDirty[ Dimension::DIMENSION_COUNT ];              ///< Flags indicating whether the layout dimension is dirty or not
134
135   Vector3 sizeModeFactor;                              ///< Factor of size used for certain SizeModes
136
137   Vector2 preferredSize;                               ///< The preferred size of the actor
138
139   SizeScalePolicy::Type sizeSetPolicy :3;            ///< Policy to apply when setting size. Enough room for the enum
140
141   bool relayoutEnabled :1;                   ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
142   bool insideRelayout :1;                    ///< Locking flag to prevent recursive relayouts on size set
143 };
144
145 namespace // unnamed namespace
146 {
147
148 // Properties
149
150 /**
151  * We want to discourage the use of property strings (minimize string comparisons),
152  * particularly for the default properties.
153  *              Name                  Type   writable animatable constraint-input  enum for index-checking
154  */
155 DALI_PROPERTY_TABLE_BEGIN
156 DALI_PROPERTY( "parentOrigin",              VECTOR3,  true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN )
157 DALI_PROPERTY( "parentOriginX",             FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_X )
158 DALI_PROPERTY( "parentOriginY",             FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_Y )
159 DALI_PROPERTY( "parentOriginZ",             FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_Z )
160 DALI_PROPERTY( "anchorPoint",               VECTOR3,  true,  false, true,  Dali::Actor::Property::ANCHOR_POINT )
161 DALI_PROPERTY( "anchorPointX",              FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_X )
162 DALI_PROPERTY( "anchorPointY",              FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_Y )
163 DALI_PROPERTY( "anchorPointZ",              FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_Z )
164 DALI_PROPERTY( "size",                      VECTOR3,  true,  true,  true,  Dali::Actor::Property::SIZE )
165 DALI_PROPERTY( "sizeWidth",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_WIDTH )
166 DALI_PROPERTY( "sizeHeight",                FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_HEIGHT )
167 DALI_PROPERTY( "sizeDepth",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_DEPTH )
168 DALI_PROPERTY( "position",                  VECTOR3,  true,  true,  true,  Dali::Actor::Property::POSITION )
169 DALI_PROPERTY( "positionX",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_X )
170 DALI_PROPERTY( "positionY",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_Y )
171 DALI_PROPERTY( "positionZ",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_Z )
172 DALI_PROPERTY( "worldPosition",             VECTOR3,  false, false, true,  Dali::Actor::Property::WORLD_POSITION )
173 DALI_PROPERTY( "worldPositionX",            FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_X )
174 DALI_PROPERTY( "worldPositionY",            FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_Y )
175 DALI_PROPERTY( "worldPositionZ",            FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_Z )
176 DALI_PROPERTY( "orientation",               ROTATION, true,  true,  true,  Dali::Actor::Property::ORIENTATION )
177 DALI_PROPERTY( "worldOrientation",          ROTATION, false, false, true,  Dali::Actor::Property::WORLD_ORIENTATION )
178 DALI_PROPERTY( "scale",                     VECTOR3,  true,  true,  true,  Dali::Actor::Property::SCALE )
179 DALI_PROPERTY( "scaleX",                    FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_X )
180 DALI_PROPERTY( "scaleY",                    FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_Y )
181 DALI_PROPERTY( "scaleZ",                    FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_Z )
182 DALI_PROPERTY( "worldScale",                VECTOR3,  false, false, true,  Dali::Actor::Property::WORLD_SCALE )
183 DALI_PROPERTY( "visible",                   BOOLEAN,  true,  true,  true,  Dali::Actor::Property::VISIBLE )
184 DALI_PROPERTY( "color",                     VECTOR4,  true,  true,  true,  Dali::Actor::Property::COLOR )
185 DALI_PROPERTY( "colorRed",                  FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_RED )
186 DALI_PROPERTY( "colorGreen",                FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_GREEN )
187 DALI_PROPERTY( "colorBlue",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_BLUE )
188 DALI_PROPERTY( "colorAlpha",                FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_ALPHA )
189 DALI_PROPERTY( "worldColor",                VECTOR4,  false, false, true,  Dali::Actor::Property::WORLD_COLOR )
190 DALI_PROPERTY( "worldMatrix",               MATRIX,   false, false, true,  Dali::Actor::Property::WORLD_MATRIX )
191 DALI_PROPERTY( "name",                      STRING,   true,  false, false, Dali::Actor::Property::NAME )
192 DALI_PROPERTY( "sensitive",                 BOOLEAN,  true,  false, false, Dali::Actor::Property::SENSITIVE )
193 DALI_PROPERTY( "leaveRequired",             BOOLEAN,  true,  false, false, Dali::Actor::Property::LEAVE_REQUIRED )
194 DALI_PROPERTY( "inheritOrientation",        BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
195 DALI_PROPERTY( "inheritScale",              BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_SCALE )
196 DALI_PROPERTY( "colorMode",                 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_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
223
224 // Signals
225
226 const char* const SIGNAL_TOUCHED = "touched";
227 const char* const SIGNAL_HOVERED = "hovered";
228 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
229 const char* const SIGNAL_ON_STAGE = "onStage";
230 const char* const SIGNAL_OFF_STAGE = "offStage";
231 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
232 const char* const SIGNAL_TOUCH = "touch";
233 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
234 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
235 const char* const SIGNAL_CHILD_ADDED = "childAdded";
236 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
237
238 // Actions
239
240 const char* const ACTION_SHOW = "show";
241 const char* const ACTION_HIDE = "hide";
242
243 BaseHandle CreateActor()
244 {
245   return Dali::Actor::New();
246 }
247
248 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
249
250 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
251 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
256 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &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::OnStage() const
450 {
451   return mIsOnStage;
452 }
453
454 Dali::Layer Actor::GetLayer()
455 {
456   Dali::Layer layer;
457
458   // Short-circuit for Layer derived actors
459   if( mIsLayer )
460   {
461     layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
462   }
463
464   // Find the immediate Layer parent
465   for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
466   {
467     if( parent->IsLayer() )
468     {
469       layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
470     }
471   }
472
473   return layer;
474 }
475
476 void Actor::Add( Actor& child )
477 {
478   DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
479   DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
480
481   if( !mChildren )
482   {
483     mChildren = new ActorContainer;
484   }
485
486   Actor* const oldParent( child.mParent );
487
488   // child might already be ours
489   if( this != oldParent )
490   {
491     // if we already have parent, unparent us first
492     if( oldParent )
493     {
494       oldParent->Remove( child ); // This causes OnChildRemove callback & 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( NULL );
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 ( NULL != 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 = 0;
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 = 0;
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 && OnStage() )
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 && OnStage() )
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( OnStage() )
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( !OnStage() )
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( !OnStage() )
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( OnStage() )
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() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1792 }
1793
1794 bool Actor::GetHoverRequired() const
1795 {
1796   return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1797 }
1798
1799 bool Actor::GetWheelEventRequired() const
1800 {
1801   return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
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( NULL == mGestureData )
1814   {
1815     mGestureData = new ActorGestureData;
1816   }
1817   return *mGestureData;
1818 }
1819
1820 bool Actor::IsGestureRequred( DevelGesture::Type type ) const
1821 {
1822   return mGestureData && mGestureData->IsGestureRequred( type );
1823 }
1824
1825 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1826 {
1827   bool consumed = false;
1828
1829   if( !mTouchSignal.Empty() )
1830   {
1831     Dali::Actor handle( this );
1832     consumed = mTouchSignal.Emit( handle, touch );
1833   }
1834
1835   if( !mTouchedSignal.Empty() )
1836   {
1837     Dali::Actor handle( this );
1838     consumed |= mTouchedSignal.Emit( handle, event );
1839   }
1840
1841   if( !consumed )
1842   {
1843     // Notification for derived classes
1844     consumed = OnTouchEvent( event ); // TODO
1845   }
1846
1847   return consumed;
1848 }
1849
1850 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1851 {
1852   bool consumed = false;
1853
1854   if( !mHoveredSignal.Empty() )
1855   {
1856     Dali::Actor handle( this );
1857     consumed = mHoveredSignal.Emit( handle, event );
1858   }
1859
1860   if( !consumed )
1861   {
1862     // Notification for derived classes
1863     consumed = OnHoverEvent( event );
1864   }
1865
1866   return consumed;
1867 }
1868
1869 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1870 {
1871   bool consumed = false;
1872
1873   if( !mWheelEventSignal.Empty() )
1874   {
1875     Dali::Actor handle( this );
1876     consumed = mWheelEventSignal.Emit( handle, event );
1877   }
1878
1879   if( !consumed )
1880   {
1881     // Notification for derived classes
1882     consumed = OnWheelEvent( event );
1883   }
1884
1885   return consumed;
1886 }
1887
1888 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1889 {
1890   if( ! mVisibilityChangedSignal.Empty() )
1891   {
1892     Dali::Actor handle( this );
1893     mVisibilityChangedSignal.Emit( handle, visible, type );
1894   }
1895 }
1896
1897 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1898 {
1899   if( ! mLayoutDirectionChangedSignal.Empty() )
1900   {
1901     Dali::Actor handle( this );
1902     mLayoutDirectionChangedSignal.Emit( handle, type );
1903   }
1904 }
1905
1906 void Actor::EmitChildAddedSignal( Actor& child )
1907 {
1908   if( ! mChildAddedSignal.Empty() )
1909   {
1910     Dali::Actor handle( &child );
1911     mChildAddedSignal.Emit( handle );
1912   }
1913 }
1914
1915 void Actor::EmitChildRemovedSignal( Actor& child )
1916 {
1917   if( ! mChildRemovedSignal.Empty() )
1918   {
1919     Dali::Actor handle( &child );
1920     mChildRemovedSignal.Emit( handle );
1921   }
1922 }
1923
1924 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1925 {
1926   return mTouchedSignal;
1927 }
1928
1929 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1930 {
1931   return mTouchSignal;
1932 }
1933
1934 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1935 {
1936   return mHoveredSignal;
1937 }
1938
1939 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1940 {
1941   return mWheelEventSignal;
1942 }
1943
1944 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1945 {
1946   return mOnStageSignal;
1947 }
1948
1949 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1950 {
1951   return mOffStageSignal;
1952 }
1953
1954 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1955 {
1956   return mOnRelayoutSignal;
1957 }
1958
1959 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1960 {
1961   return mVisibilityChangedSignal;
1962 }
1963
1964 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1965 {
1966   return mLayoutDirectionChangedSignal;
1967 }
1968
1969 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1970 {
1971   return mChildAddedSignal;
1972 }
1973
1974 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1975 {
1976   return mChildRemovedSignal;
1977 }
1978
1979 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1980 {
1981   return mChildOrderChangedSignal;
1982 }
1983
1984 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1985 {
1986   bool connected( true );
1987   Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1988
1989   if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1990   {
1991     actor->TouchedSignal().Connect( tracker, functor );
1992   }
1993   else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1994   {
1995     actor->HoveredSignal().Connect( tracker, functor );
1996   }
1997   else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1998   {
1999     actor->WheelEventSignal().Connect( tracker, functor );
2000   }
2001   else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2002   {
2003     actor->OnStageSignal().Connect( tracker, functor );
2004   }
2005   else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2006   {
2007     actor->OffStageSignal().Connect( tracker, functor );
2008   }
2009   else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2010   {
2011     actor->OnRelayoutSignal().Connect( tracker, functor );
2012   }
2013   else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2014   {
2015     actor->TouchSignal().Connect( tracker, functor );
2016   }
2017   else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
2018   {
2019     actor->VisibilityChangedSignal().Connect( tracker, functor );
2020   }
2021   else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2022   {
2023     actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2024   }
2025   else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2026   {
2027     actor->ChildAddedSignal().Connect( tracker, functor );
2028   }
2029   else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2030   {
2031     actor->ChildRemovedSignal().Connect( tracker, functor );
2032   }
2033   else
2034   {
2035     // signalName does not match any signal
2036     connected = false;
2037   }
2038
2039   return connected;
2040 }
2041
2042 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2043 : Object( &node ),
2044   mScene( nullptr ),
2045   mParent( NULL ),
2046   mChildren( NULL ),
2047   mRenderers( NULL ),
2048   mParentOrigin( NULL ),
2049   mAnchorPoint( NULL ),
2050   mRelayoutData( NULL ),
2051   mGestureData( NULL ),
2052   mTouchedSignal(),
2053   mTouchSignal(),
2054   mHoveredSignal(),
2055   mWheelEventSignal(),
2056   mOnStageSignal(),
2057   mOffStageSignal(),
2058   mOnRelayoutSignal(),
2059   mVisibilityChangedSignal(),
2060   mLayoutDirectionChangedSignal(),
2061   mChildAddedSignal(),
2062   mChildRemovedSignal(),
2063   mChildOrderChangedSignal(),
2064   mTargetOrientation( Quaternion::IDENTITY ),
2065   mTargetColor( Color::WHITE ),
2066   mTargetSize( Vector3::ZERO ),
2067   mTargetPosition( Vector3::ZERO ),
2068   mTargetScale( Vector3::ONE ),
2069   mAnimatedSize( Vector3::ZERO ),
2070   mName(),
2071   mSortedDepth( 0u ),
2072   mDepth( 0u ),
2073   mUseAnimatedSize( AnimatedSizeFlag::CLEAR ),
2074   mIsRoot( ROOT_LAYER == derivedType ),
2075   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2076   mIsOnStage( false ),
2077   mSensitive( true ),
2078   mLeaveRequired( false ),
2079   mKeyboardFocusable( false ),
2080   mDerivedRequiresTouch( false ),
2081   mDerivedRequiresHover( false ),
2082   mDerivedRequiresWheelEvent( false ),
2083   mOnStageSignalled( false ),
2084   mInsideOnSizeSet( false ),
2085   mInheritPosition( true ),
2086   mInheritOrientation( true ),
2087   mInheritScale( true ),
2088   mPositionUsesAnchorPoint( true ),
2089   mVisible( true ),
2090   mInheritLayoutDirection( true ),
2091   mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2092   mDrawMode( DrawMode::NORMAL ),
2093   mColorMode( Node::DEFAULT_COLOR_MODE ),
2094   mClippingMode( ClippingMode::DISABLED )
2095 {
2096 }
2097
2098 void Actor::Initialize()
2099 {
2100   OnInitialize();
2101
2102   GetEventThreadServices().RegisterObject( this );
2103 }
2104
2105 Actor::~Actor()
2106 {
2107   // Remove mParent pointers from children even if we're destroying core,
2108   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2109   if( mChildren )
2110   {
2111     ActorConstIter endIter = mChildren->end();
2112     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2113     {
2114       (*iter)->SetParent( NULL );
2115     }
2116   }
2117   delete mChildren;
2118   delete mRenderers;
2119
2120   // Guard to allow handle destruction after Core has been destroyed
2121   if( EventThreadServices::IsCoreRunning() )
2122   {
2123     // Root layer will destroy its node in its own destructor
2124     if ( !mIsRoot )
2125     {
2126       DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2127
2128       GetEventThreadServices().UnregisterObject( this );
2129     }
2130   }
2131
2132   // Cleanup optional gesture data
2133   delete mGestureData;
2134
2135   // Cleanup optional parent origin and anchor
2136   delete mParentOrigin;
2137   delete mAnchorPoint;
2138
2139   // Delete optional relayout data
2140   delete mRelayoutData;
2141 }
2142
2143 void Actor::ConnectToStage( uint32_t parentDepth )
2144 {
2145   // This container is used instead of walking the Actor hierarchy.
2146   // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2147   ActorContainer connectionList;
2148
2149   if( mScene )
2150   {
2151     mScene->RequestRebuildDepthTree();
2152   }
2153
2154   // This stage is atomic i.e. not interrupted by user callbacks.
2155   RecursiveConnectToStage( connectionList, parentDepth + 1 );
2156
2157   // Notify applications about the newly connected actors.
2158   const ActorIter endIter = connectionList.end();
2159   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2160   {
2161     (*iter)->NotifyStageConnection();
2162   }
2163
2164   RelayoutRequest();
2165 }
2166
2167 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2168 {
2169   DALI_ASSERT_ALWAYS( !OnStage() );
2170
2171   mIsOnStage = true;
2172   mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2173
2174   ConnectToSceneGraph();
2175
2176   // Notification for internal derived classes
2177   OnStageConnectionInternal();
2178
2179   // This stage is atomic; avoid emitting callbacks until all Actors are connected
2180   connectionList.push_back( ActorPtr( this ) );
2181
2182   // Recursively connect children
2183   if( mChildren )
2184   {
2185     ActorConstIter endIter = mChildren->end();
2186     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2187     {
2188       (*iter)->SetScene( *mScene );
2189       (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2190     }
2191   }
2192 }
2193
2194 /**
2195  * This method is called when the Actor is connected to the Stage.
2196  * The parent must have added its Node to the scene-graph.
2197  * The child must connect its Node to the parent's Node.
2198  * This is recursive; the child calls ConnectToStage() for its children.
2199  */
2200 void Actor::ConnectToSceneGraph()
2201 {
2202   DALI_ASSERT_DEBUG( mParent != NULL);
2203
2204   // Reparent Node in next Update
2205   ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2206
2207   // Request relayout on all actors that are added to the scenegraph
2208   RelayoutRequest();
2209
2210   // Notification for Object::Observers
2211   OnSceneObjectAdd();
2212 }
2213
2214 void Actor::NotifyStageConnection()
2215 {
2216   // Actors can be removed (in a callback), before the on-stage stage is reported.
2217   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2218   if( OnStage() && !mOnStageSignalled )
2219   {
2220     // Notification for external (CustomActor) derived classes
2221     OnStageConnectionExternal( mDepth );
2222
2223     if( !mOnStageSignal.Empty() )
2224     {
2225       Dali::Actor handle( this );
2226       mOnStageSignal.Emit( handle );
2227     }
2228
2229     // Guard against Remove during callbacks
2230     if( OnStage() )
2231     {
2232       mOnStageSignalled = true; // signal required next time Actor is removed
2233     }
2234   }
2235 }
2236
2237 void Actor::DisconnectFromStage()
2238 {
2239   // This container is used instead of walking the Actor hierachy.
2240   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2241   ActorContainer disconnectionList;
2242
2243   if( mScene )
2244   {
2245     mScene->RequestRebuildDepthTree();
2246   }
2247
2248   // This stage is atomic i.e. not interrupted by user callbacks
2249   RecursiveDisconnectFromStage( disconnectionList );
2250
2251   // Notify applications about the newly disconnected actors.
2252   const ActorIter endIter = disconnectionList.end();
2253   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2254   {
2255     (*iter)->NotifyStageDisconnection();
2256   }
2257 }
2258
2259 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2260 {
2261   // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2262   mIsOnStage = false;
2263
2264   // Recursively disconnect children
2265   if( mChildren )
2266   {
2267     ActorConstIter endIter = mChildren->end();
2268     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2269     {
2270       (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2271     }
2272   }
2273
2274   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2275   disconnectionList.push_back( ActorPtr( this ) );
2276
2277   // Notification for internal derived classes
2278   OnStageDisconnectionInternal();
2279
2280   DisconnectFromSceneGraph();
2281 }
2282
2283 /**
2284  * This method is called by an actor or its parent, before a node removal message is sent.
2285  * This is recursive; the child calls DisconnectFromStage() for its children.
2286  */
2287 void Actor::DisconnectFromSceneGraph()
2288 {
2289   // Notification for Object::Observers
2290   OnSceneObjectRemove();
2291 }
2292
2293 void Actor::NotifyStageDisconnection()
2294 {
2295   // Actors can be added (in a callback), before the off-stage state is reported.
2296   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2297   // only do this step if there is a stage, i.e. Core is not being shut down
2298   if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2299   {
2300     // Notification for external (CustomeActor) derived classes
2301     OnStageDisconnectionExternal();
2302
2303     if( !mOffStageSignal.Empty() )
2304     {
2305       Dali::Actor handle( this );
2306       mOffStageSignal.Emit( handle );
2307     }
2308
2309     // Guard against Add during callbacks
2310     if( !OnStage() )
2311     {
2312       mOnStageSignalled = false; // signal required next time Actor is added
2313     }
2314   }
2315 }
2316
2317 bool Actor::IsNodeConnected() const
2318 {
2319   bool connected( false );
2320
2321   if( OnStage() )
2322   {
2323     if( IsRoot() || GetNode().GetParent() )
2324     {
2325       connected = true;
2326     }
2327   }
2328
2329   return connected;
2330 }
2331
2332 // This method initiates traversal of the actor tree using depth-first
2333 // traversal to set a depth index based on traversal order. It sends a
2334 // single message to update manager to update all the actor's nodes in
2335 // this tree with the depth index. The sceneGraphNodeDepths vector's
2336 // elements are ordered by depth, and could be used to reduce sorting
2337 // in the update thread.
2338 void Actor::RebuildDepthTree()
2339 {
2340   DALI_LOG_TIMER_START(depthTimer);
2341
2342   // Vector of scene-graph nodes and their depths to send to UpdateManager
2343   // in a single message
2344   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2345
2346   int32_t depthIndex = 1;
2347   DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2348
2349   SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2350   DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2351 }
2352
2353 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2354 {
2355   mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2356   sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2357
2358   // Create/add to children of this node
2359   if( mChildren )
2360   {
2361     for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2362     {
2363       Actor* childActor = (*it).Get();
2364       ++depthIndex;
2365       childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2366     }
2367   }
2368 }
2369
2370 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2371 {
2372   switch( index )
2373   {
2374     case Dali::Actor::Property::PARENT_ORIGIN:
2375     {
2376       Property::Type type = property.GetType();
2377       if( type == Property::VECTOR3 )
2378       {
2379         SetParentOrigin( property.Get< Vector3 >() );
2380       }
2381       else if ( type == Property::STRING )
2382       {
2383         std::string parentOriginString;
2384         property.Get( parentOriginString );
2385         Vector3 parentOrigin;
2386         if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2387         {
2388           SetParentOrigin( parentOrigin );
2389         }
2390       }
2391       break;
2392     }
2393
2394     case Dali::Actor::Property::PARENT_ORIGIN_X:
2395     {
2396       SetParentOriginX( property.Get< float >() );
2397       break;
2398     }
2399
2400     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2401     {
2402       SetParentOriginY( property.Get< float >() );
2403       break;
2404     }
2405
2406     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2407     {
2408       SetParentOriginZ( property.Get< float >() );
2409       break;
2410     }
2411
2412     case Dali::Actor::Property::ANCHOR_POINT:
2413     {
2414       Property::Type type = property.GetType();
2415       if( type == Property::VECTOR3 )
2416       {
2417         SetAnchorPoint( property.Get< Vector3 >() );
2418       }
2419       else if ( type == Property::STRING )
2420       {
2421         std::string anchorPointString;
2422         property.Get( anchorPointString );
2423         Vector3 anchor;
2424         if( GetAnchorPointConstant( anchorPointString, anchor ) )
2425         {
2426           SetAnchorPoint( anchor );
2427         }
2428       }
2429       break;
2430     }
2431
2432     case Dali::Actor::Property::ANCHOR_POINT_X:
2433     {
2434       SetAnchorPointX( property.Get< float >() );
2435       break;
2436     }
2437
2438     case Dali::Actor::Property::ANCHOR_POINT_Y:
2439     {
2440       SetAnchorPointY( property.Get< float >() );
2441       break;
2442     }
2443
2444     case Dali::Actor::Property::ANCHOR_POINT_Z:
2445     {
2446       SetAnchorPointZ( property.Get< float >() );
2447       break;
2448     }
2449
2450     case Dali::Actor::Property::SIZE:
2451     {
2452       Property::Type type = property.GetType();
2453       if( type == Property::VECTOR2 )
2454       {
2455         SetSize( property.Get< Vector2 >() );
2456       }
2457       else if ( type == Property::VECTOR3 )
2458       {
2459         SetSize( property.Get< Vector3 >() );
2460       }
2461       break;
2462     }
2463
2464     case Dali::Actor::Property::SIZE_WIDTH:
2465     {
2466       SetWidth( property.Get< float >() );
2467       break;
2468     }
2469
2470     case Dali::Actor::Property::SIZE_HEIGHT:
2471     {
2472       SetHeight( property.Get< float >() );
2473       break;
2474     }
2475
2476     case Dali::Actor::Property::SIZE_DEPTH:
2477     {
2478       SetDepth( property.Get< float >() );
2479       break;
2480     }
2481
2482     case Dali::Actor::Property::POSITION:
2483     {
2484       Property::Type type = property.GetType();
2485       if( type == Property::VECTOR2 )
2486       {
2487         Vector2 position = property.Get< Vector2 >();
2488         SetPosition( Vector3( position.x, position.y, 0.0f ) );
2489       }
2490       else if ( type == Property::VECTOR3 )
2491       {
2492         SetPosition( property.Get< Vector3 >() );
2493       }
2494       break;
2495     }
2496
2497     case Dali::Actor::Property::POSITION_X:
2498     {
2499       SetX( property.Get< float >() );
2500       break;
2501     }
2502
2503     case Dali::Actor::Property::POSITION_Y:
2504     {
2505       SetY( property.Get< float >() );
2506       break;
2507     }
2508
2509     case Dali::Actor::Property::POSITION_Z:
2510     {
2511       SetZ( property.Get< float >() );
2512       break;
2513     }
2514
2515     case Dali::Actor::Property::ORIENTATION:
2516     {
2517       SetOrientation( property.Get< Quaternion >() );
2518       break;
2519     }
2520
2521     case Dali::Actor::Property::SCALE:
2522     {
2523       Property::Type type = property.GetType();
2524       if( type == Property::FLOAT )
2525       {
2526         float scale = property.Get< float >();
2527         SetScale( scale, scale, scale );
2528       }
2529       else if ( type == Property::VECTOR3 )
2530       {
2531         SetScale( property.Get< Vector3 >() );
2532       }
2533       break;
2534     }
2535
2536     case Dali::Actor::Property::SCALE_X:
2537     {
2538       SetScaleX( property.Get< float >() );
2539       break;
2540     }
2541
2542     case Dali::Actor::Property::SCALE_Y:
2543     {
2544       SetScaleY( property.Get< float >() );
2545       break;
2546     }
2547
2548     case Dali::Actor::Property::SCALE_Z:
2549     {
2550       SetScaleZ( property.Get< float >() );
2551       break;
2552     }
2553
2554     case Dali::Actor::Property::VISIBLE:
2555     {
2556       SetVisible( property.Get< bool >() );
2557       break;
2558     }
2559
2560     case Dali::Actor::Property::COLOR:
2561     {
2562       Property::Type type = property.GetType();
2563       if( type == Property::VECTOR3 )
2564       {
2565         Vector3 color = property.Get< Vector3 >();
2566         SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2567       }
2568       else if( type == Property::VECTOR4 )
2569       {
2570         SetColor( property.Get< Vector4 >() );
2571       }
2572       break;
2573     }
2574
2575     case Dali::Actor::Property::COLOR_RED:
2576     {
2577       SetColorRed( property.Get< float >() );
2578       break;
2579     }
2580
2581     case Dali::Actor::Property::COLOR_GREEN:
2582     {
2583       SetColorGreen( property.Get< float >() );
2584       break;
2585     }
2586
2587     case Dali::Actor::Property::COLOR_BLUE:
2588     {
2589       SetColorBlue( property.Get< float >() );
2590       break;
2591     }
2592
2593     case Dali::Actor::Property::COLOR_ALPHA:
2594     case Dali::Actor::Property::OPACITY:
2595     {
2596       float value;
2597       if( property.Get( value ) )
2598       {
2599         SetOpacity( value );
2600       }
2601       break;
2602     }
2603
2604     case Dali::Actor::Property::NAME:
2605     {
2606       SetName( property.Get< std::string >() );
2607       break;
2608     }
2609
2610     case Dali::Actor::Property::SENSITIVE:
2611     {
2612       SetSensitive( property.Get< bool >() );
2613       break;
2614     }
2615
2616     case Dali::Actor::Property::LEAVE_REQUIRED:
2617     {
2618       SetLeaveRequired( property.Get< bool >() );
2619       break;
2620     }
2621
2622     case Dali::Actor::Property::INHERIT_POSITION:
2623     {
2624       SetInheritPosition( property.Get< bool >() );
2625       break;
2626     }
2627
2628     case Dali::Actor::Property::INHERIT_ORIENTATION:
2629     {
2630       SetInheritOrientation( property.Get< bool >() );
2631       break;
2632     }
2633
2634     case Dali::Actor::Property::INHERIT_SCALE:
2635     {
2636       SetInheritScale( property.Get< bool >() );
2637       break;
2638     }
2639
2640     case Dali::Actor::Property::COLOR_MODE:
2641     {
2642       ColorMode mode = mColorMode;
2643       if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2644       {
2645         SetColorMode( mode );
2646       }
2647       break;
2648     }
2649
2650     case Dali::Actor::Property::DRAW_MODE:
2651     {
2652       DrawMode::Type mode = mDrawMode;
2653       if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2654       {
2655         SetDrawMode( mode );
2656       }
2657       break;
2658     }
2659
2660     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2661     {
2662       SetSizeModeFactor( property.Get< Vector3 >() );
2663       break;
2664     }
2665
2666     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2667     {
2668       ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2669       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2670       {
2671         SetResizePolicy( type, Dimension::WIDTH );
2672       }
2673       break;
2674     }
2675
2676     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2677     {
2678       ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2679       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2680       {
2681         SetResizePolicy( type, Dimension::HEIGHT );
2682       }
2683       break;
2684     }
2685
2686     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2687     {
2688       SizeScalePolicy::Type type = GetSizeScalePolicy();
2689       if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2690       {
2691         SetSizeScalePolicy( type );
2692       }
2693       break;
2694     }
2695
2696     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2697     {
2698       if( property.Get< bool >() )
2699       {
2700         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2701       }
2702       break;
2703     }
2704
2705     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2706     {
2707       if( property.Get< bool >() )
2708       {
2709         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2710       }
2711       break;
2712     }
2713
2714     case Dali::Actor::Property::PADDING:
2715     {
2716       Vector4 padding = property.Get< Vector4 >();
2717       SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2718       SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2719       break;
2720     }
2721
2722     case Dali::Actor::Property::MINIMUM_SIZE:
2723     {
2724       Vector2 size = property.Get< Vector2 >();
2725       SetMinimumSize( size.x, Dimension::WIDTH );
2726       SetMinimumSize( size.y, Dimension::HEIGHT );
2727       break;
2728     }
2729
2730     case Dali::Actor::Property::MAXIMUM_SIZE:
2731     {
2732       Vector2 size = property.Get< Vector2 >();
2733       SetMaximumSize( size.x, Dimension::WIDTH );
2734       SetMaximumSize( size.y, Dimension::HEIGHT );
2735       break;
2736     }
2737
2738     case Dali::DevelActor::Property::SIBLING_ORDER:
2739     {
2740       int value;
2741
2742       if( property.Get( value ) )
2743       {
2744         SetSiblingOrder( value );
2745       }
2746       break;
2747     }
2748
2749     case Dali::Actor::Property::CLIPPING_MODE:
2750     {
2751       ClippingMode::Type convertedValue = mClippingMode;
2752       if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2753       {
2754         mClippingMode = convertedValue;
2755         SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2756       }
2757       break;
2758     }
2759
2760     case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
2761     {
2762       bool value = false;
2763       if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2764       {
2765         mPositionUsesAnchorPoint = value;
2766         SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2767       }
2768       break;
2769     }
2770
2771     case Dali::Actor::Property::LAYOUT_DIRECTION:
2772     {
2773       Dali::LayoutDirection::Type direction = mLayoutDirection;
2774       mInheritLayoutDirection = false;
2775
2776       if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2777       {
2778         InheritLayoutDirectionRecursively( this, direction, true );
2779       }
2780       break;
2781     }
2782
2783     case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2784     {
2785       bool value = false;
2786       if( property.Get( value ) )
2787       {
2788         SetInheritLayoutDirection( value );
2789       }
2790       break;
2791     }
2792
2793     case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
2794     {
2795       bool value = false;
2796       if( property.Get( value ) )
2797       {
2798         SetKeyboardFocusable( value );
2799       }
2800       break;
2801     }
2802
2803     default:
2804     {
2805       // this can happen in the case of a non-animatable default property so just do nothing
2806       break;
2807     }
2808   }
2809 }
2810
2811 // TODO: This method needs to be removed
2812 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2813 {
2814   switch( entry.GetType() )
2815   {
2816     case Property::BOOLEAN:
2817     {
2818       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2819       DALI_ASSERT_DEBUG( NULL != property );
2820
2821       // property is being used in a separate thread; queue a message to set the property
2822       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2823
2824       break;
2825     }
2826
2827     case Property::INTEGER:
2828     {
2829       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2830       DALI_ASSERT_DEBUG( NULL != property );
2831
2832       // property is being used in a separate thread; queue a message to set the property
2833       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2834
2835       break;
2836     }
2837
2838     case Property::FLOAT:
2839     {
2840       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2841       DALI_ASSERT_DEBUG( NULL != property );
2842
2843       // property is being used in a separate thread; queue a message to set the property
2844       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2845
2846       break;
2847     }
2848
2849     case Property::VECTOR2:
2850     {
2851       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2852       DALI_ASSERT_DEBUG( NULL != property );
2853
2854       // property is being used in a separate thread; queue a message to set the property
2855       if(entry.componentIndex == 0)
2856       {
2857         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2858       }
2859       else if(entry.componentIndex == 1)
2860       {
2861         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2862       }
2863       else
2864       {
2865         SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2866       }
2867
2868       break;
2869     }
2870
2871     case Property::VECTOR3:
2872     {
2873       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2874       DALI_ASSERT_DEBUG( NULL != property );
2875
2876       // property is being used in a separate thread; queue a message to set the property
2877       if(entry.componentIndex == 0)
2878       {
2879         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2880       }
2881       else if(entry.componentIndex == 1)
2882       {
2883         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2884       }
2885       else if(entry.componentIndex == 2)
2886       {
2887         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2888       }
2889       else
2890       {
2891         SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2892       }
2893
2894       break;
2895     }
2896
2897     case Property::VECTOR4:
2898     {
2899       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2900       DALI_ASSERT_DEBUG( NULL != property );
2901
2902       // property is being used in a separate thread; queue a message to set the property
2903       if(entry.componentIndex == 0)
2904       {
2905         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2906       }
2907       else if(entry.componentIndex == 1)
2908       {
2909         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2910       }
2911       else if(entry.componentIndex == 2)
2912       {
2913         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2914       }
2915       else if(entry.componentIndex == 3)
2916       {
2917         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2918       }
2919       else
2920       {
2921         SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2922       }
2923
2924       break;
2925     }
2926
2927     case Property::ROTATION:
2928     {
2929       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2930       DALI_ASSERT_DEBUG( NULL != property );
2931
2932       // property is being used in a separate thread; queue a message to set the property
2933       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
2934
2935       break;
2936     }
2937
2938     case Property::MATRIX:
2939     {
2940       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2941       DALI_ASSERT_DEBUG( NULL != property );
2942
2943       // property is being used in a separate thread; queue a message to set the property
2944       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
2945
2946       break;
2947     }
2948
2949     case Property::MATRIX3:
2950     {
2951       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2952       DALI_ASSERT_DEBUG( NULL != property );
2953
2954       // property is being used in a separate thread; queue a message to set the property
2955       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
2956
2957       break;
2958     }
2959
2960     default:
2961     {
2962       // nothing to do for other types
2963     }
2964   } // entry.GetType
2965 }
2966
2967 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2968 {
2969   Property::Value value;
2970
2971   if( ! GetCachedPropertyValue( index, value ) )
2972   {
2973     // If property value is not stored in the event-side, then it must be a scene-graph only property
2974     GetCurrentPropertyValue( index, value );
2975   }
2976
2977   return value;
2978 }
2979
2980 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2981 {
2982   Property::Value value;
2983
2984   if( ! GetCurrentPropertyValue( index, value ) )
2985   {
2986     // If unable to retrieve scene-graph property value, then it must be an event-side only property
2987     GetCachedPropertyValue( index, value );
2988   }
2989
2990   return value;
2991 }
2992
2993 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2994 {
2995   switch( animationType )
2996   {
2997     case Animation::TO:
2998     case Animation::BETWEEN:
2999     {
3000       switch( index )
3001       {
3002         case Dali::Actor::Property::SIZE:
3003         {
3004           if( value.Get( mTargetSize ) )
3005           {
3006             mAnimatedSize = mTargetSize;
3007             mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3008
3009             // Notify deriving classes
3010             OnSizeAnimation( animation, mTargetSize );
3011           }
3012           break;
3013         }
3014
3015         case Dali::Actor::Property::SIZE_WIDTH:
3016         {
3017           if( value.Get( mTargetSize.width ) )
3018           {
3019             mAnimatedSize.width = mTargetSize.width;
3020             mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3021
3022             // Notify deriving classes
3023             OnSizeAnimation( animation, mTargetSize );
3024           }
3025           break;
3026         }
3027
3028         case Dali::Actor::Property::SIZE_HEIGHT:
3029         {
3030           if( value.Get( mTargetSize.height ) )
3031           {
3032             mAnimatedSize.height = mTargetSize.height;
3033             mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3034
3035             // Notify deriving classes
3036             OnSizeAnimation( animation, mTargetSize );
3037           }
3038           break;
3039         }
3040
3041         case Dali::Actor::Property::SIZE_DEPTH:
3042         {
3043           if( value.Get( mTargetSize.depth ) )
3044           {
3045             mAnimatedSize.depth = mTargetSize.depth;
3046             mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3047
3048             // Notify deriving classes
3049             OnSizeAnimation( animation, mTargetSize );
3050           }
3051           break;
3052         }
3053
3054         case Dali::Actor::Property::POSITION:
3055         {
3056           value.Get( mTargetPosition );
3057           break;
3058         }
3059
3060         case Dali::Actor::Property::POSITION_X:
3061         {
3062           value.Get( mTargetPosition.x );
3063           break;
3064         }
3065
3066         case Dali::Actor::Property::POSITION_Y:
3067         {
3068           value.Get( mTargetPosition.y );
3069           break;
3070         }
3071
3072         case Dali::Actor::Property::POSITION_Z:
3073         {
3074           value.Get( mTargetPosition.z );
3075           break;
3076         }
3077
3078         case Dali::Actor::Property::ORIENTATION:
3079         {
3080           value.Get( mTargetOrientation );
3081           break;
3082         }
3083
3084         case Dali::Actor::Property::SCALE:
3085         {
3086           value.Get( mTargetScale );
3087           break;
3088         }
3089
3090         case Dali::Actor::Property::SCALE_X:
3091         {
3092           value.Get( mTargetScale.x );
3093           break;
3094         }
3095
3096         case Dali::Actor::Property::SCALE_Y:
3097         {
3098           value.Get( mTargetScale.y );
3099           break;
3100         }
3101
3102         case Dali::Actor::Property::SCALE_Z:
3103         {
3104           value.Get( mTargetScale.z );
3105           break;
3106         }
3107
3108         case Dali::Actor::Property::VISIBLE:
3109         {
3110           SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3111           break;
3112         }
3113
3114         case Dali::Actor::Property::COLOR:
3115         {
3116           value.Get( mTargetColor );
3117           break;
3118         }
3119
3120         case Dali::Actor::Property::COLOR_RED:
3121         {
3122           value.Get( mTargetColor.r );
3123           break;
3124         }
3125
3126         case Dali::Actor::Property::COLOR_GREEN:
3127         {
3128           value.Get( mTargetColor.g );
3129           break;
3130         }
3131
3132         case Dali::Actor::Property::COLOR_BLUE:
3133         {
3134           value.Get( mTargetColor.b );
3135           break;
3136         }
3137
3138         case Dali::Actor::Property::COLOR_ALPHA:
3139         case Dali::Actor::Property::OPACITY:
3140         {
3141           value.Get( mTargetColor.a );
3142           break;
3143         }
3144
3145         default:
3146         {
3147           // Not an animatable property. Do nothing.
3148           break;
3149         }
3150       }
3151       break;
3152     }
3153
3154     case Animation::BY:
3155     {
3156       switch( index )
3157       {
3158         case Dali::Actor::Property::SIZE:
3159         {
3160           if( AdjustValue< Vector3 >( mTargetSize, value ) )
3161           {
3162             mAnimatedSize = mTargetSize;
3163             mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3164
3165             // Notify deriving classes
3166             OnSizeAnimation( animation, mTargetSize );
3167           }
3168           break;
3169         }
3170
3171         case Dali::Actor::Property::SIZE_WIDTH:
3172         {
3173           if( AdjustValue< float >( mTargetSize.width, value ) )
3174           {
3175             mAnimatedSize.width = mTargetSize.width;
3176             mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3177
3178             // Notify deriving classes
3179             OnSizeAnimation( animation, mTargetSize );
3180           }
3181           break;
3182         }
3183
3184         case Dali::Actor::Property::SIZE_HEIGHT:
3185         {
3186           if( AdjustValue< float >( mTargetSize.height, value ) )
3187           {
3188             mAnimatedSize.height = mTargetSize.height;
3189             mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3190
3191             // Notify deriving classes
3192             OnSizeAnimation( animation, mTargetSize );
3193           }
3194           break;
3195         }
3196
3197         case Dali::Actor::Property::SIZE_DEPTH:
3198         {
3199           if( AdjustValue< float >( mTargetSize.depth, value ) )
3200           {
3201             mAnimatedSize.depth = mTargetSize.depth;
3202             mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3203
3204             // Notify deriving classes
3205             OnSizeAnimation( animation, mTargetSize );
3206           }
3207           break;
3208         }
3209
3210         case Dali::Actor::Property::POSITION:
3211         {
3212           AdjustValue< Vector3 >( mTargetPosition, value );
3213           break;
3214         }
3215
3216         case Dali::Actor::Property::POSITION_X:
3217         {
3218           AdjustValue< float >( mTargetPosition.x, value );
3219           break;
3220         }
3221
3222         case Dali::Actor::Property::POSITION_Y:
3223         {
3224           AdjustValue< float >( mTargetPosition.y, value );
3225           break;
3226         }
3227
3228         case Dali::Actor::Property::POSITION_Z:
3229         {
3230           AdjustValue< float >( mTargetPosition.z, value );
3231           break;
3232         }
3233
3234         case Dali::Actor::Property::ORIENTATION:
3235         {
3236           Quaternion relativeValue;
3237           if( value.Get( relativeValue ) )
3238           {
3239             mTargetOrientation *= relativeValue;
3240           }
3241           break;
3242         }
3243
3244         case Dali::Actor::Property::SCALE:
3245         {
3246           AdjustValue< Vector3 >( mTargetScale, value );
3247           break;
3248         }
3249
3250         case Dali::Actor::Property::SCALE_X:
3251         {
3252           AdjustValue< float >( mTargetScale.x, value );
3253           break;
3254         }
3255
3256         case Dali::Actor::Property::SCALE_Y:
3257         {
3258           AdjustValue< float >( mTargetScale.y, value );
3259           break;
3260         }
3261
3262         case Dali::Actor::Property::SCALE_Z:
3263         {
3264           AdjustValue< float >( mTargetScale.z, value );
3265           break;
3266         }
3267
3268         case Dali::Actor::Property::VISIBLE:
3269         {
3270           bool relativeValue = false;
3271           if( value.Get( relativeValue ) )
3272           {
3273             bool visible = mVisible || relativeValue;
3274             SetVisibleInternal( visible, SendMessage::FALSE );
3275           }
3276           break;
3277         }
3278
3279         case Dali::Actor::Property::COLOR:
3280         {
3281           AdjustValue< Vector4 >( mTargetColor, value );
3282           break;
3283         }
3284
3285         case Dali::Actor::Property::COLOR_RED:
3286         {
3287           AdjustValue< float >( mTargetColor.r, value );
3288           break;
3289         }
3290
3291         case Dali::Actor::Property::COLOR_GREEN:
3292         {
3293           AdjustValue< float >( mTargetColor.g, value );
3294           break;
3295         }
3296
3297         case Dali::Actor::Property::COLOR_BLUE:
3298         {
3299           AdjustValue< float >( mTargetColor.b, value );
3300           break;
3301         }
3302
3303         case Dali::Actor::Property::COLOR_ALPHA:
3304         case Dali::Actor::Property::OPACITY:
3305         {
3306           AdjustValue< float >( mTargetColor.a, value );
3307           break;
3308         }
3309
3310         default:
3311         {
3312           // Not an animatable property. Do nothing.
3313           break;
3314         }
3315       }
3316       break;
3317     }
3318   }
3319 }
3320
3321 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3322 {
3323   const PropertyBase* property( NULL );
3324
3325   switch( index )
3326   {
3327     case Dali::Actor::Property::SIZE:        // FALLTHROUGH
3328     case Dali::Actor::Property::SIZE_WIDTH:  // FALLTHROUGH
3329     case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3330     case Dali::Actor::Property::SIZE_DEPTH:
3331     {
3332       property = &GetNode().mSize;
3333       break;
3334     }
3335     case Dali::Actor::Property::POSITION:   // FALLTHROUGH
3336     case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3337     case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3338     case Dali::Actor::Property::POSITION_Z:
3339     {
3340       property = &GetNode().mPosition;
3341       break;
3342     }
3343     case Dali::Actor::Property::ORIENTATION:
3344     {
3345       property = &GetNode().mOrientation;
3346       break;
3347     }
3348     case Dali::Actor::Property::SCALE:   // FALLTHROUGH
3349     case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3350     case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3351     case Dali::Actor::Property::SCALE_Z:
3352     {
3353       property = &GetNode().mScale;
3354       break;
3355     }
3356     case Dali::Actor::Property::VISIBLE:
3357     {
3358       property = &GetNode().mVisible;
3359       break;
3360     }
3361     case Dali::Actor::Property::COLOR:       // FALLTHROUGH
3362     case Dali::Actor::Property::COLOR_RED:   // FALLTHROUGH
3363     case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3364     case Dali::Actor::Property::COLOR_BLUE:  // FALLTHROUGH
3365     case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3366     case Dali::Actor::Property::OPACITY:
3367     {
3368       property = &GetNode().mColor;
3369       break;
3370     }
3371     default:
3372     {
3373       break;
3374     }
3375   }
3376   if( !property )
3377   {
3378     // not our property, ask base
3379     property = Object::GetSceneObjectAnimatableProperty( index );
3380   }
3381
3382   return property;
3383 }
3384
3385 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3386 {
3387   const PropertyInputImpl* property( NULL );
3388
3389   switch( index )
3390   {
3391     case Dali::Actor::Property::PARENT_ORIGIN:   // FALLTHROUGH
3392     case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3393     case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3394     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3395     {
3396       property = &GetNode().mParentOrigin;
3397       break;
3398     }
3399     case Dali::Actor::Property::ANCHOR_POINT:   // FALLTHROUGH
3400     case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3401     case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3402     case Dali::Actor::Property::ANCHOR_POINT_Z:
3403     {
3404       property = &GetNode().mAnchorPoint;
3405       break;
3406     }
3407     case Dali::Actor::Property::WORLD_POSITION:   // FALLTHROUGH
3408     case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3409     case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3410     case Dali::Actor::Property::WORLD_POSITION_Z:
3411     {
3412       property = &GetNode().mWorldPosition;
3413       break;
3414     }
3415     case Dali::Actor::Property::WORLD_ORIENTATION:
3416     {
3417       property = &GetNode().mWorldOrientation;
3418       break;
3419     }
3420     case Dali::Actor::Property::WORLD_SCALE:
3421     {
3422       property = &GetNode().mWorldScale;
3423       break;
3424     }
3425     case Dali::Actor::Property::WORLD_COLOR:
3426     {
3427       property = &GetNode().mWorldColor;
3428       break;
3429     }
3430     case Dali::Actor::Property::WORLD_MATRIX:
3431     {
3432       property = &GetNode().mWorldMatrix;
3433       break;
3434     }
3435     case Dali::Actor::Property::CULLED:
3436     {
3437       property = &GetNode().mCulled;
3438       break;
3439     }
3440     default:
3441     {
3442       break;
3443     }
3444   }
3445   if( !property )
3446   {
3447     // reuse animatable property getter as animatable properties are inputs as well
3448     // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3449     property = GetSceneObjectAnimatableProperty( index );
3450   }
3451
3452   return property;
3453 }
3454
3455 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3456 {
3457   int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3458
3459   switch( index )
3460   {
3461     case Dali::Actor::Property::PARENT_ORIGIN_X:
3462     case Dali::Actor::Property::ANCHOR_POINT_X:
3463     case Dali::Actor::Property::SIZE_WIDTH:
3464     case Dali::Actor::Property::POSITION_X:
3465     case Dali::Actor::Property::WORLD_POSITION_X:
3466     case Dali::Actor::Property::SCALE_X:
3467     case Dali::Actor::Property::COLOR_RED:
3468     {
3469       componentIndex = 0;
3470       break;
3471     }
3472
3473     case Dali::Actor::Property::PARENT_ORIGIN_Y:
3474     case Dali::Actor::Property::ANCHOR_POINT_Y:
3475     case Dali::Actor::Property::SIZE_HEIGHT:
3476     case Dali::Actor::Property::POSITION_Y:
3477     case Dali::Actor::Property::WORLD_POSITION_Y:
3478     case Dali::Actor::Property::SCALE_Y:
3479     case Dali::Actor::Property::COLOR_GREEN:
3480     {
3481       componentIndex = 1;
3482       break;
3483     }
3484
3485     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3486     case Dali::Actor::Property::ANCHOR_POINT_Z:
3487     case Dali::Actor::Property::SIZE_DEPTH:
3488     case Dali::Actor::Property::POSITION_Z:
3489     case Dali::Actor::Property::WORLD_POSITION_Z:
3490     case Dali::Actor::Property::SCALE_Z:
3491     case Dali::Actor::Property::COLOR_BLUE:
3492     {
3493       componentIndex = 2;
3494       break;
3495     }
3496
3497     case Dali::Actor::Property::COLOR_ALPHA:
3498     case Dali::Actor::Property::OPACITY:
3499     {
3500       componentIndex = 3;
3501       break;
3502     }
3503
3504     default:
3505     {
3506       // Do nothing
3507       break;
3508     }
3509   }
3510   if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3511   {
3512     // ask base
3513     componentIndex = Object::GetPropertyComponentIndex( index );
3514   }
3515
3516   return componentIndex;
3517 }
3518
3519 void Actor::SetParent( Actor* parent )
3520 {
3521   if( parent )
3522   {
3523     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3524
3525     mParent = parent;
3526
3527     mScene = parent->mScene;
3528
3529     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3530          parent->OnStage() )
3531     {
3532       // Instruct each actor to create a corresponding node in the scene graph
3533       ConnectToStage( parent->GetHierarchyDepth() );
3534     }
3535
3536     // Resolve the name and index for the child properties if any
3537     ResolveChildProperties();
3538   }
3539   else // parent being set to NULL
3540   {
3541     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3542
3543     mParent = NULL;
3544
3545     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3546          OnStage() )
3547     {
3548       // Disconnect the Node & its children from the scene-graph.
3549       DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3550
3551       // Instruct each actor to discard pointers to the scene-graph
3552       DisconnectFromStage();
3553     }
3554
3555     mScene = nullptr;
3556   }
3557 }
3558
3559 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3560 {
3561   bool done = false;
3562   Actor* actor = dynamic_cast< Actor* >( object );
3563
3564   if( actor )
3565   {
3566     if( 0 == actionName.compare( ACTION_SHOW ) )
3567     {
3568       actor->SetVisible( true );
3569       done = true;
3570     }
3571     else if( 0 == actionName.compare( ACTION_HIDE ) )
3572     {
3573       actor->SetVisible( false );
3574       done = true;
3575     }
3576   }
3577
3578   return done;
3579 }
3580
3581 Rect<> Actor::CalculateScreenExtents( ) const
3582 {
3583   auto screenPosition = GetCurrentScreenPosition();
3584   Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3585   Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3586   Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3587   return { position.x, position.y, size.x, size.y };
3588 }
3589
3590 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3591 {
3592   bool valueSet = true;
3593
3594   switch( index )
3595   {
3596     case Dali::Actor::Property::PARENT_ORIGIN:
3597     {
3598       value = GetCurrentParentOrigin();
3599       break;
3600     }
3601
3602     case Dali::Actor::Property::PARENT_ORIGIN_X:
3603     {
3604       value = GetCurrentParentOrigin().x;
3605       break;
3606     }
3607
3608     case Dali::Actor::Property::PARENT_ORIGIN_Y:
3609     {
3610       value = GetCurrentParentOrigin().y;
3611       break;
3612     }
3613
3614     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3615     {
3616       value = GetCurrentParentOrigin().z;
3617       break;
3618     }
3619
3620     case Dali::Actor::Property::ANCHOR_POINT:
3621     {
3622       value = GetCurrentAnchorPoint();
3623       break;
3624     }
3625
3626     case Dali::Actor::Property::ANCHOR_POINT_X:
3627     {
3628       value = GetCurrentAnchorPoint().x;
3629       break;
3630     }
3631
3632     case Dali::Actor::Property::ANCHOR_POINT_Y:
3633     {
3634       value = GetCurrentAnchorPoint().y;
3635       break;
3636     }
3637
3638     case Dali::Actor::Property::ANCHOR_POINT_Z:
3639     {
3640       value = GetCurrentAnchorPoint().z;
3641       break;
3642     }
3643
3644     case Dali::Actor::Property::SIZE:
3645     {
3646       value = GetTargetSize();
3647       break;
3648     }
3649
3650     case Dali::Actor::Property::SIZE_WIDTH:
3651     {
3652       value = GetTargetSize().width;
3653       break;
3654     }
3655
3656     case Dali::Actor::Property::SIZE_HEIGHT:
3657     {
3658       value = GetTargetSize().height;
3659       break;
3660     }
3661
3662     case Dali::Actor::Property::SIZE_DEPTH:
3663     {
3664       value = GetTargetSize().depth;
3665       break;
3666     }
3667
3668     case Dali::Actor::Property::POSITION:
3669     {
3670       value = GetTargetPosition();
3671       break;
3672     }
3673
3674     case Dali::Actor::Property::POSITION_X:
3675     {
3676       value = GetTargetPosition().x;
3677       break;
3678     }
3679
3680     case Dali::Actor::Property::POSITION_Y:
3681     {
3682       value = GetTargetPosition().y;
3683       break;
3684     }
3685
3686     case Dali::Actor::Property::POSITION_Z:
3687     {
3688       value = GetTargetPosition().z;
3689       break;
3690     }
3691
3692     case Dali::Actor::Property::ORIENTATION:
3693     {
3694       value = mTargetOrientation;
3695       break;
3696     }
3697
3698     case Dali::Actor::Property::SCALE:
3699     {
3700       value = mTargetScale;
3701       break;
3702     }
3703
3704     case Dali::Actor::Property::SCALE_X:
3705     {
3706       value = mTargetScale.x;
3707       break;
3708     }
3709
3710     case Dali::Actor::Property::SCALE_Y:
3711     {
3712       value = mTargetScale.y;
3713       break;
3714     }
3715
3716     case Dali::Actor::Property::SCALE_Z:
3717     {
3718       value = mTargetScale.z;
3719       break;
3720     }
3721
3722     case Dali::Actor::Property::VISIBLE:
3723     {
3724       value = mVisible;
3725       break;
3726     }
3727
3728     case Dali::Actor::Property::COLOR:
3729     {
3730       value = mTargetColor;
3731       break;
3732     }
3733
3734     case Dali::Actor::Property::COLOR_RED:
3735     {
3736       value = mTargetColor.r;
3737       break;
3738     }
3739
3740     case Dali::Actor::Property::COLOR_GREEN:
3741     {
3742       value = mTargetColor.g;
3743       break;
3744     }
3745
3746     case Dali::Actor::Property::COLOR_BLUE:
3747     {
3748       value = mTargetColor.b;
3749       break;
3750     }
3751
3752     case Dali::Actor::Property::COLOR_ALPHA:
3753     case Dali::Actor::Property::OPACITY:
3754     {
3755       value = mTargetColor.a;
3756       break;
3757     }
3758
3759     case Dali::Actor::Property::NAME:
3760     {
3761       value = GetName();
3762       break;
3763     }
3764
3765     case Dali::Actor::Property::SENSITIVE:
3766     {
3767       value = IsSensitive();
3768       break;
3769     }
3770
3771     case Dali::Actor::Property::LEAVE_REQUIRED:
3772     {
3773       value = GetLeaveRequired();
3774       break;
3775     }
3776
3777     case Dali::Actor::Property::INHERIT_POSITION:
3778     {
3779       value = IsPositionInherited();
3780       break;
3781     }
3782
3783     case Dali::Actor::Property::INHERIT_ORIENTATION:
3784     {
3785       value = IsOrientationInherited();
3786       break;
3787     }
3788
3789     case Dali::Actor::Property::INHERIT_SCALE:
3790     {
3791       value = IsScaleInherited();
3792       break;
3793     }
3794
3795     case Dali::Actor::Property::COLOR_MODE:
3796     {
3797       value = GetColorMode();
3798       break;
3799     }
3800
3801     case Dali::Actor::Property::DRAW_MODE:
3802     {
3803       value = GetDrawMode();
3804       break;
3805     }
3806
3807     case Dali::Actor::Property::SIZE_MODE_FACTOR:
3808     {
3809       value = GetSizeModeFactor();
3810       break;
3811     }
3812
3813     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3814     {
3815       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3816       break;
3817     }
3818
3819     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3820     {
3821       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3822       break;
3823     }
3824
3825     case Dali::Actor::Property::SIZE_SCALE_POLICY:
3826     {
3827       value = GetSizeScalePolicy();
3828       break;
3829     }
3830
3831     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3832     {
3833       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3834       break;
3835     }
3836
3837     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3838     {
3839       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3840       break;
3841     }
3842
3843     case Dali::Actor::Property::PADDING:
3844     {
3845       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3846       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3847       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3848       break;
3849     }
3850
3851     case Dali::Actor::Property::MINIMUM_SIZE:
3852     {
3853       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3854       break;
3855     }
3856
3857     case Dali::Actor::Property::MAXIMUM_SIZE:
3858     {
3859       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3860       break;
3861     }
3862
3863     case Dali::Actor::Property::CLIPPING_MODE:
3864     {
3865       value = mClippingMode;
3866       break;
3867     }
3868
3869     case Dali::DevelActor::Property::SIBLING_ORDER:
3870     {
3871       value = static_cast<int>( GetSiblingOrder() );
3872       break;
3873     }
3874
3875     case Dali::Actor::Property::SCREEN_POSITION:
3876     {
3877       value = GetCurrentScreenPosition();
3878       break;
3879     }
3880
3881     case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
3882     {
3883       value = mPositionUsesAnchorPoint;
3884       break;
3885     }
3886
3887     case Dali::Actor::Property::LAYOUT_DIRECTION:
3888     {
3889       value = mLayoutDirection;
3890       break;
3891     }
3892
3893     case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3894     {
3895       value = IsLayoutDirectionInherited();
3896       break;
3897     }
3898
3899     case Dali::Actor::Property::ID:
3900     {
3901       value = static_cast<int>( GetId() );
3902       break;
3903     }
3904
3905     case Dali::Actor::Property::HIERARCHY_DEPTH:
3906     {
3907       value = GetHierarchyDepth();
3908       break;
3909     }
3910
3911     case Dali::Actor::Property::IS_ROOT:
3912     {
3913       value = IsRoot();
3914       break;
3915     }
3916
3917     case Dali::Actor::Property::IS_LAYER:
3918     {
3919       value = IsLayer();
3920       break;
3921     }
3922
3923     case Dali::Actor::Property::CONNECTED_TO_SCENE:
3924     {
3925       value = OnStage();
3926       break;
3927     }
3928
3929     case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
3930     {
3931       value = IsKeyboardFocusable();
3932       break;
3933     }
3934
3935     default:
3936     {
3937       // Must be a scene-graph only property
3938       valueSet = false;
3939       break;
3940     }
3941   }
3942
3943   return valueSet;
3944 }
3945
3946 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value  ) const
3947 {
3948   bool valueSet = true;
3949
3950   switch( index )
3951   {
3952     case Dali::Actor::Property::SIZE:
3953     {
3954       value = GetCurrentSize();
3955       break;
3956     }
3957
3958     case Dali::Actor::Property::SIZE_WIDTH:
3959     {
3960       value = GetCurrentSize().width;
3961       break;
3962     }
3963
3964     case Dali::Actor::Property::SIZE_HEIGHT:
3965     {
3966       value = GetCurrentSize().height;
3967       break;
3968     }
3969
3970     case Dali::Actor::Property::SIZE_DEPTH:
3971     {
3972       value = GetCurrentSize().depth;
3973       break;
3974     }
3975
3976     case Dali::Actor::Property::POSITION:
3977     {
3978       value = GetCurrentPosition();
3979       break;
3980     }
3981
3982     case Dali::Actor::Property::POSITION_X:
3983     {
3984       value = GetCurrentPosition().x;
3985       break;
3986     }
3987
3988     case Dali::Actor::Property::POSITION_Y:
3989     {
3990       value = GetCurrentPosition().y;
3991       break;
3992     }
3993
3994     case Dali::Actor::Property::POSITION_Z:
3995     {
3996       value = GetCurrentPosition().z;
3997       break;
3998     }
3999
4000     case Dali::Actor::Property::WORLD_POSITION:
4001     {
4002       value = GetCurrentWorldPosition();
4003       break;
4004     }
4005
4006     case Dali::Actor::Property::WORLD_POSITION_X:
4007     {
4008       value = GetCurrentWorldPosition().x;
4009       break;
4010     }
4011
4012     case Dali::Actor::Property::WORLD_POSITION_Y:
4013     {
4014       value = GetCurrentWorldPosition().y;
4015       break;
4016     }
4017
4018     case Dali::Actor::Property::WORLD_POSITION_Z:
4019     {
4020       value = GetCurrentWorldPosition().z;
4021       break;
4022     }
4023
4024     case Dali::Actor::Property::ORIENTATION:
4025     {
4026       value = GetCurrentOrientation();
4027       break;
4028     }
4029
4030     case Dali::Actor::Property::WORLD_ORIENTATION:
4031     {
4032       value = GetCurrentWorldOrientation();
4033       break;
4034     }
4035
4036     case Dali::Actor::Property::SCALE:
4037     {
4038       value = GetCurrentScale();
4039       break;
4040     }
4041
4042     case Dali::Actor::Property::SCALE_X:
4043     {
4044       value = GetCurrentScale().x;
4045       break;
4046     }
4047
4048     case Dali::Actor::Property::SCALE_Y:
4049     {
4050       value = GetCurrentScale().y;
4051       break;
4052     }
4053
4054     case Dali::Actor::Property::SCALE_Z:
4055     {
4056       value = GetCurrentScale().z;
4057       break;
4058     }
4059
4060     case Dali::Actor::Property::WORLD_SCALE:
4061     {
4062       value = GetCurrentWorldScale();
4063       break;
4064     }
4065
4066     case Dali::Actor::Property::COLOR:
4067     {
4068       value = GetCurrentColor();
4069       break;
4070     }
4071
4072     case Dali::Actor::Property::COLOR_RED:
4073     {
4074       value = GetCurrentColor().r;
4075       break;
4076     }
4077
4078     case Dali::Actor::Property::COLOR_GREEN:
4079     {
4080       value = GetCurrentColor().g;
4081       break;
4082     }
4083
4084     case Dali::Actor::Property::COLOR_BLUE:
4085     {
4086       value = GetCurrentColor().b;
4087       break;
4088     }
4089
4090     case Dali::Actor::Property::COLOR_ALPHA:
4091     case Dali::Actor::Property::OPACITY:
4092     {
4093       value = GetCurrentColor().a;
4094       break;
4095     }
4096
4097     case Dali::Actor::Property::WORLD_COLOR:
4098     {
4099       value = GetCurrentWorldColor();
4100       break;
4101     }
4102
4103     case Dali::Actor::Property::WORLD_MATRIX:
4104     {
4105       value = GetCurrentWorldMatrix();
4106       break;
4107     }
4108
4109     case Dali::Actor::Property::VISIBLE:
4110     {
4111       value = IsVisible();
4112       break;
4113     }
4114
4115     case Dali::Actor::Property::CULLED:
4116     {
4117       value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4118       break;
4119     }
4120
4121     default:
4122     {
4123       // Must be an event-side only property
4124       valueSet = false;
4125       break;
4126     }
4127   }
4128
4129   return valueSet;
4130 }
4131
4132 void Actor::EnsureRelayoutData()
4133 {
4134   // Assign relayout data.
4135   if( !mRelayoutData )
4136   {
4137     mRelayoutData = new RelayoutData();
4138   }
4139 }
4140
4141 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4142 {
4143   // Check if actor is dependent on parent
4144   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4145   {
4146     if( ( dimension & ( 1 << i ) ) )
4147     {
4148       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4149       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4150       {
4151         return true;
4152       }
4153     }
4154   }
4155
4156   return false;
4157 }
4158
4159 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4160 {
4161   // Check if actor is dependent on children
4162   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4163   {
4164     if( ( dimension & ( 1 << i ) ) )
4165     {
4166       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4167       switch( resizePolicy )
4168       {
4169         case ResizePolicy::FIT_TO_CHILDREN:
4170         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
4171         {
4172           return true;
4173         }
4174
4175         default:
4176         {
4177           break;
4178         }
4179       }
4180     }
4181   }
4182
4183   return false;
4184 }
4185
4186 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4187 {
4188   return Actor::RelayoutDependentOnChildren( dimension );
4189 }
4190
4191 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4192 {
4193   // Check each possible dimension and see if it is dependent on the input one
4194   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4195   {
4196     if( dimension & ( 1 << i ) )
4197     {
4198       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4199     }
4200   }
4201
4202   return false;
4203 }
4204
4205 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4206 {
4207   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4208   {
4209     if( dimension & ( 1 << i ) )
4210     {
4211       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4212     }
4213   }
4214 }
4215
4216 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4217 {
4218   // If more than one dimension is requested, just return the first one found
4219   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4220   {
4221     if( ( dimension & ( 1 << i ) ) )
4222     {
4223       return mRelayoutData->negotiatedDimensions[ i ];
4224     }
4225   }
4226
4227   return 0.0f;   // Default
4228 }
4229
4230 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4231 {
4232   EnsureRelayoutData();
4233
4234   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4235   {
4236     if( dimension & ( 1 << i ) )
4237     {
4238       mRelayoutData->dimensionPadding[ i ] = padding;
4239     }
4240   }
4241 }
4242
4243 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4244 {
4245   if ( mRelayoutData )
4246   {
4247     // If more than one dimension is requested, just return the first one found
4248     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4249     {
4250       if( ( dimension & ( 1 << i ) ) )
4251       {
4252         return mRelayoutData->dimensionPadding[ i ];
4253       }
4254     }
4255   }
4256
4257   return GetDefaultDimensionPadding();
4258 }
4259
4260 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4261 {
4262   EnsureRelayoutData();
4263
4264   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4265   {
4266     if( dimension & ( 1 << i ) )
4267     {
4268       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4269     }
4270   }
4271 }
4272
4273 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4274 {
4275   if ( mRelayoutData )
4276   {
4277     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4278     {
4279       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4280       {
4281         return true;
4282       }
4283     }
4284   }
4285
4286   return false;
4287 }
4288
4289 float Actor::GetHeightForWidthBase( float width )
4290 {
4291   float height = 0.0f;
4292
4293   const Vector3 naturalSize = GetNaturalSize();
4294   if( naturalSize.width > 0.0f )
4295   {
4296     height = naturalSize.height * width / naturalSize.width;
4297   }
4298   else // we treat 0 as 1:1 aspect ratio
4299   {
4300     height = width;
4301   }
4302
4303   return height;
4304 }
4305
4306 float Actor::GetWidthForHeightBase( float height )
4307 {
4308   float width = 0.0f;
4309
4310   const Vector3 naturalSize = GetNaturalSize();
4311   if( naturalSize.height > 0.0f )
4312   {
4313     width = naturalSize.width * height / naturalSize.height;
4314   }
4315   else // we treat 0 as 1:1 aspect ratio
4316   {
4317     width = height;
4318   }
4319
4320   return width;
4321 }
4322
4323 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4324 {
4325   // Fill to parent, taking size mode factor into account
4326   switch( child.GetResizePolicy( dimension ) )
4327   {
4328     case ResizePolicy::FILL_TO_PARENT:
4329     {
4330       return GetLatestSize( dimension );
4331     }
4332
4333     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4334     {
4335       return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4336     }
4337
4338     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4339     {
4340       return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4341     }
4342
4343     default:
4344     {
4345       return GetLatestSize( dimension );
4346     }
4347   }
4348 }
4349
4350 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4351 {
4352   // Can be overridden in derived class
4353   return CalculateChildSizeBase( child, dimension );
4354 }
4355
4356 float Actor::GetHeightForWidth( float width )
4357 {
4358   // Can be overridden in derived class
4359   return GetHeightForWidthBase( width );
4360 }
4361
4362 float Actor::GetWidthForHeight( float height )
4363 {
4364   // Can be overridden in derived class
4365   return GetWidthForHeightBase( height );
4366 }
4367
4368 float Actor::GetLatestSize( Dimension::Type dimension ) const
4369 {
4370   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4371 }
4372
4373 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4374 {
4375   Vector2 padding = GetPadding( dimension );
4376
4377   return GetLatestSize( dimension ) + padding.x + padding.y;
4378 }
4379
4380 float Actor::NegotiateFromParent( Dimension::Type dimension )
4381 {
4382   Actor* parent = GetParent();
4383   if( parent )
4384   {
4385     Vector2 padding( GetPadding( dimension ) );
4386     Vector2 parentPadding( parent->GetPadding( dimension ) );
4387     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4388   }
4389
4390   return 0.0f;
4391 }
4392
4393 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4394 {
4395   float maxDimensionPoint = 0.0f;
4396
4397   for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4398   {
4399     ActorPtr child = GetChildAt( i );
4400
4401     if( !child->RelayoutDependentOnParent( dimension ) )
4402     {
4403       // Calculate the min and max points that the children range across
4404       float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4405       float dimensionSize = child->GetRelayoutSize( dimension );
4406       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4407     }
4408   }
4409
4410   return maxDimensionPoint;
4411 }
4412
4413 float Actor::GetSize( Dimension::Type dimension ) const
4414 {
4415   return GetDimensionValue( mTargetSize, dimension );
4416 }
4417
4418 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4419 {
4420   return GetDimensionValue( GetNaturalSize(), dimension );
4421 }
4422
4423 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4424 {
4425   switch( GetResizePolicy( dimension ) )
4426   {
4427     case ResizePolicy::USE_NATURAL_SIZE:
4428     {
4429       return GetNaturalSize( dimension );
4430     }
4431
4432     case ResizePolicy::FIXED:
4433     {
4434       return GetDimensionValue( GetPreferredSize(), dimension );
4435     }
4436
4437     case ResizePolicy::USE_ASSIGNED_SIZE:
4438     {
4439       return GetDimensionValue( maximumSize, dimension );
4440     }
4441
4442     case ResizePolicy::FILL_TO_PARENT:
4443     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4444     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4445     {
4446       return NegotiateFromParent( dimension );
4447     }
4448
4449     case ResizePolicy::FIT_TO_CHILDREN:
4450     {
4451       return NegotiateFromChildren( dimension );
4452     }
4453
4454     case ResizePolicy::DIMENSION_DEPENDENCY:
4455     {
4456       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4457
4458       // Custom rules
4459       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4460       {
4461         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4462       }
4463
4464       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4465       {
4466         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4467       }
4468
4469       break;
4470     }
4471
4472     default:
4473     {
4474       break;
4475     }
4476   }
4477
4478   return 0.0f;  // Default
4479 }
4480
4481 float Actor::ClampDimension( float size, Dimension::Type dimension )
4482 {
4483   const float minSize = GetMinimumSize( dimension );
4484   const float maxSize = GetMaximumSize( dimension );
4485
4486   return std::max( minSize, std::min( size, maxSize ) );
4487 }
4488
4489 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4490 {
4491   // Check if it needs to be negotiated
4492   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4493   {
4494     // Check that we havn't gotten into an infinite loop
4495     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4496     bool recursionFound = false;
4497     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4498     {
4499       if( *it == searchActor )
4500       {
4501         recursionFound = true;
4502         break;
4503       }
4504     }
4505
4506     if( !recursionFound )
4507     {
4508       // Record the path that we have taken
4509       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4510
4511       // Dimension dependency check
4512       for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4513       {
4514         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4515
4516         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4517         {
4518           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4519         }
4520       }
4521
4522       // Parent dependency check
4523       Actor* parent = GetParent();
4524       if( parent && RelayoutDependentOnParent( dimension ) )
4525       {
4526         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4527       }
4528
4529       // Children dependency check
4530       if( RelayoutDependentOnChildren( dimension ) )
4531       {
4532         for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4533         {
4534           ActorPtr child = GetChildAt( i );
4535
4536           // Only relayout child first if it is not dependent on this actor
4537           if( !child->RelayoutDependentOnParent( dimension ) )
4538           {
4539             child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4540           }
4541         }
4542       }
4543
4544       // For deriving classes
4545       OnCalculateRelayoutSize( dimension );
4546
4547       // All dependencies checked, calculate the size and set negotiated flag
4548       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4549
4550       SetNegotiatedDimension( newSize, dimension );
4551       SetLayoutNegotiated( true, dimension );
4552
4553       // For deriving classes
4554       OnLayoutNegotiated( newSize, dimension );
4555
4556       // This actor has been successfully processed, pop it off the recursion stack
4557       recursionStack.pop_back();
4558     }
4559     else
4560     {
4561       // TODO: Break infinite loop
4562       SetLayoutNegotiated( true, dimension );
4563     }
4564   }
4565 }
4566
4567 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4568 {
4569   // Negotiate all dimensions that require it
4570   ActorDimensionStack recursionStack;
4571
4572   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4573   {
4574     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4575
4576     // Negotiate
4577     NegotiateDimension( dimension, allocatedSize, recursionStack );
4578   }
4579 }
4580
4581 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4582 {
4583   switch( mRelayoutData->sizeSetPolicy )
4584   {
4585     case SizeScalePolicy::USE_SIZE_SET:
4586     {
4587       return size;
4588     }
4589
4590     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4591     {
4592       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4593       const Vector3 naturalSize = GetNaturalSize();
4594       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4595       {
4596         const float sizeRatio = size.width / size.height;
4597         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4598
4599         if( naturalSizeRatio < sizeRatio )
4600         {
4601           return Vector2( naturalSizeRatio * size.height, size.height );
4602         }
4603         else if( naturalSizeRatio > sizeRatio )
4604         {
4605           return Vector2( size.width, size.width / naturalSizeRatio );
4606         }
4607         else
4608         {
4609           return size;
4610         }
4611       }
4612
4613       break;
4614     }
4615
4616     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4617     {
4618       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4619       const Vector3 naturalSize = GetNaturalSize();
4620       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4621       {
4622         const float sizeRatio = size.width / size.height;
4623         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4624
4625         if( naturalSizeRatio < sizeRatio )
4626         {
4627           return Vector2( size.width, size.width / naturalSizeRatio );
4628         }
4629         else if( naturalSizeRatio > sizeRatio )
4630         {
4631           return Vector2( naturalSizeRatio * size.height, size.height );
4632         }
4633         else
4634         {
4635           return size;
4636         }
4637       }
4638       break;
4639     }
4640
4641     default:
4642     {
4643       break;
4644     }
4645   }
4646
4647   return size;
4648 }
4649
4650 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4651 {
4652   // Do the set actor size
4653   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4654
4655   // Adjust for size set policy
4656   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4657
4658   // Lock the flag to stop recursive relayouts on set size
4659   mRelayoutData->insideRelayout = true;
4660   SetSize( negotiatedSize );
4661   mRelayoutData->insideRelayout = false;
4662
4663   // Clear flags for all dimensions
4664   SetLayoutDirty( false );
4665
4666   // Give deriving classes a chance to respond
4667   OnRelayout( negotiatedSize, container );
4668
4669   if( !mOnRelayoutSignal.Empty() )
4670   {
4671     Dali::Actor handle( this );
4672     mOnRelayoutSignal.Emit( handle );
4673   }
4674 }
4675
4676 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4677 {
4678   // Force a size negotiation for actors that has assigned size during relayout
4679   // This is required as otherwise the flags that force a relayout will not
4680   // necessarilly be set. This will occur if the actor has already been laid out.
4681   // The dirty flags are then cleared. Then if the actor is added back into the
4682   // relayout container afterwards, the dirty flags would still be clear...
4683   // causing a relayout to be skipped. Here we force any actors added to the
4684   // container to be relayed out.
4685   DALI_LOG_TIMER_START( NegSizeTimer1 );
4686
4687   if( GetUseAssignedSize(Dimension::WIDTH ) )
4688   {
4689     SetLayoutNegotiated( false, Dimension::WIDTH );
4690   }
4691   if( GetUseAssignedSize( Dimension::HEIGHT ) )
4692   {
4693     SetLayoutNegotiated( false, Dimension::HEIGHT );
4694   }
4695
4696   // Do the negotiation
4697   NegotiateDimensions( allocatedSize );
4698
4699   // Set the actor size
4700   SetNegotiatedSize( container );
4701
4702   // Negotiate down to children
4703   for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4704   {
4705     ActorPtr child = GetChildAt( i );
4706
4707     // Forces children that have already been laid out to be relayed out
4708     // if they have assigned size during relayout.
4709     if( child->GetUseAssignedSize(Dimension::WIDTH) )
4710     {
4711       child->SetLayoutNegotiated(false, Dimension::WIDTH);
4712       child->SetLayoutDirty(true, Dimension::WIDTH);
4713     }
4714
4715     if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4716     {
4717       child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4718       child->SetLayoutDirty(true, Dimension::HEIGHT);
4719     }
4720
4721     // Only relayout if required
4722     if( child->RelayoutRequired() )
4723     {
4724       container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4725     }
4726   }
4727   DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4728 }
4729
4730 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4731 {
4732   if( mRelayoutData )
4733   {
4734     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4735     {
4736       if( dimension & ( 1 << i ) )
4737       {
4738         mRelayoutData->useAssignedSize[ i ] = use;
4739       }
4740     }
4741   }
4742 }
4743
4744 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4745 {
4746   if ( mRelayoutData )
4747   {
4748     // If more than one dimension is requested, just return the first one found
4749     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4750     {
4751       if( dimension & ( 1 << i ) )
4752       {
4753         return mRelayoutData->useAssignedSize[ i ];
4754       }
4755     }
4756   }
4757
4758   return false;
4759 }
4760
4761 void Actor::RelayoutRequest( Dimension::Type dimension )
4762 {
4763   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4764   if( relayoutController )
4765   {
4766     Dali::Actor self( this );
4767     relayoutController->RequestRelayout( self, dimension );
4768   }
4769 }
4770
4771 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4772 {
4773 }
4774
4775 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4776 {
4777 }
4778
4779 void Actor::SetPreferredSize( const Vector2& size )
4780 {
4781   EnsureRelayoutData();
4782
4783   // If valid width or height, then set the resize policy to FIXED
4784   // 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,
4785   // then change to FIXED as well
4786
4787   if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4788   {
4789     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4790   }
4791
4792   if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4793   {
4794     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4795   }
4796
4797   mRelayoutData->preferredSize = size;
4798
4799   mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4800
4801   RelayoutRequest();
4802 }
4803
4804 Vector2 Actor::GetPreferredSize() const
4805 {
4806   if ( mRelayoutData )
4807   {
4808     return Vector2( mRelayoutData->preferredSize );
4809   }
4810
4811   return GetDefaultPreferredSize();
4812 }
4813
4814 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4815 {
4816   EnsureRelayoutData();
4817
4818   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4819   {
4820     if( dimension & ( 1 << i ) )
4821     {
4822       mRelayoutData->minimumSize[ i ] = size;
4823     }
4824   }
4825
4826   RelayoutRequest();
4827 }
4828
4829 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4830 {
4831   if ( mRelayoutData )
4832   {
4833     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4834     {
4835       if( dimension & ( 1 << i ) )
4836       {
4837         return mRelayoutData->minimumSize[ i ];
4838       }
4839     }
4840   }
4841
4842   return 0.0f;  // Default
4843 }
4844
4845 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4846 {
4847   EnsureRelayoutData();
4848
4849   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4850   {
4851     if( dimension & ( 1 << i ) )
4852     {
4853       mRelayoutData->maximumSize[ i ] = size;
4854     }
4855   }
4856
4857   RelayoutRequest();
4858 }
4859
4860 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4861 {
4862   if ( mRelayoutData )
4863   {
4864     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4865     {
4866       if( dimension & ( 1 << i ) )
4867       {
4868         return mRelayoutData->maximumSize[ i ];
4869       }
4870     }
4871   }
4872
4873   return FLT_MAX;  // Default
4874 }
4875
4876 Object* Actor::GetParentObject() const
4877 {
4878   return mParent;
4879 }
4880
4881 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4882 {
4883   if( mVisible != visible )
4884   {
4885     if( sendMessage == SendMessage::TRUE )
4886     {
4887       // node is being used in a separate thread; queue a message to set the value & base value
4888       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4889     }
4890
4891     mVisible = visible;
4892
4893     // Emit the signal on this actor and all its children
4894     EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4895   }
4896 }
4897
4898 void Actor::SetSiblingOrder( uint32_t order )
4899 {
4900   if ( mParent )
4901   {
4902     ActorContainer& siblings = *(mParent->mChildren);
4903     uint32_t currentOrder = GetSiblingOrder();
4904
4905     if( order != currentOrder )
4906     {
4907       if( order == 0 )
4908       {
4909         LowerToBottom();
4910       }
4911       else if( order < siblings.size() -1 )
4912       {
4913         if( order > currentOrder )
4914         {
4915           RaiseAbove( *siblings[order] );
4916         }
4917         else
4918         {
4919           LowerBelow( *siblings[order] );
4920         }
4921       }
4922       else
4923       {
4924         RaiseToTop();
4925       }
4926     }
4927   }
4928 }
4929
4930 uint32_t Actor::GetSiblingOrder() const
4931 {
4932   uint32_t order = 0;
4933
4934   if ( mParent )
4935   {
4936     ActorContainer& siblings = *(mParent->mChildren);
4937     for( std::size_t i = 0; i < siblings.size(); ++i )
4938     {
4939       if( siblings[i] == this )
4940       {
4941         order = static_cast<uint32_t>( i );
4942         break;
4943       }
4944     }
4945   }
4946
4947   return order;
4948 }
4949
4950 void Actor::RequestRebuildDepthTree()
4951 {
4952   if( mIsOnStage )
4953   {
4954     if( mScene )
4955     {
4956       mScene->RequestRebuildDepthTree();
4957     }
4958   }
4959 }
4960
4961 void Actor::Raise()
4962 {
4963   if ( mParent )
4964   {
4965     ActorContainer& siblings = *(mParent->mChildren);
4966     if( siblings.back() != this ) // If not already at end
4967     {
4968       for( std::size_t i=0; i<siblings.size(); ++i )
4969       {
4970         if( siblings[i] == this )
4971         {
4972           // Swap with next
4973           ActorPtr next = siblings[i+1];
4974           siblings[i+1] = this;
4975           siblings[i] = next;
4976           break;
4977         }
4978       }
4979     }
4980
4981     Dali::Actor handle( this );
4982     mParent->mChildOrderChangedSignal.Emit( handle );
4983
4984     RequestRebuildDepthTree();
4985   }
4986   else
4987   {
4988     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4989   }
4990 }
4991
4992 void Actor::Lower()
4993 {
4994   if ( mParent )
4995   {
4996     ActorContainer& siblings = *(mParent->mChildren);
4997     if( siblings.front() != this ) // If not already at beginning
4998     {
4999       for( std::size_t i=1; i<siblings.size(); ++i )
5000       {
5001         if( siblings[i] == this )
5002         {
5003           // Swap with previous
5004           ActorPtr previous = siblings[i-1];
5005           siblings[i-1] = this;
5006           siblings[i] = previous;
5007           break;
5008         }
5009       }
5010     }
5011
5012     Dali::Actor handle( this );
5013     mParent->mChildOrderChangedSignal.Emit( handle );
5014
5015     RequestRebuildDepthTree();
5016   }
5017   else
5018   {
5019     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5020   }
5021 }
5022
5023 void Actor::RaiseToTop()
5024 {
5025   if ( mParent )
5026   {
5027     ActorContainer& siblings = *(mParent->mChildren);
5028     if( siblings.back() != this ) // If not already at end
5029     {
5030       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5031       if( iter != siblings.end() )
5032       {
5033         siblings.erase(iter);
5034         siblings.push_back(ActorPtr(this));
5035       }
5036     }
5037
5038     Dali::Actor handle( this );
5039     mParent->mChildOrderChangedSignal.Emit( handle );
5040
5041     RequestRebuildDepthTree();
5042   }
5043   else
5044   {
5045     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5046   }
5047 }
5048
5049 void Actor::LowerToBottom()
5050 {
5051   if ( mParent )
5052   {
5053     ActorContainer& siblings = *(mParent->mChildren);
5054     if( siblings.front() != this ) // If not already at bottom,
5055     {
5056       ActorPtr thisPtr(this); // ensure this actor remains referenced.
5057
5058       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5059       if( iter != siblings.end() )
5060       {
5061         siblings.erase(iter);
5062         siblings.insert(siblings.begin(), thisPtr);
5063       }
5064     }
5065
5066     Dali::Actor handle( this );
5067     mParent->mChildOrderChangedSignal.Emit( handle );
5068
5069     RequestRebuildDepthTree();
5070   }
5071   else
5072   {
5073     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5074   }
5075 }
5076
5077 void Actor::RaiseAbove( Internal::Actor& target )
5078 {
5079   if ( mParent )
5080   {
5081     ActorContainer& siblings = *(mParent->mChildren);
5082     if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5083     {
5084       ActorPtr thisPtr(this); // ensure this actor remains referenced.
5085
5086       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5087       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5088       if( thisIter < targetIter )
5089       {
5090         siblings.erase(thisIter);
5091         // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5092         // invalidate thisIter)
5093         targetIter = std::find( siblings.begin(), siblings.end(), &target );
5094         ++targetIter;
5095         siblings.insert(targetIter, thisPtr);
5096       }
5097
5098       Dali::Actor handle( this );
5099       mParent->mChildOrderChangedSignal.Emit( handle );
5100
5101       RequestRebuildDepthTree();
5102     }
5103   }
5104   else
5105   {
5106     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5107   }
5108 }
5109
5110 void Actor::LowerBelow( Internal::Actor& target )
5111 {
5112   if ( mParent )
5113   {
5114     ActorContainer& siblings = *(mParent->mChildren);
5115     if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5116     {
5117       ActorPtr thisPtr(this); // ensure this actor remains referenced.
5118
5119       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5120       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5121
5122       if( thisIter > targetIter )
5123       {
5124         siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5125         siblings.insert(targetIter, thisPtr);
5126       }
5127
5128       Dali::Actor handle( this );
5129       mParent->mChildOrderChangedSignal.Emit( handle );
5130
5131       RequestRebuildDepthTree();
5132     }
5133   }
5134   else
5135   {
5136     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5137   }
5138 }
5139
5140 void Actor::SetScene( Scene& scene )
5141 {
5142   mScene = &scene;
5143 }
5144
5145 Scene& Actor::GetScene() const
5146 {
5147   return *mScene;
5148 }
5149
5150 void Actor::SetInheritLayoutDirection( bool inherit )
5151 {
5152   if( mInheritLayoutDirection != inherit )
5153   {
5154     mInheritLayoutDirection = inherit;
5155
5156     if( inherit && mParent )
5157     {
5158       InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5159     }
5160   }
5161 }
5162
5163 bool Actor::IsLayoutDirectionInherited() const
5164 {
5165   return mInheritLayoutDirection;
5166 }
5167
5168 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5169 {
5170   if( actor && ( actor->mInheritLayoutDirection || set ) )
5171   {
5172     if( actor->mLayoutDirection != direction )
5173     {
5174       actor->mLayoutDirection = direction;
5175       actor->EmitLayoutDirectionChangedSignal( direction );
5176       actor->RelayoutRequest();
5177     }
5178
5179     if( actor->GetChildCount() > 0 )
5180     {
5181       ActorContainer& children = actor->GetChildrenInternal();
5182       for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5183       {
5184         InheritLayoutDirectionRecursively( *iter, direction );
5185       }
5186     }
5187   }
5188 }
5189
5190 } // namespace Internal
5191
5192 } // namespace Dali