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