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