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