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