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