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