Merge branch 'devel/master' into tizen
[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     DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2084
2085     GetEventThreadServices().UnregisterObject( this );
2086   }
2087
2088   // Cleanup optional gesture data
2089   delete mGestureData;
2090
2091   // Cleanup optional parent origin and anchor
2092   delete mParentOrigin;
2093   delete mAnchorPoint;
2094
2095   // Delete optional relayout data
2096   delete mRelayoutData;
2097 }
2098
2099 void Actor::ConnectToStage( uint32_t parentDepth )
2100 {
2101   // This container is used instead of walking the Actor hierarchy.
2102   // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2103   ActorContainer connectionList;
2104
2105   if( mScene )
2106   {
2107     mScene->RequestRebuildDepthTree();
2108   }
2109
2110   // This stage is atomic i.e. not interrupted by user callbacks.
2111   RecursiveConnectToStage( connectionList, parentDepth + 1 );
2112
2113   // Notify applications about the newly connected actors.
2114   const ActorIter endIter = connectionList.end();
2115   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2116   {
2117     (*iter)->NotifyStageConnection();
2118   }
2119
2120   RelayoutRequest();
2121 }
2122
2123 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2124 {
2125   DALI_ASSERT_ALWAYS( !OnStage() );
2126
2127   mIsOnStage = true;
2128   mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2129
2130   ConnectToSceneGraph();
2131
2132   // Notification for internal derived classes
2133   OnStageConnectionInternal();
2134
2135   // This stage is atomic; avoid emitting callbacks until all Actors are connected
2136   connectionList.push_back( ActorPtr( this ) );
2137
2138   // Recursively connect children
2139   if( mChildren )
2140   {
2141     ActorConstIter endIter = mChildren->end();
2142     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2143     {
2144       (*iter)->SetScene( *mScene );
2145       (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2146     }
2147   }
2148 }
2149
2150 /**
2151  * This method is called when the Actor is connected to the Stage.
2152  * The parent must have added its Node to the scene-graph.
2153  * The child must connect its Node to the parent's Node.
2154  * This is recursive; the child calls ConnectToStage() for its children.
2155  */
2156 void Actor::ConnectToSceneGraph()
2157 {
2158   DALI_ASSERT_DEBUG( mParent != NULL);
2159
2160   // Reparent Node in next Update
2161   ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2162
2163   // Request relayout on all actors that are added to the scenegraph
2164   RelayoutRequest();
2165
2166   // Notification for Object::Observers
2167   OnSceneObjectAdd();
2168 }
2169
2170 void Actor::NotifyStageConnection()
2171 {
2172   // Actors can be removed (in a callback), before the on-stage stage is reported.
2173   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2174   if( OnStage() && !mOnStageSignalled )
2175   {
2176     // Notification for external (CustomActor) derived classes
2177     OnStageConnectionExternal( mDepth );
2178
2179     if( !mOnStageSignal.Empty() )
2180     {
2181       Dali::Actor handle( this );
2182       mOnStageSignal.Emit( handle );
2183     }
2184
2185     // Guard against Remove during callbacks
2186     if( OnStage() )
2187     {
2188       mOnStageSignalled = true; // signal required next time Actor is removed
2189     }
2190   }
2191 }
2192
2193 void Actor::DisconnectFromStage()
2194 {
2195   // This container is used instead of walking the Actor hierachy.
2196   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2197   ActorContainer disconnectionList;
2198
2199   if( mScene )
2200   {
2201     mScene->RequestRebuildDepthTree();
2202   }
2203
2204   // This stage is atomic i.e. not interrupted by user callbacks
2205   RecursiveDisconnectFromStage( disconnectionList );
2206
2207   // Notify applications about the newly disconnected actors.
2208   const ActorIter endIter = disconnectionList.end();
2209   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2210   {
2211     (*iter)->NotifyStageDisconnection();
2212   }
2213 }
2214
2215 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2216 {
2217   // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2218   mIsOnStage = false;
2219
2220   // Recursively disconnect children
2221   if( mChildren )
2222   {
2223     ActorConstIter endIter = mChildren->end();
2224     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2225     {
2226       (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2227     }
2228   }
2229
2230   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2231   disconnectionList.push_back( ActorPtr( this ) );
2232
2233   // Notification for internal derived classes
2234   OnStageDisconnectionInternal();
2235
2236   DisconnectFromSceneGraph();
2237 }
2238
2239 /**
2240  * This method is called by an actor or its parent, before a node removal message is sent.
2241  * This is recursive; the child calls DisconnectFromStage() for its children.
2242  */
2243 void Actor::DisconnectFromSceneGraph()
2244 {
2245   // Notification for Object::Observers
2246   OnSceneObjectRemove();
2247 }
2248
2249 void Actor::NotifyStageDisconnection()
2250 {
2251   // Actors can be added (in a callback), before the off-stage state is reported.
2252   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2253   // only do this step if there is a stage, i.e. Core is not being shut down
2254   if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2255   {
2256     // Notification for external (CustomeActor) derived classes
2257     OnStageDisconnectionExternal();
2258
2259     if( !mOffStageSignal.Empty() )
2260     {
2261       Dali::Actor handle( this );
2262       mOffStageSignal.Emit( handle );
2263     }
2264
2265     // Guard against Add during callbacks
2266     if( !OnStage() )
2267     {
2268       mOnStageSignalled = false; // signal required next time Actor is added
2269     }
2270   }
2271 }
2272
2273 bool Actor::IsNodeConnected() const
2274 {
2275   bool connected( false );
2276
2277   if( OnStage() )
2278   {
2279     if( IsRoot() || GetNode().GetParent() )
2280     {
2281       connected = true;
2282     }
2283   }
2284
2285   return connected;
2286 }
2287
2288 // This method initiates traversal of the actor tree using depth-first
2289 // traversal to set a depth index based on traversal order. It sends a
2290 // single message to update manager to update all the actor's nodes in
2291 // this tree with the depth index. The sceneGraphNodeDepths vector's
2292 // elements are ordered by depth, and could be used to reduce sorting
2293 // in the update thread.
2294 void Actor::RebuildDepthTree()
2295 {
2296   DALI_LOG_TIMER_START(depthTimer);
2297
2298   // Vector of scene-graph nodes and their depths to send to UpdateManager
2299   // in a single message
2300   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2301
2302   int32_t depthIndex = 1;
2303   DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2304
2305   SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2306   DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2307 }
2308
2309 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2310 {
2311   mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2312   sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2313
2314   // Create/add to children of this node
2315   if( mChildren )
2316   {
2317     for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2318     {
2319       Actor* childActor = (*it).Get();
2320       ++depthIndex;
2321       childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2322     }
2323   }
2324 }
2325
2326 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2327 {
2328   switch( index )
2329   {
2330     case Dali::Actor::Property::PARENT_ORIGIN:
2331     {
2332       Property::Type type = property.GetType();
2333       if( type == Property::VECTOR3 )
2334       {
2335         SetParentOrigin( property.Get< Vector3 >() );
2336       }
2337       else if ( type == Property::STRING )
2338       {
2339         std::string parentOriginString;
2340         property.Get( parentOriginString );
2341         Vector3 parentOrigin;
2342         if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2343         {
2344           SetParentOrigin( parentOrigin );
2345         }
2346       }
2347       break;
2348     }
2349
2350     case Dali::Actor::Property::PARENT_ORIGIN_X:
2351     {
2352       SetParentOriginX( property.Get< float >() );
2353       break;
2354     }
2355
2356     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2357     {
2358       SetParentOriginY( property.Get< float >() );
2359       break;
2360     }
2361
2362     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2363     {
2364       SetParentOriginZ( property.Get< float >() );
2365       break;
2366     }
2367
2368     case Dali::Actor::Property::ANCHOR_POINT:
2369     {
2370       Property::Type type = property.GetType();
2371       if( type == Property::VECTOR3 )
2372       {
2373         SetAnchorPoint( property.Get< Vector3 >() );
2374       }
2375       else if ( type == Property::STRING )
2376       {
2377         std::string anchorPointString;
2378         property.Get( anchorPointString );
2379         Vector3 anchor;
2380         if( GetAnchorPointConstant( anchorPointString, anchor ) )
2381         {
2382           SetAnchorPoint( anchor );
2383         }
2384       }
2385       break;
2386     }
2387
2388     case Dali::Actor::Property::ANCHOR_POINT_X:
2389     {
2390       SetAnchorPointX( property.Get< float >() );
2391       break;
2392     }
2393
2394     case Dali::Actor::Property::ANCHOR_POINT_Y:
2395     {
2396       SetAnchorPointY( property.Get< float >() );
2397       break;
2398     }
2399
2400     case Dali::Actor::Property::ANCHOR_POINT_Z:
2401     {
2402       SetAnchorPointZ( property.Get< float >() );
2403       break;
2404     }
2405
2406     case Dali::Actor::Property::SIZE:
2407     {
2408       SetSize( property.Get< Vector3 >() );
2409       break;
2410     }
2411
2412     case Dali::Actor::Property::SIZE_WIDTH:
2413     {
2414       SetWidth( property.Get< float >() );
2415       break;
2416     }
2417
2418     case Dali::Actor::Property::SIZE_HEIGHT:
2419     {
2420       SetHeight( property.Get< float >() );
2421       break;
2422     }
2423
2424     case Dali::Actor::Property::SIZE_DEPTH:
2425     {
2426       SetDepth( property.Get< float >() );
2427       break;
2428     }
2429
2430     case Dali::Actor::Property::POSITION:
2431     {
2432       SetPosition( property.Get< Vector3 >() );
2433       break;
2434     }
2435
2436     case Dali::Actor::Property::POSITION_X:
2437     {
2438       SetX( property.Get< float >() );
2439       break;
2440     }
2441
2442     case Dali::Actor::Property::POSITION_Y:
2443     {
2444       SetY( property.Get< float >() );
2445       break;
2446     }
2447
2448     case Dali::Actor::Property::POSITION_Z:
2449     {
2450       SetZ( property.Get< float >() );
2451       break;
2452     }
2453
2454     case Dali::Actor::Property::ORIENTATION:
2455     {
2456       SetOrientation( property.Get< Quaternion >() );
2457       break;
2458     }
2459
2460     case Dali::Actor::Property::SCALE:
2461     {
2462       SetScale( property.Get< Vector3 >() );
2463       break;
2464     }
2465
2466     case Dali::Actor::Property::SCALE_X:
2467     {
2468       SetScaleX( property.Get< float >() );
2469       break;
2470     }
2471
2472     case Dali::Actor::Property::SCALE_Y:
2473     {
2474       SetScaleY( property.Get< float >() );
2475       break;
2476     }
2477
2478     case Dali::Actor::Property::SCALE_Z:
2479     {
2480       SetScaleZ( property.Get< float >() );
2481       break;
2482     }
2483
2484     case Dali::Actor::Property::VISIBLE:
2485     {
2486       SetVisible( property.Get< bool >() );
2487       break;
2488     }
2489
2490     case Dali::Actor::Property::COLOR:
2491     {
2492       SetColor( property.Get< Vector4 >() );
2493       break;
2494     }
2495
2496     case Dali::Actor::Property::COLOR_RED:
2497     {
2498       SetColorRed( property.Get< float >() );
2499       break;
2500     }
2501
2502     case Dali::Actor::Property::COLOR_GREEN:
2503     {
2504       SetColorGreen( property.Get< float >() );
2505       break;
2506     }
2507
2508     case Dali::Actor::Property::COLOR_BLUE:
2509     {
2510       SetColorBlue( property.Get< float >() );
2511       break;
2512     }
2513
2514     case Dali::Actor::Property::COLOR_ALPHA:
2515     case Dali::DevelActor::Property::OPACITY:
2516     {
2517       float value;
2518       if( property.Get( value ) )
2519       {
2520         SetOpacity( value );
2521       }
2522       break;
2523     }
2524
2525     case Dali::Actor::Property::NAME:
2526     {
2527       SetName( property.Get< std::string >() );
2528       break;
2529     }
2530
2531     case Dali::Actor::Property::SENSITIVE:
2532     {
2533       SetSensitive( property.Get< bool >() );
2534       break;
2535     }
2536
2537     case Dali::Actor::Property::LEAVE_REQUIRED:
2538     {
2539       SetLeaveRequired( property.Get< bool >() );
2540       break;
2541     }
2542
2543     case Dali::Actor::Property::INHERIT_POSITION:
2544     {
2545       SetInheritPosition( property.Get< bool >() );
2546       break;
2547     }
2548
2549     case Dali::Actor::Property::INHERIT_ORIENTATION:
2550     {
2551       SetInheritOrientation( property.Get< bool >() );
2552       break;
2553     }
2554
2555     case Dali::Actor::Property::INHERIT_SCALE:
2556     {
2557       SetInheritScale( property.Get< bool >() );
2558       break;
2559     }
2560
2561     case Dali::Actor::Property::COLOR_MODE:
2562     {
2563       ColorMode mode = mColorMode;
2564       if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2565       {
2566         SetColorMode( mode );
2567       }
2568       break;
2569     }
2570
2571     case Dali::Actor::Property::DRAW_MODE:
2572     {
2573       DrawMode::Type mode = mDrawMode;
2574       if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2575       {
2576         SetDrawMode( mode );
2577       }
2578       break;
2579     }
2580
2581     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2582     {
2583       SetSizeModeFactor( property.Get< Vector3 >() );
2584       break;
2585     }
2586
2587     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2588     {
2589       ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2590       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2591       {
2592         SetResizePolicy( type, Dimension::WIDTH );
2593       }
2594       break;
2595     }
2596
2597     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2598     {
2599       ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2600       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2601       {
2602         SetResizePolicy( type, Dimension::HEIGHT );
2603       }
2604       break;
2605     }
2606
2607     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2608     {
2609       SizeScalePolicy::Type type = GetSizeScalePolicy();
2610       if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2611       {
2612         SetSizeScalePolicy( type );
2613       }
2614       break;
2615     }
2616
2617     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2618     {
2619       if( property.Get< bool >() )
2620       {
2621         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2622       }
2623       break;
2624     }
2625
2626     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2627     {
2628       if( property.Get< bool >() )
2629       {
2630         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2631       }
2632       break;
2633     }
2634
2635     case Dali::Actor::Property::PADDING:
2636     {
2637       Vector4 padding = property.Get< Vector4 >();
2638       SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2639       SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2640       break;
2641     }
2642
2643     case Dali::Actor::Property::MINIMUM_SIZE:
2644     {
2645       Vector2 size = property.Get< Vector2 >();
2646       SetMinimumSize( size.x, Dimension::WIDTH );
2647       SetMinimumSize( size.y, Dimension::HEIGHT );
2648       break;
2649     }
2650
2651     case Dali::Actor::Property::MAXIMUM_SIZE:
2652     {
2653       Vector2 size = property.Get< Vector2 >();
2654       SetMaximumSize( size.x, Dimension::WIDTH );
2655       SetMaximumSize( size.y, Dimension::HEIGHT );
2656       break;
2657     }
2658
2659     case Dali::DevelActor::Property::SIBLING_ORDER:
2660     {
2661       int value;
2662
2663       if( property.Get( value ) )
2664       {
2665         SetSiblingOrder( value );
2666       }
2667       break;
2668     }
2669
2670     case Dali::Actor::Property::CLIPPING_MODE:
2671     {
2672       ClippingMode::Type convertedValue = mClippingMode;
2673       if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2674       {
2675         mClippingMode = convertedValue;
2676         SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2677       }
2678       break;
2679     }
2680
2681     case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2682     {
2683       bool value = false;
2684       if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2685       {
2686         mPositionUsesAnchorPoint = value;
2687         SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2688       }
2689       break;
2690     }
2691
2692     case Dali::Actor::Property::LAYOUT_DIRECTION:
2693     {
2694       Dali::LayoutDirection::Type direction = mLayoutDirection;
2695       mInheritLayoutDirection = false;
2696
2697       if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2698       {
2699         InheritLayoutDirectionRecursively( this, direction, true );
2700       }
2701       break;
2702     }
2703
2704     case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2705     {
2706       bool value = false;
2707       if( property.Get( value ) )
2708       {
2709         SetInheritLayoutDirection( value );
2710       }
2711       break;
2712     }
2713
2714     default:
2715     {
2716       // this can happen in the case of a non-animatable default property so just do nothing
2717       break;
2718     }
2719   }
2720 }
2721
2722 // TODO: This method needs to be removed
2723 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2724 {
2725   switch( entry.GetType() )
2726   {
2727     case Property::BOOLEAN:
2728     {
2729       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2730       DALI_ASSERT_DEBUG( NULL != property );
2731
2732       // property is being used in a separate thread; queue a message to set the property
2733       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2734
2735       break;
2736     }
2737
2738     case Property::INTEGER:
2739     {
2740       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2741       DALI_ASSERT_DEBUG( NULL != property );
2742
2743       // property is being used in a separate thread; queue a message to set the property
2744       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2745
2746       break;
2747     }
2748
2749     case Property::FLOAT:
2750     {
2751       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2752       DALI_ASSERT_DEBUG( NULL != property );
2753
2754       // property is being used in a separate thread; queue a message to set the property
2755       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2756
2757       break;
2758     }
2759
2760     case Property::VECTOR2:
2761     {
2762       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2763       DALI_ASSERT_DEBUG( NULL != property );
2764
2765       // property is being used in a separate thread; queue a message to set the property
2766       if(entry.componentIndex == 0)
2767       {
2768         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2769       }
2770       else if(entry.componentIndex == 1)
2771       {
2772         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2773       }
2774       else
2775       {
2776         SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2777       }
2778
2779       break;
2780     }
2781
2782     case Property::VECTOR3:
2783     {
2784       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2785       DALI_ASSERT_DEBUG( NULL != property );
2786
2787       // property is being used in a separate thread; queue a message to set the property
2788       if(entry.componentIndex == 0)
2789       {
2790         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2791       }
2792       else if(entry.componentIndex == 1)
2793       {
2794         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2795       }
2796       else if(entry.componentIndex == 2)
2797       {
2798         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2799       }
2800       else
2801       {
2802         SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2803       }
2804
2805       break;
2806     }
2807
2808     case Property::VECTOR4:
2809     {
2810       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2811       DALI_ASSERT_DEBUG( NULL != property );
2812
2813       // property is being used in a separate thread; queue a message to set the property
2814       if(entry.componentIndex == 0)
2815       {
2816         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2817       }
2818       else if(entry.componentIndex == 1)
2819       {
2820         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2821       }
2822       else if(entry.componentIndex == 2)
2823       {
2824         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2825       }
2826       else if(entry.componentIndex == 3)
2827       {
2828         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2829       }
2830       else
2831       {
2832         SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2833       }
2834
2835       break;
2836     }
2837
2838     case Property::ROTATION:
2839     {
2840       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2841       DALI_ASSERT_DEBUG( NULL != property );
2842
2843       // property is being used in a separate thread; queue a message to set the property
2844       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
2845
2846       break;
2847     }
2848
2849     case Property::MATRIX:
2850     {
2851       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2852       DALI_ASSERT_DEBUG( NULL != property );
2853
2854       // property is being used in a separate thread; queue a message to set the property
2855       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
2856
2857       break;
2858     }
2859
2860     case Property::MATRIX3:
2861     {
2862       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2863       DALI_ASSERT_DEBUG( NULL != property );
2864
2865       // property is being used in a separate thread; queue a message to set the property
2866       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
2867
2868       break;
2869     }
2870
2871     default:
2872     {
2873       // nothing to do for other types
2874     }
2875   } // entry.GetType
2876 }
2877
2878 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2879 {
2880   Property::Value value;
2881
2882   if( ! GetCachedPropertyValue( index, value ) )
2883   {
2884     // If property value is not stored in the event-side, then it must be a scene-graph only property
2885     GetCurrentPropertyValue( index, value );
2886   }
2887
2888   return value;
2889 }
2890
2891 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2892 {
2893   Property::Value value;
2894
2895   if( ! GetCurrentPropertyValue( index, value ) )
2896   {
2897     // If unable to retrieve scene-graph property value, then it must be an event-side only property
2898     GetCachedPropertyValue( index, value );
2899   }
2900
2901   return value;
2902 }
2903
2904 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2905 {
2906   switch( animationType )
2907   {
2908     case Animation::TO:
2909     case Animation::BETWEEN:
2910     {
2911       switch( index )
2912       {
2913         case Dali::Actor::Property::SIZE:
2914         {
2915           if( value.Get( mTargetSize ) )
2916           {
2917             // Notify deriving classes
2918             OnSizeAnimation( animation, mTargetSize );
2919           }
2920           break;
2921         }
2922
2923         case Dali::Actor::Property::SIZE_WIDTH:
2924         {
2925           if( value.Get( mTargetSize.width ) )
2926           {
2927             // Notify deriving classes
2928             OnSizeAnimation( animation, mTargetSize );
2929           }
2930           break;
2931         }
2932
2933         case Dali::Actor::Property::SIZE_HEIGHT:
2934         {
2935           if( value.Get( mTargetSize.height ) )
2936           {
2937             // Notify deriving classes
2938             OnSizeAnimation( animation, mTargetSize );
2939           }
2940           break;
2941         }
2942
2943         case Dali::Actor::Property::SIZE_DEPTH:
2944         {
2945           if( value.Get( mTargetSize.depth ) )
2946           {
2947             // Notify deriving classes
2948             OnSizeAnimation( animation, mTargetSize );
2949           }
2950           break;
2951         }
2952
2953         case Dali::Actor::Property::POSITION:
2954         {
2955           value.Get( mTargetPosition );
2956           break;
2957         }
2958
2959         case Dali::Actor::Property::POSITION_X:
2960         {
2961           value.Get( mTargetPosition.x );
2962           break;
2963         }
2964
2965         case Dali::Actor::Property::POSITION_Y:
2966         {
2967           value.Get( mTargetPosition.y );
2968           break;
2969         }
2970
2971         case Dali::Actor::Property::POSITION_Z:
2972         {
2973           value.Get( mTargetPosition.z );
2974           break;
2975         }
2976
2977         case Dali::Actor::Property::ORIENTATION:
2978         {
2979           value.Get( mTargetOrientation );
2980           break;
2981         }
2982
2983         case Dali::Actor::Property::SCALE:
2984         {
2985           value.Get( mTargetScale );
2986           break;
2987         }
2988
2989         case Dali::Actor::Property::SCALE_X:
2990         {
2991           value.Get( mTargetScale.x );
2992           break;
2993         }
2994
2995         case Dali::Actor::Property::SCALE_Y:
2996         {
2997           value.Get( mTargetScale.y );
2998           break;
2999         }
3000
3001         case Dali::Actor::Property::SCALE_Z:
3002         {
3003           value.Get( mTargetScale.z );
3004           break;
3005         }
3006
3007         case Dali::Actor::Property::VISIBLE:
3008         {
3009           SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3010           break;
3011         }
3012
3013         case Dali::Actor::Property::COLOR:
3014         {
3015           value.Get( mTargetColor );
3016           break;
3017         }
3018
3019         case Dali::Actor::Property::COLOR_RED:
3020         {
3021           value.Get( mTargetColor.r );
3022           break;
3023         }
3024
3025         case Dali::Actor::Property::COLOR_GREEN:
3026         {
3027           value.Get( mTargetColor.g );
3028           break;
3029         }
3030
3031         case Dali::Actor::Property::COLOR_BLUE:
3032         {
3033           value.Get( mTargetColor.b );
3034           break;
3035         }
3036
3037         case Dali::Actor::Property::COLOR_ALPHA:
3038         case Dali::DevelActor::Property::OPACITY:
3039         {
3040           value.Get( mTargetColor.a );
3041           break;
3042         }
3043
3044         default:
3045         {
3046           // Not an animatable property. Do nothing.
3047           break;
3048         }
3049       }
3050       break;
3051     }
3052
3053     case Animation::BY:
3054     {
3055       switch( index )
3056       {
3057         case Dali::Actor::Property::SIZE:
3058         {
3059           if( AdjustValue< Vector3 >( mTargetSize, value ) )
3060           {
3061             // Notify deriving classes
3062             OnSizeAnimation( animation, mTargetSize );
3063           }
3064           break;
3065         }
3066
3067         case Dali::Actor::Property::SIZE_WIDTH:
3068         {
3069           if( AdjustValue< float >( mTargetSize.width, value ) )
3070           {
3071             // Notify deriving classes
3072             OnSizeAnimation( animation, mTargetSize );
3073           }
3074           break;
3075         }
3076
3077         case Dali::Actor::Property::SIZE_HEIGHT:
3078         {
3079           if( AdjustValue< float >( mTargetSize.height, value ) )
3080           {
3081             // Notify deriving classes
3082             OnSizeAnimation( animation, mTargetSize );
3083           }
3084           break;
3085         }
3086
3087         case Dali::Actor::Property::SIZE_DEPTH:
3088         {
3089           if( AdjustValue< float >( mTargetSize.depth, value ) )
3090           {
3091             // Notify deriving classes
3092             OnSizeAnimation( animation, mTargetSize );
3093           }
3094           break;
3095         }
3096
3097         case Dali::Actor::Property::POSITION:
3098         {
3099           AdjustValue< Vector3 >( mTargetPosition, value );
3100           break;
3101         }
3102
3103         case Dali::Actor::Property::POSITION_X:
3104         {
3105           AdjustValue< float >( mTargetPosition.x, value );
3106           break;
3107         }
3108
3109         case Dali::Actor::Property::POSITION_Y:
3110         {
3111           AdjustValue< float >( mTargetPosition.y, value );
3112           break;
3113         }
3114
3115         case Dali::Actor::Property::POSITION_Z:
3116         {
3117           AdjustValue< float >( mTargetPosition.z, value );
3118           break;
3119         }
3120
3121         case Dali::Actor::Property::ORIENTATION:
3122         {
3123           Quaternion relativeValue;
3124           if( value.Get( relativeValue ) )
3125           {
3126             mTargetOrientation *= relativeValue;
3127           }
3128           break;
3129         }
3130
3131         case Dali::Actor::Property::SCALE:
3132         {
3133           AdjustValue< Vector3 >( mTargetScale, value );
3134           break;
3135         }
3136
3137         case Dali::Actor::Property::SCALE_X:
3138         {
3139           AdjustValue< float >( mTargetScale.x, value );
3140           break;
3141         }
3142
3143         case Dali::Actor::Property::SCALE_Y:
3144         {
3145           AdjustValue< float >( mTargetScale.y, value );
3146           break;
3147         }
3148
3149         case Dali::Actor::Property::SCALE_Z:
3150         {
3151           AdjustValue< float >( mTargetScale.z, value );
3152           break;
3153         }
3154
3155         case Dali::Actor::Property::VISIBLE:
3156         {
3157           bool relativeValue = false;
3158           if( value.Get( relativeValue ) )
3159           {
3160             bool visible = mVisible || relativeValue;
3161             SetVisibleInternal( visible, SendMessage::FALSE );
3162           }
3163           break;
3164         }
3165
3166         case Dali::Actor::Property::COLOR:
3167         {
3168           AdjustValue< Vector4 >( mTargetColor, value );
3169           break;
3170         }
3171
3172         case Dali::Actor::Property::COLOR_RED:
3173         {
3174           AdjustValue< float >( mTargetColor.r, value );
3175           break;
3176         }
3177
3178         case Dali::Actor::Property::COLOR_GREEN:
3179         {
3180           AdjustValue< float >( mTargetColor.g, value );
3181           break;
3182         }
3183
3184         case Dali::Actor::Property::COLOR_BLUE:
3185         {
3186           AdjustValue< float >( mTargetColor.b, value );
3187           break;
3188         }
3189
3190         case Dali::Actor::Property::COLOR_ALPHA:
3191         case Dali::DevelActor::Property::OPACITY:
3192         {
3193           AdjustValue< float >( mTargetColor.a, value );
3194           break;
3195         }
3196
3197         default:
3198         {
3199           // Not an animatable property. Do nothing.
3200           break;
3201         }
3202       }
3203       break;
3204     }
3205   }
3206 }
3207
3208 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3209 {
3210   const PropertyBase* property( NULL );
3211
3212   switch( index )
3213   {
3214     case Dali::Actor::Property::SIZE:        // FALLTHROUGH
3215     case Dali::Actor::Property::SIZE_WIDTH:  // FALLTHROUGH
3216     case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3217     case Dali::Actor::Property::SIZE_DEPTH:
3218     {
3219       property = &GetNode().mSize;
3220       break;
3221     }
3222     case Dali::Actor::Property::POSITION:   // FALLTHROUGH
3223     case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3224     case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3225     case Dali::Actor::Property::POSITION_Z:
3226     {
3227       property = &GetNode().mPosition;
3228       break;
3229     }
3230     case Dali::Actor::Property::ORIENTATION:
3231     {
3232       property = &GetNode().mOrientation;
3233       break;
3234     }
3235     case Dali::Actor::Property::SCALE:   // FALLTHROUGH
3236     case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3237     case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3238     case Dali::Actor::Property::SCALE_Z:
3239     {
3240       property = &GetNode().mScale;
3241       break;
3242     }
3243     case Dali::Actor::Property::VISIBLE:
3244     {
3245       property = &GetNode().mVisible;
3246       break;
3247     }
3248     case Dali::Actor::Property::COLOR:       // FALLTHROUGH
3249     case Dali::Actor::Property::COLOR_RED:   // FALLTHROUGH
3250     case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3251     case Dali::Actor::Property::COLOR_BLUE:  // FALLTHROUGH
3252     case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3253     case Dali::DevelActor::Property::OPACITY:
3254     {
3255       property = &GetNode().mColor;
3256       break;
3257     }
3258     default:
3259     {
3260       break;
3261     }
3262   }
3263   if( !property )
3264   {
3265     // not our property, ask base
3266     property = Object::GetSceneObjectAnimatableProperty( index );
3267   }
3268
3269   return property;
3270 }
3271
3272 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3273 {
3274   const PropertyInputImpl* property( NULL );
3275
3276   switch( index )
3277   {
3278     case Dali::Actor::Property::PARENT_ORIGIN:   // FALLTHROUGH
3279     case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3280     case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3281     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3282     {
3283       property = &GetNode().mParentOrigin;
3284       break;
3285     }
3286     case Dali::Actor::Property::ANCHOR_POINT:   // FALLTHROUGH
3287     case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3288     case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3289     case Dali::Actor::Property::ANCHOR_POINT_Z:
3290     {
3291       property = &GetNode().mAnchorPoint;
3292       break;
3293     }
3294     case Dali::Actor::Property::WORLD_POSITION:   // FALLTHROUGH
3295     case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3296     case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3297     case Dali::Actor::Property::WORLD_POSITION_Z:
3298     {
3299       property = &GetNode().mWorldPosition;
3300       break;
3301     }
3302     case Dali::Actor::Property::WORLD_ORIENTATION:
3303     {
3304       property = &GetNode().mWorldOrientation;
3305       break;
3306     }
3307     case Dali::Actor::Property::WORLD_SCALE:
3308     {
3309       property = &GetNode().mWorldScale;
3310       break;
3311     }
3312     case Dali::Actor::Property::WORLD_COLOR:
3313     {
3314       property = &GetNode().mWorldColor;
3315       break;
3316     }
3317     case Dali::Actor::Property::WORLD_MATRIX:
3318     {
3319       property = &GetNode().mWorldMatrix;
3320       break;
3321     }
3322     case Dali::DevelActor::Property::CULLED:
3323     {
3324       property = &GetNode().mCulled;
3325       break;
3326     }
3327     default:
3328     {
3329       break;
3330     }
3331   }
3332   if( !property )
3333   {
3334     // reuse animatable property getter as animatable properties are inputs as well
3335     // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3336     property = GetSceneObjectAnimatableProperty( index );
3337   }
3338
3339   return property;
3340 }
3341
3342 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3343 {
3344   int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3345
3346   switch( index )
3347   {
3348     case Dali::Actor::Property::PARENT_ORIGIN_X:
3349     case Dali::Actor::Property::ANCHOR_POINT_X:
3350     case Dali::Actor::Property::SIZE_WIDTH:
3351     case Dali::Actor::Property::POSITION_X:
3352     case Dali::Actor::Property::WORLD_POSITION_X:
3353     case Dali::Actor::Property::SCALE_X:
3354     case Dali::Actor::Property::COLOR_RED:
3355     {
3356       componentIndex = 0;
3357       break;
3358     }
3359
3360     case Dali::Actor::Property::PARENT_ORIGIN_Y:
3361     case Dali::Actor::Property::ANCHOR_POINT_Y:
3362     case Dali::Actor::Property::SIZE_HEIGHT:
3363     case Dali::Actor::Property::POSITION_Y:
3364     case Dali::Actor::Property::WORLD_POSITION_Y:
3365     case Dali::Actor::Property::SCALE_Y:
3366     case Dali::Actor::Property::COLOR_GREEN:
3367     {
3368       componentIndex = 1;
3369       break;
3370     }
3371
3372     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3373     case Dali::Actor::Property::ANCHOR_POINT_Z:
3374     case Dali::Actor::Property::SIZE_DEPTH:
3375     case Dali::Actor::Property::POSITION_Z:
3376     case Dali::Actor::Property::WORLD_POSITION_Z:
3377     case Dali::Actor::Property::SCALE_Z:
3378     case Dali::Actor::Property::COLOR_BLUE:
3379     {
3380       componentIndex = 2;
3381       break;
3382     }
3383
3384     case Dali::Actor::Property::COLOR_ALPHA:
3385     case Dali::DevelActor::Property::OPACITY:
3386     {
3387       componentIndex = 3;
3388       break;
3389     }
3390
3391     default:
3392     {
3393       // Do nothing
3394       break;
3395     }
3396   }
3397   if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3398   {
3399     // ask base
3400     componentIndex = Object::GetPropertyComponentIndex( index );
3401   }
3402
3403   return componentIndex;
3404 }
3405
3406 void Actor::SetParent( Actor* parent )
3407 {
3408   if( parent )
3409   {
3410     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3411
3412     mParent = parent;
3413
3414     mScene = parent->mScene;
3415
3416     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3417          parent->OnStage() )
3418     {
3419       // Instruct each actor to create a corresponding node in the scene graph
3420       ConnectToStage( parent->GetHierarchyDepth() );
3421     }
3422
3423     // Resolve the name and index for the child properties if any
3424     ResolveChildProperties();
3425   }
3426   else // parent being set to NULL
3427   {
3428     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3429
3430     mParent = NULL;
3431
3432     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3433          OnStage() )
3434     {
3435       // Disconnect the Node & its children from the scene-graph.
3436       DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3437
3438       // Instruct each actor to discard pointers to the scene-graph
3439       DisconnectFromStage();
3440     }
3441
3442     mScene = nullptr;
3443   }
3444 }
3445
3446 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3447 {
3448   bool done = false;
3449   Actor* actor = dynamic_cast< Actor* >( object );
3450
3451   if( actor )
3452   {
3453     if( 0 == actionName.compare( ACTION_SHOW ) )
3454     {
3455       actor->SetVisible( true );
3456       done = true;
3457     }
3458     else if( 0 == actionName.compare( ACTION_HIDE ) )
3459     {
3460       actor->SetVisible( false );
3461       done = true;
3462     }
3463   }
3464
3465   return done;
3466 }
3467
3468 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3469 {
3470   bool valueSet = true;
3471
3472   switch( index )
3473   {
3474     case Dali::Actor::Property::PARENT_ORIGIN:
3475     {
3476       value = GetCurrentParentOrigin();
3477       break;
3478     }
3479
3480     case Dali::Actor::Property::PARENT_ORIGIN_X:
3481     {
3482       value = GetCurrentParentOrigin().x;
3483       break;
3484     }
3485
3486     case Dali::Actor::Property::PARENT_ORIGIN_Y:
3487     {
3488       value = GetCurrentParentOrigin().y;
3489       break;
3490     }
3491
3492     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3493     {
3494       value = GetCurrentParentOrigin().z;
3495       break;
3496     }
3497
3498     case Dali::Actor::Property::ANCHOR_POINT:
3499     {
3500       value = GetCurrentAnchorPoint();
3501       break;
3502     }
3503
3504     case Dali::Actor::Property::ANCHOR_POINT_X:
3505     {
3506       value = GetCurrentAnchorPoint().x;
3507       break;
3508     }
3509
3510     case Dali::Actor::Property::ANCHOR_POINT_Y:
3511     {
3512       value = GetCurrentAnchorPoint().y;
3513       break;
3514     }
3515
3516     case Dali::Actor::Property::ANCHOR_POINT_Z:
3517     {
3518       value = GetCurrentAnchorPoint().z;
3519       break;
3520     }
3521
3522     case Dali::Actor::Property::SIZE:
3523     {
3524       value = GetTargetSize();
3525       break;
3526     }
3527
3528     case Dali::Actor::Property::SIZE_WIDTH:
3529     {
3530       value = GetTargetSize().width;
3531       break;
3532     }
3533
3534     case Dali::Actor::Property::SIZE_HEIGHT:
3535     {
3536       value = GetTargetSize().height;
3537       break;
3538     }
3539
3540     case Dali::Actor::Property::SIZE_DEPTH:
3541     {
3542       value = GetTargetSize().depth;
3543       break;
3544     }
3545
3546     case Dali::Actor::Property::POSITION:
3547     {
3548       value = GetTargetPosition();
3549       break;
3550     }
3551
3552     case Dali::Actor::Property::POSITION_X:
3553     {
3554       value = GetTargetPosition().x;
3555       break;
3556     }
3557
3558     case Dali::Actor::Property::POSITION_Y:
3559     {
3560       value = GetTargetPosition().y;
3561       break;
3562     }
3563
3564     case Dali::Actor::Property::POSITION_Z:
3565     {
3566       value = GetTargetPosition().z;
3567       break;
3568     }
3569
3570     case Dali::Actor::Property::ORIENTATION:
3571     {
3572       value = mTargetOrientation;
3573       break;
3574     }
3575
3576     case Dali::Actor::Property::SCALE:
3577     {
3578       value = mTargetScale;
3579       break;
3580     }
3581
3582     case Dali::Actor::Property::SCALE_X:
3583     {
3584       value = mTargetScale.x;
3585       break;
3586     }
3587
3588     case Dali::Actor::Property::SCALE_Y:
3589     {
3590       value = mTargetScale.y;
3591       break;
3592     }
3593
3594     case Dali::Actor::Property::SCALE_Z:
3595     {
3596       value = mTargetScale.z;
3597       break;
3598     }
3599
3600     case Dali::Actor::Property::VISIBLE:
3601     {
3602       value = mVisible;
3603       break;
3604     }
3605
3606     case Dali::Actor::Property::COLOR:
3607     {
3608       value = mTargetColor;
3609       break;
3610     }
3611
3612     case Dali::Actor::Property::COLOR_RED:
3613     {
3614       value = mTargetColor.r;
3615       break;
3616     }
3617
3618     case Dali::Actor::Property::COLOR_GREEN:
3619     {
3620       value = mTargetColor.g;
3621       break;
3622     }
3623
3624     case Dali::Actor::Property::COLOR_BLUE:
3625     {
3626       value = mTargetColor.b;
3627       break;
3628     }
3629
3630     case Dali::Actor::Property::COLOR_ALPHA:
3631     case Dali::DevelActor::Property::OPACITY:
3632     {
3633       value = mTargetColor.a;
3634       break;
3635     }
3636
3637     case Dali::Actor::Property::NAME:
3638     {
3639       value = GetName();
3640       break;
3641     }
3642
3643     case Dali::Actor::Property::SENSITIVE:
3644     {
3645       value = IsSensitive();
3646       break;
3647     }
3648
3649     case Dali::Actor::Property::LEAVE_REQUIRED:
3650     {
3651       value = GetLeaveRequired();
3652       break;
3653     }
3654
3655     case Dali::Actor::Property::INHERIT_POSITION:
3656     {
3657       value = IsPositionInherited();
3658       break;
3659     }
3660
3661     case Dali::Actor::Property::INHERIT_ORIENTATION:
3662     {
3663       value = IsOrientationInherited();
3664       break;
3665     }
3666
3667     case Dali::Actor::Property::INHERIT_SCALE:
3668     {
3669       value = IsScaleInherited();
3670       break;
3671     }
3672
3673     case Dali::Actor::Property::COLOR_MODE:
3674     {
3675       value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3676       break;
3677     }
3678
3679     case Dali::Actor::Property::DRAW_MODE:
3680     {
3681       value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3682       break;
3683     }
3684
3685     case Dali::Actor::Property::SIZE_MODE_FACTOR:
3686     {
3687       value = GetSizeModeFactor();
3688       break;
3689     }
3690
3691     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3692     {
3693       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3694       break;
3695     }
3696
3697     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3698     {
3699       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3700       break;
3701     }
3702
3703     case Dali::Actor::Property::SIZE_SCALE_POLICY:
3704     {
3705       value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3706       break;
3707     }
3708
3709     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3710     {
3711       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3712       break;
3713     }
3714
3715     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3716     {
3717       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3718       break;
3719     }
3720
3721     case Dali::Actor::Property::PADDING:
3722     {
3723       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3724       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3725       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3726       break;
3727     }
3728
3729     case Dali::Actor::Property::MINIMUM_SIZE:
3730     {
3731       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3732       break;
3733     }
3734
3735     case Dali::Actor::Property::MAXIMUM_SIZE:
3736     {
3737       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3738       break;
3739     }
3740
3741     case Dali::Actor::Property::CLIPPING_MODE:
3742     {
3743       value = mClippingMode;
3744       break;
3745     }
3746
3747     case Dali::DevelActor::Property::SIBLING_ORDER:
3748     {
3749       value = static_cast<int>( GetSiblingOrder() );
3750       break;
3751     }
3752
3753     case Dali::DevelActor::Property::SCREEN_POSITION:
3754     {
3755       value = GetCurrentScreenPosition();
3756       break;
3757     }
3758
3759     case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3760     {
3761       value = mPositionUsesAnchorPoint;
3762       break;
3763     }
3764
3765     case Dali::Actor::Property::LAYOUT_DIRECTION:
3766     {
3767       value = mLayoutDirection;
3768       break;
3769     }
3770
3771     case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3772     {
3773       value = IsLayoutDirectionInherited();
3774       break;
3775     }
3776
3777     default:
3778     {
3779       // Must be a scene-graph only property
3780       valueSet = false;
3781       break;
3782     }
3783   }
3784
3785   return valueSet;
3786 }
3787
3788 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value  ) const
3789 {
3790   bool valueSet = true;
3791
3792   switch( index )
3793   {
3794     case Dali::Actor::Property::SIZE:
3795     {
3796       value = GetCurrentSize();
3797       break;
3798     }
3799
3800     case Dali::Actor::Property::SIZE_WIDTH:
3801     {
3802       value = GetCurrentSize().width;
3803       break;
3804     }
3805
3806     case Dali::Actor::Property::SIZE_HEIGHT:
3807     {
3808       value = GetCurrentSize().height;
3809       break;
3810     }
3811
3812     case Dali::Actor::Property::SIZE_DEPTH:
3813     {
3814       value = GetCurrentSize().depth;
3815       break;
3816     }
3817
3818     case Dali::Actor::Property::POSITION:
3819     {
3820       value = GetCurrentPosition();
3821       break;
3822     }
3823
3824     case Dali::Actor::Property::POSITION_X:
3825     {
3826       value = GetCurrentPosition().x;
3827       break;
3828     }
3829
3830     case Dali::Actor::Property::POSITION_Y:
3831     {
3832       value = GetCurrentPosition().y;
3833       break;
3834     }
3835
3836     case Dali::Actor::Property::POSITION_Z:
3837     {
3838       value = GetCurrentPosition().z;
3839       break;
3840     }
3841
3842     case Dali::Actor::Property::WORLD_POSITION:
3843     {
3844       value = GetCurrentWorldPosition();
3845       break;
3846     }
3847
3848     case Dali::Actor::Property::WORLD_POSITION_X:
3849     {
3850       value = GetCurrentWorldPosition().x;
3851       break;
3852     }
3853
3854     case Dali::Actor::Property::WORLD_POSITION_Y:
3855     {
3856       value = GetCurrentWorldPosition().y;
3857       break;
3858     }
3859
3860     case Dali::Actor::Property::WORLD_POSITION_Z:
3861     {
3862       value = GetCurrentWorldPosition().z;
3863       break;
3864     }
3865
3866     case Dali::Actor::Property::ORIENTATION:
3867     {
3868       value = GetCurrentOrientation();
3869       break;
3870     }
3871
3872     case Dali::Actor::Property::WORLD_ORIENTATION:
3873     {
3874       value = GetCurrentWorldOrientation();
3875       break;
3876     }
3877
3878     case Dali::Actor::Property::SCALE:
3879     {
3880       value = GetCurrentScale();
3881       break;
3882     }
3883
3884     case Dali::Actor::Property::SCALE_X:
3885     {
3886       value = GetCurrentScale().x;
3887       break;
3888     }
3889
3890     case Dali::Actor::Property::SCALE_Y:
3891     {
3892       value = GetCurrentScale().y;
3893       break;
3894     }
3895
3896     case Dali::Actor::Property::SCALE_Z:
3897     {
3898       value = GetCurrentScale().z;
3899       break;
3900     }
3901
3902     case Dali::Actor::Property::WORLD_SCALE:
3903     {
3904       value = GetCurrentWorldScale();
3905       break;
3906     }
3907
3908     case Dali::Actor::Property::COLOR:
3909     {
3910       value = GetCurrentColor();
3911       break;
3912     }
3913
3914     case Dali::Actor::Property::COLOR_RED:
3915     {
3916       value = GetCurrentColor().r;
3917       break;
3918     }
3919
3920     case Dali::Actor::Property::COLOR_GREEN:
3921     {
3922       value = GetCurrentColor().g;
3923       break;
3924     }
3925
3926     case Dali::Actor::Property::COLOR_BLUE:
3927     {
3928       value = GetCurrentColor().b;
3929       break;
3930     }
3931
3932     case Dali::Actor::Property::COLOR_ALPHA:
3933     case Dali::DevelActor::Property::OPACITY:
3934     {
3935       value = GetCurrentColor().a;
3936       break;
3937     }
3938
3939     case Dali::Actor::Property::WORLD_COLOR:
3940     {
3941       value = GetCurrentWorldColor();
3942       break;
3943     }
3944
3945     case Dali::Actor::Property::WORLD_MATRIX:
3946     {
3947       value = GetCurrentWorldMatrix();
3948       break;
3949     }
3950
3951     case Dali::Actor::Property::VISIBLE:
3952     {
3953       value = IsVisible();
3954       break;
3955     }
3956
3957     case DevelActor::Property::CULLED:
3958     {
3959       value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
3960       break;
3961     }
3962
3963     default:
3964     {
3965       // Must be an event-side only property
3966       valueSet = false;
3967       break;
3968     }
3969   }
3970
3971   return valueSet;
3972 }
3973
3974 void Actor::EnsureRelayoutData()
3975 {
3976   // Assign relayout data.
3977   if( !mRelayoutData )
3978   {
3979     mRelayoutData = new RelayoutData();
3980   }
3981 }
3982
3983 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3984 {
3985   // Check if actor is dependent on parent
3986   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3987   {
3988     if( ( dimension & ( 1 << i ) ) )
3989     {
3990       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3991       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3992       {
3993         return true;
3994       }
3995     }
3996   }
3997
3998   return false;
3999 }
4000
4001 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4002 {
4003   // Check if actor is dependent on children
4004   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4005   {
4006     if( ( dimension & ( 1 << i ) ) )
4007     {
4008       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4009       switch( resizePolicy )
4010       {
4011         case ResizePolicy::FIT_TO_CHILDREN:
4012         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
4013         {
4014           return true;
4015         }
4016
4017         default:
4018         {
4019           break;
4020         }
4021       }
4022     }
4023   }
4024
4025   return false;
4026 }
4027
4028 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4029 {
4030   return Actor::RelayoutDependentOnChildren( dimension );
4031 }
4032
4033 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4034 {
4035   // Check each possible dimension and see if it is dependent on the input one
4036   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4037   {
4038     if( dimension & ( 1 << i ) )
4039     {
4040       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4041     }
4042   }
4043
4044   return false;
4045 }
4046
4047 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4048 {
4049   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4050   {
4051     if( dimension & ( 1 << i ) )
4052     {
4053       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4054     }
4055   }
4056 }
4057
4058 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4059 {
4060   // If more than one dimension is requested, just return the first one found
4061   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4062   {
4063     if( ( dimension & ( 1 << i ) ) )
4064     {
4065       return mRelayoutData->negotiatedDimensions[ i ];
4066     }
4067   }
4068
4069   return 0.0f;   // Default
4070 }
4071
4072 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4073 {
4074   EnsureRelayoutData();
4075
4076   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4077   {
4078     if( dimension & ( 1 << i ) )
4079     {
4080       mRelayoutData->dimensionPadding[ i ] = padding;
4081     }
4082   }
4083 }
4084
4085 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4086 {
4087   if ( mRelayoutData )
4088   {
4089     // If more than one dimension is requested, just return the first one found
4090     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4091     {
4092       if( ( dimension & ( 1 << i ) ) )
4093       {
4094         return mRelayoutData->dimensionPadding[ i ];
4095       }
4096     }
4097   }
4098
4099   return GetDefaultDimensionPadding();
4100 }
4101
4102 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4103 {
4104   EnsureRelayoutData();
4105
4106   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4107   {
4108     if( dimension & ( 1 << i ) )
4109     {
4110       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4111     }
4112   }
4113 }
4114
4115 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4116 {
4117   if ( mRelayoutData )
4118   {
4119     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4120     {
4121       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4122       {
4123         return true;
4124       }
4125     }
4126   }
4127
4128   return false;
4129 }
4130
4131 float Actor::GetHeightForWidthBase( float width )
4132 {
4133   float height = 0.0f;
4134
4135   const Vector3 naturalSize = GetNaturalSize();
4136   if( naturalSize.width > 0.0f )
4137   {
4138     height = naturalSize.height * width / naturalSize.width;
4139   }
4140   else // we treat 0 as 1:1 aspect ratio
4141   {
4142     height = width;
4143   }
4144
4145   return height;
4146 }
4147
4148 float Actor::GetWidthForHeightBase( float height )
4149 {
4150   float width = 0.0f;
4151
4152   const Vector3 naturalSize = GetNaturalSize();
4153   if( naturalSize.height > 0.0f )
4154   {
4155     width = naturalSize.width * height / naturalSize.height;
4156   }
4157   else // we treat 0 as 1:1 aspect ratio
4158   {
4159     width = height;
4160   }
4161
4162   return width;
4163 }
4164
4165 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4166 {
4167   // Fill to parent, taking size mode factor into account
4168   switch( child.GetResizePolicy( dimension ) )
4169   {
4170     case ResizePolicy::FILL_TO_PARENT:
4171     {
4172       return GetLatestSize( dimension );
4173     }
4174
4175     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4176     {
4177       return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4178     }
4179
4180     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4181     {
4182       return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4183     }
4184
4185     default:
4186     {
4187       return GetLatestSize( dimension );
4188     }
4189   }
4190 }
4191
4192 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4193 {
4194   // Can be overridden in derived class
4195   return CalculateChildSizeBase( child, dimension );
4196 }
4197
4198 float Actor::GetHeightForWidth( float width )
4199 {
4200   // Can be overridden in derived class
4201   return GetHeightForWidthBase( width );
4202 }
4203
4204 float Actor::GetWidthForHeight( float height )
4205 {
4206   // Can be overridden in derived class
4207   return GetWidthForHeightBase( height );
4208 }
4209
4210 float Actor::GetLatestSize( Dimension::Type dimension ) const
4211 {
4212   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4213 }
4214
4215 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4216 {
4217   Vector2 padding = GetPadding( dimension );
4218
4219   return GetLatestSize( dimension ) + padding.x + padding.y;
4220 }
4221
4222 float Actor::NegotiateFromParent( Dimension::Type dimension )
4223 {
4224   Actor* parent = GetParent();
4225   if( parent )
4226   {
4227     Vector2 padding( GetPadding( dimension ) );
4228     Vector2 parentPadding( parent->GetPadding( dimension ) );
4229     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4230   }
4231
4232   return 0.0f;
4233 }
4234
4235 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4236 {
4237   float maxDimensionPoint = 0.0f;
4238
4239   for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4240   {
4241     ActorPtr child = GetChildAt( i );
4242
4243     if( !child->RelayoutDependentOnParent( dimension ) )
4244     {
4245       // Calculate the min and max points that the children range across
4246       float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4247       float dimensionSize = child->GetRelayoutSize( dimension );
4248       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4249     }
4250   }
4251
4252   return maxDimensionPoint;
4253 }
4254
4255 float Actor::GetSize( Dimension::Type dimension ) const
4256 {
4257   return GetDimensionValue( mTargetSize, dimension );
4258 }
4259
4260 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4261 {
4262   return GetDimensionValue( GetNaturalSize(), dimension );
4263 }
4264
4265 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4266 {
4267   switch( GetResizePolicy( dimension ) )
4268   {
4269     case ResizePolicy::USE_NATURAL_SIZE:
4270     {
4271       return GetNaturalSize( dimension );
4272     }
4273
4274     case ResizePolicy::FIXED:
4275     {
4276       return GetDimensionValue( GetPreferredSize(), dimension );
4277     }
4278
4279     case ResizePolicy::USE_ASSIGNED_SIZE:
4280     {
4281       return GetDimensionValue( maximumSize, dimension );
4282     }
4283
4284     case ResizePolicy::FILL_TO_PARENT:
4285     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4286     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4287     {
4288       return NegotiateFromParent( dimension );
4289     }
4290
4291     case ResizePolicy::FIT_TO_CHILDREN:
4292     {
4293       return NegotiateFromChildren( dimension );
4294     }
4295
4296     case ResizePolicy::DIMENSION_DEPENDENCY:
4297     {
4298       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4299
4300       // Custom rules
4301       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4302       {
4303         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4304       }
4305
4306       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4307       {
4308         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4309       }
4310
4311       break;
4312     }
4313
4314     default:
4315     {
4316       break;
4317     }
4318   }
4319
4320   return 0.0f;  // Default
4321 }
4322
4323 float Actor::ClampDimension( float size, Dimension::Type dimension )
4324 {
4325   const float minSize = GetMinimumSize( dimension );
4326   const float maxSize = GetMaximumSize( dimension );
4327
4328   return std::max( minSize, std::min( size, maxSize ) );
4329 }
4330
4331 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4332 {
4333   // Check if it needs to be negotiated
4334   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4335   {
4336     // Check that we havn't gotten into an infinite loop
4337     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4338     bool recursionFound = false;
4339     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4340     {
4341       if( *it == searchActor )
4342       {
4343         recursionFound = true;
4344         break;
4345       }
4346     }
4347
4348     if( !recursionFound )
4349     {
4350       // Record the path that we have taken
4351       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4352
4353       // Dimension dependency check
4354       for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4355       {
4356         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4357
4358         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4359         {
4360           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4361         }
4362       }
4363
4364       // Parent dependency check
4365       Actor* parent = GetParent();
4366       if( parent && RelayoutDependentOnParent( dimension ) )
4367       {
4368         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4369       }
4370
4371       // Children dependency check
4372       if( RelayoutDependentOnChildren( dimension ) )
4373       {
4374         for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4375         {
4376           ActorPtr child = GetChildAt( i );
4377
4378           // Only relayout child first if it is not dependent on this actor
4379           if( !child->RelayoutDependentOnParent( dimension ) )
4380           {
4381             child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4382           }
4383         }
4384       }
4385
4386       // For deriving classes
4387       OnCalculateRelayoutSize( dimension );
4388
4389       // All dependencies checked, calculate the size and set negotiated flag
4390       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4391
4392       SetNegotiatedDimension( newSize, dimension );
4393       SetLayoutNegotiated( true, dimension );
4394
4395       // For deriving classes
4396       OnLayoutNegotiated( newSize, dimension );
4397
4398       // This actor has been successfully processed, pop it off the recursion stack
4399       recursionStack.pop_back();
4400     }
4401     else
4402     {
4403       // TODO: Break infinite loop
4404       SetLayoutNegotiated( true, dimension );
4405     }
4406   }
4407 }
4408
4409 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4410 {
4411   // Negotiate all dimensions that require it
4412   ActorDimensionStack recursionStack;
4413
4414   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4415   {
4416     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4417
4418     // Negotiate
4419     NegotiateDimension( dimension, allocatedSize, recursionStack );
4420   }
4421 }
4422
4423 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4424 {
4425   switch( mRelayoutData->sizeSetPolicy )
4426   {
4427     case SizeScalePolicy::USE_SIZE_SET:
4428     {
4429       return size;
4430     }
4431
4432     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4433     {
4434       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4435       const Vector3 naturalSize = GetNaturalSize();
4436       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4437       {
4438         const float sizeRatio = size.width / size.height;
4439         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4440
4441         if( naturalSizeRatio < sizeRatio )
4442         {
4443           return Vector2( naturalSizeRatio * size.height, size.height );
4444         }
4445         else if( naturalSizeRatio > sizeRatio )
4446         {
4447           return Vector2( size.width, size.width / naturalSizeRatio );
4448         }
4449         else
4450         {
4451           return size;
4452         }
4453       }
4454
4455       break;
4456     }
4457
4458     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4459     {
4460       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4461       const Vector3 naturalSize = GetNaturalSize();
4462       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4463       {
4464         const float sizeRatio = size.width / size.height;
4465         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4466
4467         if( naturalSizeRatio < sizeRatio )
4468         {
4469           return Vector2( size.width, size.width / naturalSizeRatio );
4470         }
4471         else if( naturalSizeRatio > sizeRatio )
4472         {
4473           return Vector2( naturalSizeRatio * size.height, size.height );
4474         }
4475         else
4476         {
4477           return size;
4478         }
4479       }
4480       break;
4481     }
4482
4483     default:
4484     {
4485       break;
4486     }
4487   }
4488
4489   return size;
4490 }
4491
4492 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4493 {
4494   // Do the set actor size
4495   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4496
4497   // Adjust for size set policy
4498   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4499
4500   // Lock the flag to stop recursive relayouts on set size
4501   mRelayoutData->insideRelayout = true;
4502   SetSize( negotiatedSize );
4503   mRelayoutData->insideRelayout = false;
4504
4505   // Clear flags for all dimensions
4506   SetLayoutDirty( false );
4507
4508   // Give deriving classes a chance to respond
4509   OnRelayout( negotiatedSize, container );
4510
4511   if( !mOnRelayoutSignal.Empty() )
4512   {
4513     Dali::Actor handle( this );
4514     mOnRelayoutSignal.Emit( handle );
4515   }
4516 }
4517
4518 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4519 {
4520   // Force a size negotiation for actors that has assigned size during relayout
4521   // This is required as otherwise the flags that force a relayout will not
4522   // necessarilly be set. This will occur if the actor has already been laid out.
4523   // The dirty flags are then cleared. Then if the actor is added back into the
4524   // relayout container afterwards, the dirty flags would still be clear...
4525   // causing a relayout to be skipped. Here we force any actors added to the
4526   // container to be relayed out.
4527   DALI_LOG_TIMER_START( NegSizeTimer1 );
4528
4529   if( GetUseAssignedSize(Dimension::WIDTH ) )
4530   {
4531     SetLayoutNegotiated( false, Dimension::WIDTH );
4532   }
4533   if( GetUseAssignedSize( Dimension::HEIGHT ) )
4534   {
4535     SetLayoutNegotiated( false, Dimension::HEIGHT );
4536   }
4537
4538   // Do the negotiation
4539   NegotiateDimensions( allocatedSize );
4540
4541   // Set the actor size
4542   SetNegotiatedSize( container );
4543
4544   // Negotiate down to children
4545   for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4546   {
4547     ActorPtr child = GetChildAt( i );
4548
4549     // Forces children that have already been laid out to be relayed out
4550     // if they have assigned size during relayout.
4551     if( child->GetUseAssignedSize(Dimension::WIDTH) )
4552     {
4553       child->SetLayoutNegotiated(false, Dimension::WIDTH);
4554       child->SetLayoutDirty(true, Dimension::WIDTH);
4555     }
4556
4557     if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4558     {
4559       child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4560       child->SetLayoutDirty(true, Dimension::HEIGHT);
4561     }
4562
4563     // Only relayout if required
4564     if( child->RelayoutRequired() )
4565     {
4566       container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4567     }
4568   }
4569   DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4570 }
4571
4572 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4573 {
4574   if( mRelayoutData )
4575   {
4576     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4577     {
4578       if( dimension & ( 1 << i ) )
4579       {
4580         mRelayoutData->useAssignedSize[ i ] = use;
4581       }
4582     }
4583   }
4584 }
4585
4586 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4587 {
4588   if ( mRelayoutData )
4589   {
4590     // If more than one dimension is requested, just return the first one found
4591     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4592     {
4593       if( dimension & ( 1 << i ) )
4594       {
4595         return mRelayoutData->useAssignedSize[ i ];
4596       }
4597     }
4598   }
4599
4600   return false;
4601 }
4602
4603 void Actor::RelayoutRequest( Dimension::Type dimension )
4604 {
4605   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4606   if( relayoutController )
4607   {
4608     Dali::Actor self( this );
4609     relayoutController->RequestRelayout( self, dimension );
4610   }
4611 }
4612
4613 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4614 {
4615 }
4616
4617 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4618 {
4619 }
4620
4621 void Actor::SetPreferredSize( const Vector2& size )
4622 {
4623   EnsureRelayoutData();
4624
4625   if( size.width > 0.0f )
4626   {
4627     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4628   }
4629
4630   if( size.height > 0.0f )
4631   {
4632     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4633   }
4634
4635   mRelayoutData->preferredSize = size;
4636
4637   RelayoutRequest();
4638 }
4639
4640 Vector2 Actor::GetPreferredSize() const
4641 {
4642   if ( mRelayoutData )
4643   {
4644     return Vector2( mRelayoutData->preferredSize );
4645   }
4646
4647   return GetDefaultPreferredSize();
4648 }
4649
4650 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4651 {
4652   EnsureRelayoutData();
4653
4654   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4655   {
4656     if( dimension & ( 1 << i ) )
4657     {
4658       mRelayoutData->minimumSize[ i ] = size;
4659     }
4660   }
4661
4662   RelayoutRequest();
4663 }
4664
4665 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4666 {
4667   if ( mRelayoutData )
4668   {
4669     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4670     {
4671       if( dimension & ( 1 << i ) )
4672       {
4673         return mRelayoutData->minimumSize[ i ];
4674       }
4675     }
4676   }
4677
4678   return 0.0f;  // Default
4679 }
4680
4681 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4682 {
4683   EnsureRelayoutData();
4684
4685   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4686   {
4687     if( dimension & ( 1 << i ) )
4688     {
4689       mRelayoutData->maximumSize[ i ] = size;
4690     }
4691   }
4692
4693   RelayoutRequest();
4694 }
4695
4696 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4697 {
4698   if ( mRelayoutData )
4699   {
4700     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4701     {
4702       if( dimension & ( 1 << i ) )
4703       {
4704         return mRelayoutData->maximumSize[ i ];
4705       }
4706     }
4707   }
4708
4709   return FLT_MAX;  // Default
4710 }
4711
4712 Object* Actor::GetParentObject() const
4713 {
4714   return mParent;
4715 }
4716
4717 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4718 {
4719   if( mVisible != visible )
4720   {
4721     if( sendMessage == SendMessage::TRUE )
4722     {
4723       // node is being used in a separate thread; queue a message to set the value & base value
4724       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4725     }
4726
4727     mVisible = visible;
4728
4729     // Emit the signal on this actor and all its children
4730     EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4731   }
4732 }
4733
4734 void Actor::SetSiblingOrder( uint32_t order )
4735 {
4736   if ( mParent )
4737   {
4738     ActorContainer& siblings = *(mParent->mChildren);
4739     uint32_t currentOrder = GetSiblingOrder();
4740
4741     if( order != currentOrder )
4742     {
4743       if( order == 0 )
4744       {
4745         LowerToBottom();
4746       }
4747       else if( order < siblings.size() -1 )
4748       {
4749         if( order > currentOrder )
4750         {
4751           RaiseAbove( *siblings[order] );
4752         }
4753         else
4754         {
4755           LowerBelow( *siblings[order] );
4756         }
4757       }
4758       else
4759       {
4760         RaiseToTop();
4761       }
4762     }
4763   }
4764 }
4765
4766 uint32_t Actor::GetSiblingOrder() const
4767 {
4768   uint32_t order = 0;
4769
4770   if ( mParent )
4771   {
4772     ActorContainer& siblings = *(mParent->mChildren);
4773     for( std::size_t i = 0; i < siblings.size(); ++i )
4774     {
4775       if( siblings[i] == this )
4776       {
4777         order = static_cast<uint32_t>( i );
4778         break;
4779       }
4780     }
4781   }
4782
4783   return order;
4784 }
4785
4786 void Actor::RequestRebuildDepthTree()
4787 {
4788   if( mIsOnStage )
4789   {
4790     if( mScene )
4791     {
4792       mScene->RequestRebuildDepthTree();
4793     }
4794   }
4795 }
4796
4797 void Actor::Raise()
4798 {
4799   if ( mParent )
4800   {
4801     ActorContainer& siblings = *(mParent->mChildren);
4802     if( siblings.back() != this ) // If not already at end
4803     {
4804       for( std::size_t i=0; i<siblings.size(); ++i )
4805       {
4806         if( siblings[i] == this )
4807         {
4808           // Swap with next
4809           ActorPtr next = siblings[i+1];
4810           siblings[i+1] = this;
4811           siblings[i] = next;
4812           break;
4813         }
4814       }
4815     }
4816
4817     Dali::Actor handle( this );
4818     mParent->mChildOrderChangedSignal.Emit( handle );
4819
4820     RequestRebuildDepthTree();
4821   }
4822   else
4823   {
4824     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4825   }
4826 }
4827
4828 void Actor::Lower()
4829 {
4830   if ( mParent )
4831   {
4832     ActorContainer& siblings = *(mParent->mChildren);
4833     if( siblings.front() != this ) // If not already at beginning
4834     {
4835       for( std::size_t i=1; i<siblings.size(); ++i )
4836       {
4837         if( siblings[i] == this )
4838         {
4839           // Swap with previous
4840           ActorPtr previous = siblings[i-1];
4841           siblings[i-1] = this;
4842           siblings[i] = previous;
4843           break;
4844         }
4845       }
4846     }
4847
4848     Dali::Actor handle( this );
4849     mParent->mChildOrderChangedSignal.Emit( handle );
4850
4851     RequestRebuildDepthTree();
4852   }
4853   else
4854   {
4855     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4856   }
4857 }
4858
4859 void Actor::RaiseToTop()
4860 {
4861   if ( mParent )
4862   {
4863     ActorContainer& siblings = *(mParent->mChildren);
4864     if( siblings.back() != this ) // If not already at end
4865     {
4866       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4867       if( iter != siblings.end() )
4868       {
4869         siblings.erase(iter);
4870         siblings.push_back(ActorPtr(this));
4871       }
4872     }
4873
4874     Dali::Actor handle( this );
4875     mParent->mChildOrderChangedSignal.Emit( handle );
4876
4877     RequestRebuildDepthTree();
4878   }
4879   else
4880   {
4881     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4882   }
4883 }
4884
4885 void Actor::LowerToBottom()
4886 {
4887   if ( mParent )
4888   {
4889     ActorContainer& siblings = *(mParent->mChildren);
4890     if( siblings.front() != this ) // If not already at bottom,
4891     {
4892       ActorPtr thisPtr(this); // ensure this actor remains referenced.
4893
4894       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4895       if( iter != siblings.end() )
4896       {
4897         siblings.erase(iter);
4898         siblings.insert(siblings.begin(), thisPtr);
4899       }
4900     }
4901
4902     Dali::Actor handle( this );
4903     mParent->mChildOrderChangedSignal.Emit( handle );
4904
4905     RequestRebuildDepthTree();
4906   }
4907   else
4908   {
4909     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4910   }
4911 }
4912
4913 void Actor::RaiseAbove( Internal::Actor& target )
4914 {
4915   if ( mParent )
4916   {
4917     ActorContainer& siblings = *(mParent->mChildren);
4918     if( siblings.back() != this && target.mParent == mParent ) // If not already at top
4919     {
4920       ActorPtr thisPtr(this); // ensure this actor remains referenced.
4921
4922       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
4923       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
4924       if( thisIter < targetIter )
4925       {
4926         siblings.erase(thisIter);
4927         // Erasing early invalidates the targetIter. (Conversely, inserting first may also
4928         // invalidate thisIter)
4929         targetIter = std::find( siblings.begin(), siblings.end(), &target );
4930         ++targetIter;
4931         siblings.insert(targetIter, thisPtr);
4932       }
4933
4934       Dali::Actor handle( this );
4935       mParent->mChildOrderChangedSignal.Emit( handle );
4936
4937       RequestRebuildDepthTree();
4938     }
4939   }
4940   else
4941   {
4942     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4943   }
4944 }
4945
4946 void Actor::LowerBelow( Internal::Actor& target )
4947 {
4948   if ( mParent )
4949   {
4950     ActorContainer& siblings = *(mParent->mChildren);
4951     if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
4952     {
4953       ActorPtr thisPtr(this); // ensure this actor remains referenced.
4954
4955       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
4956       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
4957
4958       if( thisIter > targetIter )
4959       {
4960         siblings.erase(thisIter); // this only invalidates iterators at or after this point.
4961         siblings.insert(targetIter, thisPtr);
4962       }
4963
4964       Dali::Actor handle( this );
4965       mParent->mChildOrderChangedSignal.Emit( handle );
4966
4967       RequestRebuildDepthTree();
4968     }
4969   }
4970   else
4971   {
4972     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4973   }
4974 }
4975
4976 void Actor::SetScene( Scene& scene )
4977 {
4978   mScene = &scene;
4979 }
4980
4981 Scene& Actor::GetScene() const
4982 {
4983   return *mScene;
4984 }
4985
4986 void Actor::SetInheritLayoutDirection( bool inherit )
4987 {
4988   if( mInheritLayoutDirection != inherit )
4989   {
4990     mInheritLayoutDirection = inherit;
4991
4992     if( inherit && mParent )
4993     {
4994       InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
4995     }
4996   }
4997 }
4998
4999 bool Actor::IsLayoutDirectionInherited() const
5000 {
5001   return mInheritLayoutDirection;
5002 }
5003
5004 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5005 {
5006   if( actor && ( actor->mInheritLayoutDirection || set ) )
5007   {
5008     if( actor->mLayoutDirection != direction )
5009     {
5010       actor->mLayoutDirection = direction;
5011       actor->EmitLayoutDirectionChangedSignal( direction );
5012       actor->RelayoutRequest();
5013     }
5014
5015     if( actor->GetChildCount() > 0 )
5016     {
5017       ActorContainer& children = actor->GetChildrenInternal();
5018       for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5019       {
5020         InheritLayoutDirectionRecursively( *iter, direction );
5021       }
5022     }
5023   }
5024 }
5025
5026 } // namespace Internal
5027
5028 } // namespace Dali