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