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