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