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