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