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