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