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