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