f7df4d42aafd6e84a51ca792c3d2bafb2f594f18
[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( "inheritLayoutDirection",    BOOLEAN,  true,  false, false, Dali::DevelActor::Property::INHERIT_LAYOUT_DIRECTION )
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   mInheritLayoutDirection( 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
2891       if( Scripting::GetEnumerationProperty< DevelActor::LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2892       {
2893         mInheritLayoutDirection = false;
2894         InheritLayoutDirectionRecursively( this, direction, true );
2895       }
2896       break;
2897     }
2898
2899     case Dali::DevelActor::Property::INHERIT_LAYOUT_DIRECTION:
2900     {
2901       bool value = false;
2902       if( property.Get( value ) )
2903       {
2904         SetInheritLayoutDirection( value );
2905       }
2906       break;
2907     }
2908
2909     default:
2910     {
2911       // this can happen in the case of a non-animatable default property so just do nothing
2912       break;
2913     }
2914   }
2915 }
2916
2917 // TODO: This method needs to be removed
2918 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2919 {
2920   switch( entry.GetType() )
2921   {
2922     case Property::BOOLEAN:
2923     {
2924       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2925       DALI_ASSERT_DEBUG( NULL != property );
2926
2927       // property is being used in a separate thread; queue a message to set the property
2928       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2929
2930       break;
2931     }
2932
2933     case Property::INTEGER:
2934     {
2935       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2936       DALI_ASSERT_DEBUG( NULL != property );
2937
2938       // property is being used in a separate thread; queue a message to set the property
2939       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2940
2941       break;
2942     }
2943
2944     case Property::FLOAT:
2945     {
2946       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2947       DALI_ASSERT_DEBUG( NULL != property );
2948
2949       // property is being used in a separate thread; queue a message to set the property
2950       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2951
2952       break;
2953     }
2954
2955     case Property::VECTOR2:
2956     {
2957       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2958       DALI_ASSERT_DEBUG( NULL != property );
2959
2960       // property is being used in a separate thread; queue a message to set the property
2961       if(entry.componentIndex == 0)
2962       {
2963         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2964       }
2965       else if(entry.componentIndex == 1)
2966       {
2967         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2968       }
2969       else
2970       {
2971         SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2972       }
2973
2974       break;
2975     }
2976
2977     case Property::VECTOR3:
2978     {
2979       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2980       DALI_ASSERT_DEBUG( NULL != property );
2981
2982       // property is being used in a separate thread; queue a message to set the property
2983       if(entry.componentIndex == 0)
2984       {
2985         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2986       }
2987       else if(entry.componentIndex == 1)
2988       {
2989         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2990       }
2991       else if(entry.componentIndex == 2)
2992       {
2993         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2994       }
2995       else
2996       {
2997         SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2998       }
2999
3000       break;
3001     }
3002
3003     case Property::VECTOR4:
3004     {
3005       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
3006       DALI_ASSERT_DEBUG( NULL != property );
3007
3008       // property is being used in a separate thread; queue a message to set the property
3009       if(entry.componentIndex == 0)
3010       {
3011         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3012       }
3013       else if(entry.componentIndex == 1)
3014       {
3015         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3016       }
3017       else if(entry.componentIndex == 2)
3018       {
3019         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3020       }
3021       else if(entry.componentIndex == 3)
3022       {
3023         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3024       }
3025       else
3026       {
3027         SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3028       }
3029
3030       break;
3031     }
3032
3033     case Property::ROTATION:
3034     {
3035       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3036       DALI_ASSERT_DEBUG( NULL != property );
3037
3038       // property is being used in a separate thread; queue a message to set the property
3039       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
3040
3041       break;
3042     }
3043
3044     case Property::MATRIX:
3045     {
3046       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3047       DALI_ASSERT_DEBUG( NULL != property );
3048
3049       // property is being used in a separate thread; queue a message to set the property
3050       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
3051
3052       break;
3053     }
3054
3055     case Property::MATRIX3:
3056     {
3057       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3058       DALI_ASSERT_DEBUG( NULL != property );
3059
3060       // property is being used in a separate thread; queue a message to set the property
3061       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
3062
3063       break;
3064     }
3065
3066     default:
3067     {
3068       // nothing to do for other types
3069     }
3070   } // entry.GetType
3071 }
3072
3073 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3074 {
3075   Property::Value value;
3076
3077   if( ! GetCachedPropertyValue( index, value ) )
3078   {
3079     // If property value is not stored in the event-side, then it must be a scene-graph only property
3080     GetCurrentPropertyValue( index, value );
3081   }
3082
3083   return value;
3084 }
3085
3086 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3087 {
3088   Property::Value value;
3089
3090   if( ! GetCurrentPropertyValue( index, value ) )
3091   {
3092     // If unable to retrieve scene-graph property value, then it must be an event-side only property
3093     GetCachedPropertyValue( index, value );
3094   }
3095
3096   return value;
3097 }
3098
3099 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3100 {
3101   switch( animationType )
3102   {
3103     case Animation::TO:
3104     case Animation::BETWEEN:
3105     {
3106       switch( index )
3107       {
3108         case Dali::Actor::Property::SIZE:
3109         {
3110           if( value.Get( mTargetSize ) )
3111           {
3112             // Notify deriving classes
3113             OnSizeAnimation( animation, mTargetSize );
3114           }
3115           break;
3116         }
3117
3118         case Dali::Actor::Property::SIZE_WIDTH:
3119         {
3120           if( value.Get( mTargetSize.width ) )
3121           {
3122             // Notify deriving classes
3123             OnSizeAnimation( animation, mTargetSize );
3124           }
3125           break;
3126         }
3127
3128         case Dali::Actor::Property::SIZE_HEIGHT:
3129         {
3130           if( value.Get( mTargetSize.height ) )
3131           {
3132             // Notify deriving classes
3133             OnSizeAnimation( animation, mTargetSize );
3134           }
3135           break;
3136         }
3137
3138         case Dali::Actor::Property::SIZE_DEPTH:
3139         {
3140           if( value.Get( mTargetSize.depth ) )
3141           {
3142             // Notify deriving classes
3143             OnSizeAnimation( animation, mTargetSize );
3144           }
3145           break;
3146         }
3147
3148         case Dali::Actor::Property::POSITION:
3149         {
3150           value.Get( mTargetPosition );
3151           break;
3152         }
3153
3154         case Dali::Actor::Property::POSITION_X:
3155         {
3156           value.Get( mTargetPosition.x );
3157           break;
3158         }
3159
3160         case Dali::Actor::Property::POSITION_Y:
3161         {
3162           value.Get( mTargetPosition.y );
3163           break;
3164         }
3165
3166         case Dali::Actor::Property::POSITION_Z:
3167         {
3168           value.Get( mTargetPosition.z );
3169           break;
3170         }
3171
3172         case Dali::Actor::Property::ORIENTATION:
3173         {
3174           value.Get( mTargetOrientation );
3175           break;
3176         }
3177
3178         case Dali::Actor::Property::SCALE:
3179         {
3180           value.Get( mTargetScale );
3181           break;
3182         }
3183
3184         case Dali::Actor::Property::SCALE_X:
3185         {
3186           value.Get( mTargetScale.x );
3187           break;
3188         }
3189
3190         case Dali::Actor::Property::SCALE_Y:
3191         {
3192           value.Get( mTargetScale.y );
3193           break;
3194         }
3195
3196         case Dali::Actor::Property::SCALE_Z:
3197         {
3198           value.Get( mTargetScale.z );
3199           break;
3200         }
3201
3202         case Dali::Actor::Property::VISIBLE:
3203         {
3204           SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3205           break;
3206         }
3207
3208         case Dali::Actor::Property::COLOR:
3209         {
3210           value.Get( mTargetColor );
3211           break;
3212         }
3213
3214         case Dali::Actor::Property::COLOR_RED:
3215         {
3216           value.Get( mTargetColor.r );
3217           break;
3218         }
3219
3220         case Dali::Actor::Property::COLOR_GREEN:
3221         {
3222           value.Get( mTargetColor.g );
3223           break;
3224         }
3225
3226         case Dali::Actor::Property::COLOR_BLUE:
3227         {
3228           value.Get( mTargetColor.b );
3229           break;
3230         }
3231
3232         case Dali::Actor::Property::COLOR_ALPHA:
3233         case Dali::DevelActor::Property::OPACITY:
3234         {
3235           value.Get( mTargetColor.a );
3236           break;
3237         }
3238
3239         default:
3240         {
3241           // Not an animatable property. Do nothing.
3242           break;
3243         }
3244       }
3245       break;
3246     }
3247
3248     case Animation::BY:
3249     {
3250       switch( index )
3251       {
3252         case Dali::Actor::Property::SIZE:
3253         {
3254           if( AdjustValue< Vector3 >( mTargetSize, value ) )
3255           {
3256             // Notify deriving classes
3257             OnSizeAnimation( animation, mTargetSize );
3258           }
3259           break;
3260         }
3261
3262         case Dali::Actor::Property::SIZE_WIDTH:
3263         {
3264           if( AdjustValue< float >( mTargetSize.width, value ) )
3265           {
3266             // Notify deriving classes
3267             OnSizeAnimation( animation, mTargetSize );
3268           }
3269           break;
3270         }
3271
3272         case Dali::Actor::Property::SIZE_HEIGHT:
3273         {
3274           if( AdjustValue< float >( mTargetSize.height, value ) )
3275           {
3276             // Notify deriving classes
3277             OnSizeAnimation( animation, mTargetSize );
3278           }
3279           break;
3280         }
3281
3282         case Dali::Actor::Property::SIZE_DEPTH:
3283         {
3284           if( AdjustValue< float >( mTargetSize.depth, value ) )
3285           {
3286             // Notify deriving classes
3287             OnSizeAnimation( animation, mTargetSize );
3288           }
3289           break;
3290         }
3291
3292         case Dali::Actor::Property::POSITION:
3293         {
3294           AdjustValue< Vector3 >( mTargetPosition, value );
3295           break;
3296         }
3297
3298         case Dali::Actor::Property::POSITION_X:
3299         {
3300           AdjustValue< float >( mTargetPosition.x, value );
3301           break;
3302         }
3303
3304         case Dali::Actor::Property::POSITION_Y:
3305         {
3306           AdjustValue< float >( mTargetPosition.y, value );
3307           break;
3308         }
3309
3310         case Dali::Actor::Property::POSITION_Z:
3311         {
3312           AdjustValue< float >( mTargetPosition.z, value );
3313           break;
3314         }
3315
3316         case Dali::Actor::Property::ORIENTATION:
3317         {
3318           Quaternion relativeValue;
3319           if( value.Get( relativeValue ) )
3320           {
3321             mTargetOrientation *= relativeValue;
3322           }
3323           break;
3324         }
3325
3326         case Dali::Actor::Property::SCALE:
3327         {
3328           AdjustValue< Vector3 >( mTargetScale, value );
3329           break;
3330         }
3331
3332         case Dali::Actor::Property::SCALE_X:
3333         {
3334           AdjustValue< float >( mTargetScale.x, value );
3335           break;
3336         }
3337
3338         case Dali::Actor::Property::SCALE_Y:
3339         {
3340           AdjustValue< float >( mTargetScale.y, value );
3341           break;
3342         }
3343
3344         case Dali::Actor::Property::SCALE_Z:
3345         {
3346           AdjustValue< float >( mTargetScale.z, value );
3347           break;
3348         }
3349
3350         case Dali::Actor::Property::VISIBLE:
3351         {
3352           bool relativeValue = false;
3353           if( value.Get( relativeValue ) )
3354           {
3355             bool visible = mVisible || relativeValue;
3356             SetVisibleInternal( visible, SendMessage::FALSE );
3357           }
3358           break;
3359         }
3360
3361         case Dali::Actor::Property::COLOR:
3362         {
3363           AdjustValue< Vector4 >( mTargetColor, value );
3364           break;
3365         }
3366
3367         case Dali::Actor::Property::COLOR_RED:
3368         {
3369           AdjustValue< float >( mTargetColor.r, value );
3370           break;
3371         }
3372
3373         case Dali::Actor::Property::COLOR_GREEN:
3374         {
3375           AdjustValue< float >( mTargetColor.g, value );
3376           break;
3377         }
3378
3379         case Dali::Actor::Property::COLOR_BLUE:
3380         {
3381           AdjustValue< float >( mTargetColor.b, value );
3382           break;
3383         }
3384
3385         case Dali::Actor::Property::COLOR_ALPHA:
3386         case Dali::DevelActor::Property::OPACITY:
3387         {
3388           AdjustValue< float >( mTargetColor.a, value );
3389           break;
3390         }
3391
3392         default:
3393         {
3394           // Not an animatable property. Do nothing.
3395           break;
3396         }
3397       }
3398       break;
3399     }
3400   }
3401 }
3402
3403 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3404 {
3405   return mNode;
3406 }
3407
3408 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3409 {
3410   // This method should only return an object connected to the scene-graph
3411   return OnStage() ? mNode : NULL;
3412 }
3413
3414 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3415 {
3416   DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3417
3418   const PropertyBase* property( NULL );
3419
3420   // This method should only return a property of an object connected to the scene-graph
3421   if( !OnStage() )
3422   {
3423     return property;
3424   }
3425
3426   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3427   {
3428     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3429     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3430
3431     property = animatable->GetSceneGraphProperty();
3432   }
3433   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3434             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3435   {
3436     CustomPropertyMetadata* custom = FindCustomProperty( index );
3437     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3438
3439     property = custom->GetSceneGraphProperty();
3440   }
3441   else if( NULL != mNode )
3442   {
3443     switch( index )
3444     {
3445       case Dali::Actor::Property::SIZE:
3446         property = &mNode->mSize;
3447         break;
3448
3449       case Dali::Actor::Property::SIZE_WIDTH:
3450         property = &mNode->mSize;
3451         break;
3452
3453       case Dali::Actor::Property::SIZE_HEIGHT:
3454         property = &mNode->mSize;
3455         break;
3456
3457       case Dali::Actor::Property::SIZE_DEPTH:
3458         property = &mNode->mSize;
3459         break;
3460
3461       case Dali::Actor::Property::POSITION:
3462         property = &mNode->mPosition;
3463         break;
3464
3465       case Dali::Actor::Property::POSITION_X:
3466         property = &mNode->mPosition;
3467         break;
3468
3469       case Dali::Actor::Property::POSITION_Y:
3470         property = &mNode->mPosition;
3471         break;
3472
3473       case Dali::Actor::Property::POSITION_Z:
3474         property = &mNode->mPosition;
3475         break;
3476
3477       case Dali::Actor::Property::ORIENTATION:
3478         property = &mNode->mOrientation;
3479         break;
3480
3481       case Dali::Actor::Property::SCALE:
3482         property = &mNode->mScale;
3483         break;
3484
3485       case Dali::Actor::Property::SCALE_X:
3486         property = &mNode->mScale;
3487         break;
3488
3489       case Dali::Actor::Property::SCALE_Y:
3490         property = &mNode->mScale;
3491         break;
3492
3493       case Dali::Actor::Property::SCALE_Z:
3494         property = &mNode->mScale;
3495         break;
3496
3497       case Dali::Actor::Property::VISIBLE:
3498         property = &mNode->mVisible;
3499         break;
3500
3501       case Dali::Actor::Property::COLOR:
3502         property = &mNode->mColor;
3503         break;
3504
3505       case Dali::Actor::Property::COLOR_RED:
3506         property = &mNode->mColor;
3507         break;
3508
3509       case Dali::Actor::Property::COLOR_GREEN:
3510         property = &mNode->mColor;
3511         break;
3512
3513       case Dali::Actor::Property::COLOR_BLUE:
3514         property = &mNode->mColor;
3515         break;
3516
3517       case Dali::Actor::Property::COLOR_ALPHA:
3518       case Dali::DevelActor::Property::OPACITY:
3519         property = &mNode->mColor;
3520         break;
3521
3522       default:
3523         break;
3524     }
3525   }
3526
3527   return property;
3528 }
3529
3530 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3531 {
3532   const PropertyInputImpl* property( NULL );
3533
3534   // This method should only return a property of an object connected to the scene-graph
3535   if( !OnStage() )
3536   {
3537     return property;
3538   }
3539
3540   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3541   {
3542     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3543     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3544
3545     property = animatable->GetSceneGraphProperty();
3546   }
3547   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3548             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3549   {
3550     CustomPropertyMetadata* custom = FindCustomProperty( index );
3551     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3552     property = custom->GetSceneGraphProperty();
3553   }
3554   else if( NULL != mNode )
3555   {
3556     switch( index )
3557     {
3558       case Dali::Actor::Property::PARENT_ORIGIN:
3559         property = &mNode->mParentOrigin;
3560         break;
3561
3562       case Dali::Actor::Property::PARENT_ORIGIN_X:
3563         property = &mNode->mParentOrigin;
3564         break;
3565
3566       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3567         property = &mNode->mParentOrigin;
3568         break;
3569
3570       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3571         property = &mNode->mParentOrigin;
3572         break;
3573
3574       case Dali::Actor::Property::ANCHOR_POINT:
3575         property = &mNode->mAnchorPoint;
3576         break;
3577
3578       case Dali::Actor::Property::ANCHOR_POINT_X:
3579         property = &mNode->mAnchorPoint;
3580         break;
3581
3582       case Dali::Actor::Property::ANCHOR_POINT_Y:
3583         property = &mNode->mAnchorPoint;
3584         break;
3585
3586       case Dali::Actor::Property::ANCHOR_POINT_Z:
3587         property = &mNode->mAnchorPoint;
3588         break;
3589
3590       case Dali::Actor::Property::SIZE:
3591         property = &mNode->mSize;
3592         break;
3593
3594       case Dali::Actor::Property::SIZE_WIDTH:
3595         property = &mNode->mSize;
3596         break;
3597
3598       case Dali::Actor::Property::SIZE_HEIGHT:
3599         property = &mNode->mSize;
3600         break;
3601
3602       case Dali::Actor::Property::SIZE_DEPTH:
3603         property = &mNode->mSize;
3604         break;
3605
3606       case Dali::Actor::Property::POSITION:
3607         property = &mNode->mPosition;
3608         break;
3609
3610       case Dali::Actor::Property::POSITION_X:
3611         property = &mNode->mPosition;
3612         break;
3613
3614       case Dali::Actor::Property::POSITION_Y:
3615         property = &mNode->mPosition;
3616         break;
3617
3618       case Dali::Actor::Property::POSITION_Z:
3619         property = &mNode->mPosition;
3620         break;
3621
3622       case Dali::Actor::Property::WORLD_POSITION:
3623         property = &mNode->mWorldPosition;
3624         break;
3625
3626       case Dali::Actor::Property::WORLD_POSITION_X:
3627         property = &mNode->mWorldPosition;
3628         break;
3629
3630       case Dali::Actor::Property::WORLD_POSITION_Y:
3631         property = &mNode->mWorldPosition;
3632         break;
3633
3634       case Dali::Actor::Property::WORLD_POSITION_Z:
3635         property = &mNode->mWorldPosition;
3636         break;
3637
3638       case Dali::Actor::Property::ORIENTATION:
3639         property = &mNode->mOrientation;
3640         break;
3641
3642       case Dali::Actor::Property::WORLD_ORIENTATION:
3643         property = &mNode->mWorldOrientation;
3644         break;
3645
3646       case Dali::Actor::Property::SCALE:
3647         property = &mNode->mScale;
3648         break;
3649
3650       case Dali::Actor::Property::SCALE_X:
3651         property = &mNode->mScale;
3652         break;
3653
3654       case Dali::Actor::Property::SCALE_Y:
3655         property = &mNode->mScale;
3656         break;
3657
3658       case Dali::Actor::Property::SCALE_Z:
3659         property = &mNode->mScale;
3660         break;
3661
3662       case Dali::Actor::Property::WORLD_SCALE:
3663         property = &mNode->mWorldScale;
3664         break;
3665
3666       case Dali::Actor::Property::VISIBLE:
3667         property = &mNode->mVisible;
3668         break;
3669
3670       case Dali::Actor::Property::COLOR:
3671         property = &mNode->mColor;
3672         break;
3673
3674       case Dali::Actor::Property::COLOR_RED:
3675         property = &mNode->mColor;
3676         break;
3677
3678       case Dali::Actor::Property::COLOR_GREEN:
3679         property = &mNode->mColor;
3680         break;
3681
3682       case Dali::Actor::Property::COLOR_BLUE:
3683         property = &mNode->mColor;
3684         break;
3685
3686       case Dali::Actor::Property::COLOR_ALPHA:
3687       case Dali::DevelActor::Property::OPACITY:
3688       {
3689         property = &mNode->mColor;
3690         break;
3691       }
3692
3693       case Dali::Actor::Property::WORLD_COLOR:
3694         property = &mNode->mWorldColor;
3695         break;
3696
3697       case Dali::Actor::Property::WORLD_MATRIX:
3698         property = &mNode->mWorldMatrix;
3699         break;
3700
3701       default:
3702         break;
3703     }
3704   }
3705
3706   return property;
3707 }
3708
3709 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3710 {
3711   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3712
3713   if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3714   {
3715     // check whether the animatable property is registered already, if not then register one.
3716     AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3717     if( animatableProperty )
3718     {
3719       componentIndex = animatableProperty->componentIndex;
3720     }
3721   }
3722   else
3723   {
3724     switch( index )
3725     {
3726       case Dali::Actor::Property::PARENT_ORIGIN_X:
3727       case Dali::Actor::Property::ANCHOR_POINT_X:
3728       case Dali::Actor::Property::SIZE_WIDTH:
3729       case Dali::Actor::Property::POSITION_X:
3730       case Dali::Actor::Property::WORLD_POSITION_X:
3731       case Dali::Actor::Property::SCALE_X:
3732       case Dali::Actor::Property::COLOR_RED:
3733       {
3734         componentIndex = 0;
3735         break;
3736       }
3737
3738       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3739       case Dali::Actor::Property::ANCHOR_POINT_Y:
3740       case Dali::Actor::Property::SIZE_HEIGHT:
3741       case Dali::Actor::Property::POSITION_Y:
3742       case Dali::Actor::Property::WORLD_POSITION_Y:
3743       case Dali::Actor::Property::SCALE_Y:
3744       case Dali::Actor::Property::COLOR_GREEN:
3745       {
3746         componentIndex = 1;
3747         break;
3748       }
3749
3750       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3751       case Dali::Actor::Property::ANCHOR_POINT_Z:
3752       case Dali::Actor::Property::SIZE_DEPTH:
3753       case Dali::Actor::Property::POSITION_Z:
3754       case Dali::Actor::Property::WORLD_POSITION_Z:
3755       case Dali::Actor::Property::SCALE_Z:
3756       case Dali::Actor::Property::COLOR_BLUE:
3757       {
3758         componentIndex = 2;
3759         break;
3760       }
3761
3762       case Dali::Actor::Property::COLOR_ALPHA:
3763       case Dali::DevelActor::Property::OPACITY:
3764       {
3765         componentIndex = 3;
3766         break;
3767       }
3768
3769       default:
3770       {
3771         // Do nothing
3772         break;
3773       }
3774     }
3775   }
3776
3777   return componentIndex;
3778 }
3779
3780 void Actor::SetParent( Actor* parent )
3781 {
3782   if( parent )
3783   {
3784     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3785
3786     mParent = parent;
3787
3788     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3789          parent->OnStage() )
3790     {
3791       // Instruct each actor to create a corresponding node in the scene graph
3792       ConnectToStage( parent->GetHierarchyDepth() );
3793     }
3794
3795     // Resolve the name and index for the child properties if any
3796     ResolveChildProperties();
3797   }
3798   else // parent being set to NULL
3799   {
3800     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3801
3802     mParent = NULL;
3803
3804     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3805          OnStage() )
3806     {
3807       DALI_ASSERT_ALWAYS( mNode != NULL );
3808
3809       if( NULL != mNode )
3810       {
3811         // Disconnect the Node & its children from the scene-graph.
3812         DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3813       }
3814
3815       // Instruct each actor to discard pointers to the scene-graph
3816       DisconnectFromStage();
3817     }
3818   }
3819 }
3820
3821 SceneGraph::Node* Actor::CreateNode() const
3822 {
3823   return Node::New();
3824 }
3825
3826 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3827 {
3828   bool done = false;
3829   Actor* actor = dynamic_cast< Actor* >( object );
3830
3831   if( actor )
3832   {
3833     if( 0 == actionName.compare( ACTION_SHOW ) )
3834     {
3835       actor->SetVisible( true );
3836       done = true;
3837     }
3838     else if( 0 == actionName.compare( ACTION_HIDE ) )
3839     {
3840       actor->SetVisible( false );
3841       done = true;
3842     }
3843   }
3844
3845   return done;
3846 }
3847
3848 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3849 {
3850   bool valueSet = true;
3851
3852   switch( index )
3853   {
3854     case Dali::Actor::Property::PARENT_ORIGIN:
3855     {
3856       value = GetCurrentParentOrigin();
3857       break;
3858     }
3859
3860     case Dali::Actor::Property::PARENT_ORIGIN_X:
3861     {
3862       value = GetCurrentParentOrigin().x;
3863       break;
3864     }
3865
3866     case Dali::Actor::Property::PARENT_ORIGIN_Y:
3867     {
3868       value = GetCurrentParentOrigin().y;
3869       break;
3870     }
3871
3872     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3873     {
3874       value = GetCurrentParentOrigin().z;
3875       break;
3876     }
3877
3878     case Dali::Actor::Property::ANCHOR_POINT:
3879     {
3880       value = GetCurrentAnchorPoint();
3881       break;
3882     }
3883
3884     case Dali::Actor::Property::ANCHOR_POINT_X:
3885     {
3886       value = GetCurrentAnchorPoint().x;
3887       break;
3888     }
3889
3890     case Dali::Actor::Property::ANCHOR_POINT_Y:
3891     {
3892       value = GetCurrentAnchorPoint().y;
3893       break;
3894     }
3895
3896     case Dali::Actor::Property::ANCHOR_POINT_Z:
3897     {
3898       value = GetCurrentAnchorPoint().z;
3899       break;
3900     }
3901
3902     case Dali::Actor::Property::SIZE:
3903     {
3904       value = GetTargetSize();
3905       break;
3906     }
3907
3908     case Dali::Actor::Property::SIZE_WIDTH:
3909     {
3910       value = GetTargetSize().width;
3911       break;
3912     }
3913
3914     case Dali::Actor::Property::SIZE_HEIGHT:
3915     {
3916       value = GetTargetSize().height;
3917       break;
3918     }
3919
3920     case Dali::Actor::Property::SIZE_DEPTH:
3921     {
3922       value = GetTargetSize().depth;
3923       break;
3924     }
3925
3926     case Dali::Actor::Property::POSITION:
3927     {
3928       value = GetTargetPosition();
3929       break;
3930     }
3931
3932     case Dali::Actor::Property::POSITION_X:
3933     {
3934       value = GetTargetPosition().x;
3935       break;
3936     }
3937
3938     case Dali::Actor::Property::POSITION_Y:
3939     {
3940       value = GetTargetPosition().y;
3941       break;
3942     }
3943
3944     case Dali::Actor::Property::POSITION_Z:
3945     {
3946       value = GetTargetPosition().z;
3947       break;
3948     }
3949
3950     case Dali::Actor::Property::ORIENTATION:
3951     {
3952       value = mTargetOrientation;
3953       break;
3954     }
3955
3956     case Dali::Actor::Property::SCALE:
3957     {
3958       value = mTargetScale;
3959       break;
3960     }
3961
3962     case Dali::Actor::Property::SCALE_X:
3963     {
3964       value = mTargetScale.x;
3965       break;
3966     }
3967
3968     case Dali::Actor::Property::SCALE_Y:
3969     {
3970       value = mTargetScale.y;
3971       break;
3972     }
3973
3974     case Dali::Actor::Property::SCALE_Z:
3975     {
3976       value = mTargetScale.z;
3977       break;
3978     }
3979
3980     case Dali::Actor::Property::VISIBLE:
3981     {
3982       value = mVisible;
3983       break;
3984     }
3985
3986     case Dali::Actor::Property::COLOR:
3987     {
3988       value = mTargetColor;
3989       break;
3990     }
3991
3992     case Dali::Actor::Property::COLOR_RED:
3993     {
3994       value = mTargetColor.r;
3995       break;
3996     }
3997
3998     case Dali::Actor::Property::COLOR_GREEN:
3999     {
4000       value = mTargetColor.g;
4001       break;
4002     }
4003
4004     case Dali::Actor::Property::COLOR_BLUE:
4005     {
4006       value = mTargetColor.b;
4007       break;
4008     }
4009
4010     case Dali::Actor::Property::COLOR_ALPHA:
4011     case Dali::DevelActor::Property::OPACITY:
4012     {
4013       value = mTargetColor.a;
4014       break;
4015     }
4016
4017     case Dali::Actor::Property::NAME:
4018     {
4019       value = GetName();
4020       break;
4021     }
4022
4023     case Dali::Actor::Property::SENSITIVE:
4024     {
4025       value = IsSensitive();
4026       break;
4027     }
4028
4029     case Dali::Actor::Property::LEAVE_REQUIRED:
4030     {
4031       value = GetLeaveRequired();
4032       break;
4033     }
4034
4035     case Dali::Actor::Property::INHERIT_POSITION:
4036     {
4037       value = IsPositionInherited();
4038       break;
4039     }
4040
4041     case Dali::Actor::Property::INHERIT_ORIENTATION:
4042     {
4043       value = IsOrientationInherited();
4044       break;
4045     }
4046
4047     case Dali::Actor::Property::INHERIT_SCALE:
4048     {
4049       value = IsScaleInherited();
4050       break;
4051     }
4052
4053     case Dali::Actor::Property::COLOR_MODE:
4054     {
4055       value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4056       break;
4057     }
4058
4059     case Dali::Actor::Property::POSITION_INHERITANCE:
4060     {
4061       value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4062       break;
4063     }
4064
4065     case Dali::Actor::Property::DRAW_MODE:
4066     {
4067       value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4068       break;
4069     }
4070
4071     case Dali::Actor::Property::SIZE_MODE_FACTOR:
4072     {
4073       value = GetSizeModeFactor();
4074       break;
4075     }
4076
4077     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4078     {
4079       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4080       break;
4081     }
4082
4083     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4084     {
4085       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4086       break;
4087     }
4088
4089     case Dali::Actor::Property::SIZE_SCALE_POLICY:
4090     {
4091       value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4092       break;
4093     }
4094
4095     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4096     {
4097       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4098       break;
4099     }
4100
4101     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4102     {
4103       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4104       break;
4105     }
4106
4107     case Dali::Actor::Property::PADDING:
4108     {
4109       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4110       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4111       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4112       break;
4113     }
4114
4115     case Dali::Actor::Property::MINIMUM_SIZE:
4116     {
4117       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4118       break;
4119     }
4120
4121     case Dali::Actor::Property::MAXIMUM_SIZE:
4122     {
4123       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4124       break;
4125     }
4126
4127     case Dali::Actor::Property::CLIPPING_MODE:
4128     {
4129       value = mClippingMode;
4130       break;
4131     }
4132
4133     case Dali::DevelActor::Property::SIBLING_ORDER:
4134     {
4135       value = static_cast<int>( GetSiblingOrder() );
4136       break;
4137     }
4138
4139     case Dali::DevelActor::Property::SCREEN_POSITION:
4140     {
4141       value = GetCurrentScreenPosition();
4142       break;
4143     }
4144
4145     case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4146     {
4147       value = mPositionUsesAnchorPoint;
4148       break;
4149     }
4150
4151     case Dali::DevelActor::Property::LAYOUT_DIRECTION:
4152     {
4153       value = mLayoutDirection;
4154       break;
4155     }
4156
4157     case Dali::DevelActor::Property::INHERIT_LAYOUT_DIRECTION:
4158     {
4159       value = IsLayoutDirectionInherited();
4160       break;
4161     }
4162
4163     default:
4164     {
4165       // Must be a scene-graph only property
4166       valueSet = false;
4167       break;
4168     }
4169   }
4170
4171   return valueSet;
4172 }
4173
4174 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value  ) const
4175 {
4176   bool valueSet = true;
4177
4178   switch( index )
4179   {
4180     case Dali::Actor::Property::SIZE:
4181     {
4182       value = GetCurrentSize();
4183       break;
4184     }
4185
4186     case Dali::Actor::Property::SIZE_WIDTH:
4187     {
4188       value = GetCurrentSize().width;
4189       break;
4190     }
4191
4192     case Dali::Actor::Property::SIZE_HEIGHT:
4193     {
4194       value = GetCurrentSize().height;
4195       break;
4196     }
4197
4198     case Dali::Actor::Property::SIZE_DEPTH:
4199     {
4200       value = GetCurrentSize().depth;
4201       break;
4202     }
4203
4204     case Dali::Actor::Property::POSITION:
4205     {
4206       value = GetCurrentPosition();
4207       break;
4208     }
4209
4210     case Dali::Actor::Property::POSITION_X:
4211     {
4212       value = GetCurrentPosition().x;
4213       break;
4214     }
4215
4216     case Dali::Actor::Property::POSITION_Y:
4217     {
4218       value = GetCurrentPosition().y;
4219       break;
4220     }
4221
4222     case Dali::Actor::Property::POSITION_Z:
4223     {
4224       value = GetCurrentPosition().z;
4225       break;
4226     }
4227
4228     case Dali::Actor::Property::WORLD_POSITION:
4229     {
4230       value = GetCurrentWorldPosition();
4231       break;
4232     }
4233
4234     case Dali::Actor::Property::WORLD_POSITION_X:
4235     {
4236       value = GetCurrentWorldPosition().x;
4237       break;
4238     }
4239
4240     case Dali::Actor::Property::WORLD_POSITION_Y:
4241     {
4242       value = GetCurrentWorldPosition().y;
4243       break;
4244     }
4245
4246     case Dali::Actor::Property::WORLD_POSITION_Z:
4247     {
4248       value = GetCurrentWorldPosition().z;
4249       break;
4250     }
4251
4252     case Dali::Actor::Property::ORIENTATION:
4253     {
4254       value = GetCurrentOrientation();
4255       break;
4256     }
4257
4258     case Dali::Actor::Property::WORLD_ORIENTATION:
4259     {
4260       value = GetCurrentWorldOrientation();
4261       break;
4262     }
4263
4264     case Dali::Actor::Property::SCALE:
4265     {
4266       value = GetCurrentScale();
4267       break;
4268     }
4269
4270     case Dali::Actor::Property::SCALE_X:
4271     {
4272       value = GetCurrentScale().x;
4273       break;
4274     }
4275
4276     case Dali::Actor::Property::SCALE_Y:
4277     {
4278       value = GetCurrentScale().y;
4279       break;
4280     }
4281
4282     case Dali::Actor::Property::SCALE_Z:
4283     {
4284       value = GetCurrentScale().z;
4285       break;
4286     }
4287
4288     case Dali::Actor::Property::WORLD_SCALE:
4289     {
4290       value = GetCurrentWorldScale();
4291       break;
4292     }
4293
4294     case Dali::Actor::Property::COLOR:
4295     {
4296       value = GetCurrentColor();
4297       break;
4298     }
4299
4300     case Dali::Actor::Property::COLOR_RED:
4301     {
4302       value = GetCurrentColor().r;
4303       break;
4304     }
4305
4306     case Dali::Actor::Property::COLOR_GREEN:
4307     {
4308       value = GetCurrentColor().g;
4309       break;
4310     }
4311
4312     case Dali::Actor::Property::COLOR_BLUE:
4313     {
4314       value = GetCurrentColor().b;
4315       break;
4316     }
4317
4318     case Dali::Actor::Property::COLOR_ALPHA:
4319     case Dali::DevelActor::Property::OPACITY:
4320     {
4321       value = GetCurrentColor().a;
4322       break;
4323     }
4324
4325     case Dali::Actor::Property::WORLD_COLOR:
4326     {
4327       value = GetCurrentWorldColor();
4328       break;
4329     }
4330
4331     case Dali::Actor::Property::WORLD_MATRIX:
4332     {
4333       value = GetCurrentWorldMatrix();
4334       break;
4335     }
4336
4337     case Dali::Actor::Property::VISIBLE:
4338     {
4339       value = IsVisible();
4340       break;
4341     }
4342
4343     default:
4344     {
4345       // Must be an event-side only property
4346       valueSet = false;
4347       break;
4348     }
4349   }
4350
4351   return valueSet;
4352 }
4353
4354 void Actor::EnsureRelayoutData()
4355 {
4356   // Assign relayout data.
4357   if( !mRelayoutData )
4358   {
4359     mRelayoutData = new RelayoutData();
4360   }
4361 }
4362
4363 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4364 {
4365   // Check if actor is dependent on parent
4366   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4367   {
4368     if( ( dimension & ( 1 << i ) ) )
4369     {
4370       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4371       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4372       {
4373         return true;
4374       }
4375     }
4376   }
4377
4378   return false;
4379 }
4380
4381 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4382 {
4383   // Check if actor is dependent on children
4384   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4385   {
4386     if( ( dimension & ( 1 << i ) ) )
4387     {
4388       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4389       switch( resizePolicy )
4390       {
4391         case ResizePolicy::FIT_TO_CHILDREN:
4392         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
4393         {
4394           return true;
4395         }
4396
4397         default:
4398         {
4399           break;
4400         }
4401       }
4402     }
4403   }
4404
4405   return false;
4406 }
4407
4408 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4409 {
4410   return Actor::RelayoutDependentOnChildren( dimension );
4411 }
4412
4413 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4414 {
4415   // Check each possible dimension and see if it is dependent on the input one
4416   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4417   {
4418     if( dimension & ( 1 << i ) )
4419     {
4420       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4421     }
4422   }
4423
4424   return false;
4425 }
4426
4427 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4428 {
4429   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4430   {
4431     if( dimension & ( 1 << i ) )
4432     {
4433       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4434     }
4435   }
4436 }
4437
4438 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4439 {
4440   // If more than one dimension is requested, just return the first one found
4441   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4442   {
4443     if( ( dimension & ( 1 << i ) ) )
4444     {
4445       return mRelayoutData->negotiatedDimensions[ i ];
4446     }
4447   }
4448
4449   return 0.0f;   // Default
4450 }
4451
4452 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4453 {
4454   EnsureRelayoutData();
4455
4456   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4457   {
4458     if( dimension & ( 1 << i ) )
4459     {
4460       mRelayoutData->dimensionPadding[ i ] = padding;
4461     }
4462   }
4463 }
4464
4465 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4466 {
4467   if ( mRelayoutData )
4468   {
4469     // If more than one dimension is requested, just return the first one found
4470     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4471     {
4472       if( ( dimension & ( 1 << i ) ) )
4473       {
4474         return mRelayoutData->dimensionPadding[ i ];
4475       }
4476     }
4477   }
4478
4479   return GetDefaultDimensionPadding();
4480 }
4481
4482 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4483 {
4484   EnsureRelayoutData();
4485
4486   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4487   {
4488     if( dimension & ( 1 << i ) )
4489     {
4490       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4491     }
4492   }
4493 }
4494
4495 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4496 {
4497   if ( mRelayoutData )
4498   {
4499     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4500     {
4501       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4502       {
4503         return true;
4504       }
4505     }
4506   }
4507
4508   return false;
4509 }
4510
4511 float Actor::GetHeightForWidthBase( float width )
4512 {
4513   float height = 0.0f;
4514
4515   const Vector3 naturalSize = GetNaturalSize();
4516   if( naturalSize.width > 0.0f )
4517   {
4518     height = naturalSize.height * width / naturalSize.width;
4519   }
4520   else // we treat 0 as 1:1 aspect ratio
4521   {
4522     height = width;
4523   }
4524
4525   return height;
4526 }
4527
4528 float Actor::GetWidthForHeightBase( float height )
4529 {
4530   float width = 0.0f;
4531
4532   const Vector3 naturalSize = GetNaturalSize();
4533   if( naturalSize.height > 0.0f )
4534   {
4535     width = naturalSize.width * height / naturalSize.height;
4536   }
4537   else // we treat 0 as 1:1 aspect ratio
4538   {
4539     width = height;
4540   }
4541
4542   return width;
4543 }
4544
4545 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4546 {
4547   // Fill to parent, taking size mode factor into account
4548   switch( child.GetResizePolicy( dimension ) )
4549   {
4550     case ResizePolicy::FILL_TO_PARENT:
4551     {
4552       return GetLatestSize( dimension );
4553     }
4554
4555     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4556     {
4557       return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4558     }
4559
4560     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4561     {
4562       return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4563     }
4564
4565     default:
4566     {
4567       return GetLatestSize( dimension );
4568     }
4569   }
4570 }
4571
4572 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4573 {
4574   // Can be overridden in derived class
4575   return CalculateChildSizeBase( child, dimension );
4576 }
4577
4578 float Actor::GetHeightForWidth( float width )
4579 {
4580   // Can be overridden in derived class
4581   return GetHeightForWidthBase( width );
4582 }
4583
4584 float Actor::GetWidthForHeight( float height )
4585 {
4586   // Can be overridden in derived class
4587   return GetWidthForHeightBase( height );
4588 }
4589
4590 float Actor::GetLatestSize( Dimension::Type dimension ) const
4591 {
4592   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4593 }
4594
4595 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4596 {
4597   Vector2 padding = GetPadding( dimension );
4598
4599   return GetLatestSize( dimension ) + padding.x + padding.y;
4600 }
4601
4602 float Actor::NegotiateFromParent( Dimension::Type dimension )
4603 {
4604   Actor* parent = GetParent();
4605   if( parent )
4606   {
4607     Vector2 padding( GetPadding( dimension ) );
4608     Vector2 parentPadding( parent->GetPadding( dimension ) );
4609     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4610   }
4611
4612   return 0.0f;
4613 }
4614
4615 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4616 {
4617   float maxDimensionPoint = 0.0f;
4618
4619   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4620   {
4621     ActorPtr child = GetChildAt( i );
4622
4623     if( !child->RelayoutDependentOnParent( dimension ) )
4624     {
4625       // Calculate the min and max points that the children range across
4626       float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4627       float dimensionSize = child->GetRelayoutSize( dimension );
4628       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4629     }
4630   }
4631
4632   return maxDimensionPoint;
4633 }
4634
4635 float Actor::GetSize( Dimension::Type dimension ) const
4636 {
4637   return GetDimensionValue( mTargetSize, dimension );
4638 }
4639
4640 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4641 {
4642   return GetDimensionValue( GetNaturalSize(), dimension );
4643 }
4644
4645 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4646 {
4647   switch( GetResizePolicy( dimension ) )
4648   {
4649     case ResizePolicy::USE_NATURAL_SIZE:
4650     {
4651       return GetNaturalSize( dimension );
4652     }
4653
4654     case ResizePolicy::FIXED:
4655     {
4656       return GetDimensionValue( GetPreferredSize(), dimension );
4657     }
4658
4659     case ResizePolicy::USE_ASSIGNED_SIZE:
4660     {
4661       return GetDimensionValue( maximumSize, dimension );
4662     }
4663
4664     case ResizePolicy::FILL_TO_PARENT:
4665     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4666     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4667     {
4668       return NegotiateFromParent( dimension );
4669     }
4670
4671     case ResizePolicy::FIT_TO_CHILDREN:
4672     {
4673       return NegotiateFromChildren( dimension );
4674     }
4675
4676     case ResizePolicy::DIMENSION_DEPENDENCY:
4677     {
4678       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4679
4680       // Custom rules
4681       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4682       {
4683         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4684       }
4685
4686       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4687       {
4688         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4689       }
4690
4691       break;
4692     }
4693
4694     default:
4695     {
4696       break;
4697     }
4698   }
4699
4700   return 0.0f;  // Default
4701 }
4702
4703 float Actor::ClampDimension( float size, Dimension::Type dimension )
4704 {
4705   const float minSize = GetMinimumSize( dimension );
4706   const float maxSize = GetMaximumSize( dimension );
4707
4708   return std::max( minSize, std::min( size, maxSize ) );
4709 }
4710
4711 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4712 {
4713   // Check if it needs to be negotiated
4714   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4715   {
4716     // Check that we havn't gotten into an infinite loop
4717     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4718     bool recursionFound = false;
4719     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4720     {
4721       if( *it == searchActor )
4722       {
4723         recursionFound = true;
4724         break;
4725       }
4726     }
4727
4728     if( !recursionFound )
4729     {
4730       // Record the path that we have taken
4731       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4732
4733       // Dimension dependency check
4734       for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4735       {
4736         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4737
4738         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4739         {
4740           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4741         }
4742       }
4743
4744       // Parent dependency check
4745       Actor* parent = GetParent();
4746       if( parent && RelayoutDependentOnParent( dimension ) )
4747       {
4748         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4749       }
4750
4751       // Children dependency check
4752       if( RelayoutDependentOnChildren( dimension ) )
4753       {
4754         for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4755         {
4756           ActorPtr child = GetChildAt( i );
4757
4758           // Only relayout child first if it is not dependent on this actor
4759           if( !child->RelayoutDependentOnParent( dimension ) )
4760           {
4761             child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4762           }
4763         }
4764       }
4765
4766       // For deriving classes
4767       OnCalculateRelayoutSize( dimension );
4768
4769       // All dependencies checked, calculate the size and set negotiated flag
4770       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4771
4772       SetNegotiatedDimension( newSize, dimension );
4773       SetLayoutNegotiated( true, dimension );
4774
4775       // For deriving classes
4776       OnLayoutNegotiated( newSize, dimension );
4777
4778       // This actor has been successfully processed, pop it off the recursion stack
4779       recursionStack.pop_back();
4780     }
4781     else
4782     {
4783       // TODO: Break infinite loop
4784       SetLayoutNegotiated( true, dimension );
4785     }
4786   }
4787 }
4788
4789 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4790 {
4791   // Negotiate all dimensions that require it
4792   ActorDimensionStack recursionStack;
4793
4794   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4795   {
4796     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4797
4798     // Negotiate
4799     NegotiateDimension( dimension, allocatedSize, recursionStack );
4800   }
4801 }
4802
4803 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4804 {
4805   switch( mRelayoutData->sizeSetPolicy )
4806   {
4807     case SizeScalePolicy::USE_SIZE_SET:
4808     {
4809       return size;
4810     }
4811
4812     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4813     {
4814       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4815       const Vector3 naturalSize = GetNaturalSize();
4816       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4817       {
4818         const float sizeRatio = size.width / size.height;
4819         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4820
4821         if( naturalSizeRatio < sizeRatio )
4822         {
4823           return Vector2( naturalSizeRatio * size.height, size.height );
4824         }
4825         else if( naturalSizeRatio > sizeRatio )
4826         {
4827           return Vector2( size.width, size.width / naturalSizeRatio );
4828         }
4829         else
4830         {
4831           return size;
4832         }
4833       }
4834
4835       break;
4836     }
4837
4838     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4839     {
4840       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4841       const Vector3 naturalSize = GetNaturalSize();
4842       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4843       {
4844         const float sizeRatio = size.width / size.height;
4845         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4846
4847         if( naturalSizeRatio < sizeRatio )
4848         {
4849           return Vector2( size.width, size.width / naturalSizeRatio );
4850         }
4851         else if( naturalSizeRatio > sizeRatio )
4852         {
4853           return Vector2( naturalSizeRatio * size.height, size.height );
4854         }
4855         else
4856         {
4857           return size;
4858         }
4859       }
4860       break;
4861     }
4862
4863     default:
4864     {
4865       break;
4866     }
4867   }
4868
4869   return size;
4870 }
4871
4872 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4873 {
4874   // Do the set actor size
4875   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4876
4877   // Adjust for size set policy
4878   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4879
4880   // Lock the flag to stop recursive relayouts on set size
4881   mRelayoutData->insideRelayout = true;
4882   SetSize( negotiatedSize );
4883   mRelayoutData->insideRelayout = false;
4884
4885   // Clear flags for all dimensions
4886   SetLayoutDirty( false );
4887
4888   // Give deriving classes a chance to respond
4889   OnRelayout( negotiatedSize, container );
4890
4891   if( !mOnRelayoutSignal.Empty() )
4892   {
4893     Dali::Actor handle( this );
4894     mOnRelayoutSignal.Emit( handle );
4895   }
4896 }
4897
4898 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4899 {
4900   // Force a size negotiation for actors that has assigned size during relayout
4901   // This is required as otherwise the flags that force a relayout will not
4902   // necessarilly be set. This will occur if the actor has already been laid out.
4903   // The dirty flags are then cleared. Then if the actor is added back into the
4904   // relayout container afterwards, the dirty flags would still be clear...
4905   // causing a relayout to be skipped. Here we force any actors added to the
4906   // container to be relayed out.
4907   DALI_LOG_TIMER_START( NegSizeTimer1 );
4908
4909   if( GetUseAssignedSize(Dimension::WIDTH ) )
4910   {
4911     SetLayoutNegotiated( false, Dimension::WIDTH );
4912   }
4913   if( GetUseAssignedSize( Dimension::HEIGHT ) )
4914   {
4915     SetLayoutNegotiated( false, Dimension::HEIGHT );
4916   }
4917
4918   // Do the negotiation
4919   NegotiateDimensions( allocatedSize );
4920
4921   // Set the actor size
4922   SetNegotiatedSize( container );
4923
4924   // Negotiate down to children
4925   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4926   {
4927     ActorPtr child = GetChildAt( i );
4928
4929     // Forces children that have already been laid out to be relayed out
4930     // if they have assigned size during relayout.
4931     if( child->GetUseAssignedSize(Dimension::WIDTH) )
4932     {
4933       child->SetLayoutNegotiated(false, Dimension::WIDTH);
4934       child->SetLayoutDirty(true, Dimension::WIDTH);
4935     }
4936
4937     if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4938     {
4939       child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4940       child->SetLayoutDirty(true, Dimension::HEIGHT);
4941     }
4942
4943     // Only relayout if required
4944     if( child->RelayoutRequired() )
4945     {
4946       container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4947     }
4948   }
4949   DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4950 }
4951
4952 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4953 {
4954   if( mRelayoutData )
4955   {
4956     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4957     {
4958       if( dimension & ( 1 << i ) )
4959       {
4960         mRelayoutData->useAssignedSize[ i ] = use;
4961       }
4962     }
4963   }
4964 }
4965
4966 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4967 {
4968   if ( mRelayoutData )
4969   {
4970     // If more than one dimension is requested, just return the first one found
4971     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4972     {
4973       if( dimension & ( 1 << i ) )
4974       {
4975         return mRelayoutData->useAssignedSize[ i ];
4976       }
4977     }
4978   }
4979
4980   return false;
4981 }
4982
4983 void Actor::RelayoutRequest( Dimension::Type dimension )
4984 {
4985   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4986   if( relayoutController )
4987   {
4988     Dali::Actor self( this );
4989     relayoutController->RequestRelayout( self, dimension );
4990   }
4991 }
4992
4993 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4994 {
4995 }
4996
4997 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4998 {
4999 }
5000
5001 void Actor::SetPreferredSize( const Vector2& size )
5002 {
5003   EnsureRelayoutData();
5004
5005   if( size.width > 0.0f )
5006   {
5007     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
5008   }
5009
5010   if( size.height > 0.0f )
5011   {
5012     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
5013   }
5014
5015   mRelayoutData->preferredSize = size;
5016
5017   RelayoutRequest();
5018 }
5019
5020 Vector2 Actor::GetPreferredSize() const
5021 {
5022   if ( mRelayoutData )
5023   {
5024     return Vector2( mRelayoutData->preferredSize );
5025   }
5026
5027   return GetDefaultPreferredSize();
5028 }
5029
5030 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
5031 {
5032   EnsureRelayoutData();
5033
5034   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5035   {
5036     if( dimension & ( 1 << i ) )
5037     {
5038       mRelayoutData->minimumSize[ i ] = size;
5039     }
5040   }
5041
5042   RelayoutRequest();
5043 }
5044
5045 float Actor::GetMinimumSize( Dimension::Type dimension ) const
5046 {
5047   if ( mRelayoutData )
5048   {
5049     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5050     {
5051       if( dimension & ( 1 << i ) )
5052       {
5053         return mRelayoutData->minimumSize[ i ];
5054       }
5055     }
5056   }
5057
5058   return 0.0f;  // Default
5059 }
5060
5061 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5062 {
5063   EnsureRelayoutData();
5064
5065   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5066   {
5067     if( dimension & ( 1 << i ) )
5068     {
5069       mRelayoutData->maximumSize[ i ] = size;
5070     }
5071   }
5072
5073   RelayoutRequest();
5074 }
5075
5076 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5077 {
5078   if ( mRelayoutData )
5079   {
5080     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5081     {
5082       if( dimension & ( 1 << i ) )
5083       {
5084         return mRelayoutData->maximumSize[ i ];
5085       }
5086     }
5087   }
5088
5089   return FLT_MAX;  // Default
5090 }
5091
5092 Object* Actor::GetParentObject() const
5093 {
5094   return mParent;
5095 }
5096
5097 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5098 {
5099   if( mVisible != visible )
5100   {
5101     if( sendMessage == SendMessage::TRUE && NULL != mNode )
5102     {
5103       // mNode is being used in a separate thread; queue a message to set the value & base value
5104       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5105     }
5106
5107     mVisible = visible;
5108
5109     // Emit the signal on this actor and all its children
5110     EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5111   }
5112 }
5113
5114 void Actor::SetSiblingOrder( unsigned int order )
5115 {
5116   if ( mParent )
5117   {
5118     ActorContainer& siblings = *(mParent->mChildren);
5119     unsigned int currentOrder = GetSiblingOrder();
5120
5121     if( order != currentOrder )
5122     {
5123       if( order == 0 )
5124       {
5125         LowerToBottom();
5126       }
5127       else if( order < siblings.size() -1 )
5128       {
5129         if( order > currentOrder )
5130         {
5131           RaiseAbove( *siblings[order] );
5132         }
5133         else
5134         {
5135           LowerBelow( *siblings[order] );
5136         }
5137       }
5138       else
5139       {
5140         RaiseToTop();
5141       }
5142     }
5143   }
5144 }
5145
5146 unsigned int Actor::GetSiblingOrder() const
5147 {
5148   unsigned int order = 0;
5149
5150   if ( mParent )
5151   {
5152     ActorContainer& siblings = *(mParent->mChildren);
5153     for( size_t i=0; i<siblings.size(); ++i )
5154     {
5155       if( siblings[i] == this )
5156       {
5157         order = i;
5158         break;
5159       }
5160     }
5161   }
5162
5163   return order;
5164 }
5165
5166 void Actor::RequestRebuildDepthTree()
5167 {
5168   if( mIsOnStage )
5169   {
5170     StagePtr stage = Stage::GetCurrent();
5171     if( stage )
5172     {
5173       stage->RequestRebuildDepthTree();
5174     }
5175   }
5176 }
5177
5178 void Actor::Raise()
5179 {
5180   if ( mParent )
5181   {
5182     ActorContainer& siblings = *(mParent->mChildren);
5183     if( siblings.back() != this ) // If not already at end
5184     {
5185       for( size_t i=0; i<siblings.size(); ++i )
5186       {
5187         if( siblings[i] == this )
5188         {
5189           // Swap with next
5190           ActorPtr next = siblings[i+1];
5191           siblings[i+1] = this;
5192           siblings[i] = next;
5193           break;
5194         }
5195       }
5196     }
5197     RequestRebuildDepthTree();
5198   }
5199   else
5200   {
5201     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5202   }
5203 }
5204
5205 void Actor::Lower()
5206 {
5207   if ( mParent )
5208   {
5209     ActorContainer& siblings = *(mParent->mChildren);
5210     if( siblings.front() != this ) // If not already at beginning
5211     {
5212       for( size_t i=0; i<siblings.size(); ++i )
5213       {
5214         if( siblings[i] == this )
5215         {
5216           // Swap with previous
5217           ActorPtr previous = siblings[i-1];
5218           siblings[i-1] = this;
5219           siblings[i] = previous;
5220           break;
5221         }
5222       }
5223     }
5224     RequestRebuildDepthTree();
5225   }
5226   else
5227   {
5228     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5229   }
5230 }
5231
5232 void Actor::RaiseToTop()
5233 {
5234   if ( mParent )
5235   {
5236     ActorContainer& siblings = *(mParent->mChildren);
5237     if( siblings.back() != this ) // If not already at end
5238     {
5239       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5240       if( iter != siblings.end() )
5241       {
5242         siblings.erase(iter);
5243         siblings.push_back(ActorPtr(this));
5244       }
5245     }
5246     RequestRebuildDepthTree();
5247   }
5248   else
5249   {
5250     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5251   }
5252 }
5253
5254 void Actor::LowerToBottom()
5255 {
5256   if ( mParent )
5257   {
5258     ActorContainer& siblings = *(mParent->mChildren);
5259     if( siblings.front() != this ) // If not already at bottom,
5260     {
5261       ActorPtr thisPtr(this); // ensure this actor remains referenced.
5262
5263       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5264       if( iter != siblings.end() )
5265       {
5266         siblings.erase(iter);
5267         siblings.insert(siblings.begin(), thisPtr);
5268       }
5269     }
5270     RequestRebuildDepthTree();
5271   }
5272   else
5273   {
5274     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5275   }
5276 }
5277
5278 void Actor::RaiseAbove( Internal::Actor& target )
5279 {
5280   if ( mParent )
5281   {
5282     ActorContainer& siblings = *(mParent->mChildren);
5283     if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5284     {
5285       ActorPtr thisPtr(this); // ensure this actor remains referenced.
5286
5287       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5288       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5289       if( thisIter < targetIter )
5290       {
5291         siblings.erase(thisIter);
5292         // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5293         // invalidate thisIter)
5294         targetIter = std::find( siblings.begin(), siblings.end(), &target );
5295         ++targetIter;
5296         siblings.insert(targetIter, thisPtr);
5297       }
5298       RequestRebuildDepthTree();
5299     }
5300   }
5301   else
5302   {
5303     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5304   }
5305 }
5306
5307 void Actor::LowerBelow( Internal::Actor& target )
5308 {
5309   if ( mParent )
5310   {
5311     ActorContainer& siblings = *(mParent->mChildren);
5312     if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5313     {
5314       ActorPtr thisPtr(this); // ensure this actor remains referenced.
5315
5316       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5317       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5318
5319       if( thisIter > targetIter )
5320       {
5321         siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5322         siblings.insert(targetIter, thisPtr);
5323       }
5324       RequestRebuildDepthTree();
5325     }
5326   }
5327   else
5328   {
5329     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5330   }
5331 }
5332
5333 void Actor::SetInheritLayoutDirection( bool inherit )
5334 {
5335   if( mInheritLayoutDirection != inherit )
5336   {
5337     mInheritLayoutDirection = inherit;
5338
5339     if( inherit && mParent )
5340     {
5341       InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5342     }
5343   }
5344 }
5345
5346 bool Actor::IsLayoutDirectionInherited() const
5347 {
5348   return mInheritLayoutDirection;
5349 }
5350
5351 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::DevelActor::LayoutDirection::Type direction, bool set )
5352 {
5353   if( actor && ( actor->mInheritLayoutDirection || set ) )
5354   {
5355     if( actor->mLayoutDirection != direction)
5356     {
5357       actor->mLayoutDirection = direction;
5358       actor->EmitLayoutDirectionChangedSignal( direction );
5359       actor->RelayoutRequest();
5360     }
5361
5362     if( actor->GetChildCount() > 0 )
5363     {
5364       ActorContainer& children = actor->GetChildrenInternal();
5365       for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5366       {
5367         InheritLayoutDirectionRecursively( *iter, direction );
5368       }
5369     }
5370   }
5371 }
5372
5373 } // namespace Internal
5374
5375 } // namespace Dali