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