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