Merge "Added signal to inform when an Actor's children have changed order" into devel...
[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 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
2092 {
2093   return mChildOrderChangedSignal;
2094 }
2095
2096 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2097 {
2098   bool connected( true );
2099   Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2100
2101   if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2102   {
2103     actor->TouchedSignal().Connect( tracker, functor );
2104   }
2105   else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2106   {
2107     actor->HoveredSignal().Connect( tracker, functor );
2108   }
2109   else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2110   {
2111     actor->WheelEventSignal().Connect( tracker, functor );
2112   }
2113   else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2114   {
2115     actor->OnStageSignal().Connect( tracker, functor );
2116   }
2117   else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2118   {
2119     actor->OffStageSignal().Connect( tracker, functor );
2120   }
2121   else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2122   {
2123     actor->OnRelayoutSignal().Connect( tracker, functor );
2124   }
2125   else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2126   {
2127     actor->TouchSignal().Connect( tracker, functor );
2128   }
2129   else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
2130   {
2131     actor->VisibilityChangedSignal().Connect( tracker, functor );
2132   }
2133   else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2134   {
2135     actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2136   }
2137   else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2138   {
2139     actor->ChildAddedSignal().Connect( tracker, functor );
2140   }
2141   else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2142   {
2143     actor->ChildRemovedSignal().Connect( tracker, functor );
2144   }
2145   else
2146   {
2147     // signalName does not match any signal
2148     connected = false;
2149   }
2150
2151   return connected;
2152 }
2153
2154 Actor::Actor( DerivedType derivedType )
2155 : mParent( NULL ),
2156   mChildren( NULL ),
2157   mRenderers( NULL ),
2158   mNode( NULL ),
2159   mParentOrigin( NULL ),
2160   mAnchorPoint( NULL ),
2161   mRelayoutData( NULL ),
2162   mGestureData( NULL ),
2163   mTouchedSignal(),
2164   mTouchSignal(),
2165   mHoveredSignal(),
2166   mWheelEventSignal(),
2167   mOnStageSignal(),
2168   mOffStageSignal(),
2169   mOnRelayoutSignal(),
2170   mVisibilityChangedSignal(),
2171   mLayoutDirectionChangedSignal(),
2172   mChildAddedSignal(),
2173   mChildRemovedSignal(),
2174   mChildOrderChangedSignal(),
2175   mTargetOrientation( Quaternion::IDENTITY ),
2176   mTargetColor( Color::WHITE ),
2177   mTargetSize( Vector3::ZERO ),
2178   mTargetPosition( Vector3::ZERO ),
2179   mTargetScale( Vector3::ONE ),
2180   mName(),
2181   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2182   mSortedDepth( 0u ),
2183   mDepth( 0u ),
2184   mIsRoot( ROOT_LAYER == derivedType ),
2185   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2186   mIsOnStage( false ),
2187   mSensitive( true ),
2188   mLeaveRequired( false ),
2189   mKeyboardFocusable( false ),
2190   mDerivedRequiresTouch( false ),
2191   mDerivedRequiresHover( false ),
2192   mDerivedRequiresWheelEvent( false ),
2193   mOnStageSignalled( false ),
2194   mInsideOnSizeSet( false ),
2195   mInheritPosition( true ),
2196   mInheritOrientation( true ),
2197   mInheritScale( true ),
2198   mPositionUsesAnchorPoint( true ),
2199   mVisible( true ),
2200   mInheritLayoutDirection( true ),
2201   mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2202   mDrawMode( DrawMode::NORMAL ),
2203   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2204   mColorMode( Node::DEFAULT_COLOR_MODE ),
2205   mClippingMode( ClippingMode::DISABLED )
2206 {
2207 }
2208
2209 void Actor::Initialize()
2210 {
2211   // Node creation, keep raw-pointer to Node for messaging
2212   mNode = CreateNode();
2213   OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
2214   AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
2215
2216   OnInitialize();
2217
2218   GetEventThreadServices().RegisterObject( this );
2219 }
2220
2221 Actor::~Actor()
2222 {
2223   // Remove mParent pointers from children even if we're destroying core,
2224   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2225   if( mChildren )
2226   {
2227     ActorConstIter endIter = mChildren->end();
2228     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2229     {
2230       (*iter)->SetParent( NULL );
2231     }
2232   }
2233   delete mChildren;
2234   delete mRenderers;
2235
2236   // Guard to allow handle destruction after Core has been destroyed
2237   if( EventThreadServices::IsCoreRunning() )
2238   {
2239     if( NULL != mNode )
2240     {
2241       DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2242       mNode = NULL; // Node is about to be destroyed
2243     }
2244
2245     GetEventThreadServices().UnregisterObject( this );
2246   }
2247
2248   // Cleanup optional gesture data
2249   delete mGestureData;
2250
2251   // Cleanup optional parent origin and anchor
2252   delete mParentOrigin;
2253   delete mAnchorPoint;
2254
2255   // Delete optional relayout data
2256   if( mRelayoutData )
2257   {
2258     delete mRelayoutData;
2259   }
2260 }
2261
2262 void Actor::ConnectToStage( unsigned int parentDepth )
2263 {
2264   // This container is used instead of walking the Actor hierarchy.
2265   // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2266   ActorContainer connectionList;
2267
2268   StagePtr stage = Stage::GetCurrent();
2269   if( stage )
2270   {
2271     stage->RequestRebuildDepthTree();
2272   }
2273
2274   // This stage is atomic i.e. not interrupted by user callbacks.
2275   RecursiveConnectToStage( connectionList, parentDepth + 1 );
2276
2277   // Notify applications about the newly connected actors.
2278   const ActorIter endIter = connectionList.end();
2279   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2280   {
2281     (*iter)->NotifyStageConnection();
2282   }
2283
2284   RelayoutRequest();
2285 }
2286
2287 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2288 {
2289   DALI_ASSERT_ALWAYS( !OnStage() );
2290
2291   mIsOnStage = true;
2292   mDepth = depth;
2293
2294   ConnectToSceneGraph();
2295
2296   // Notification for internal derived classes
2297   OnStageConnectionInternal();
2298
2299   // This stage is atomic; avoid emitting callbacks until all Actors are connected
2300   connectionList.push_back( ActorPtr( this ) );
2301
2302   // Recursively connect children
2303   if( mChildren )
2304   {
2305     ActorConstIter endIter = mChildren->end();
2306     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2307     {
2308       (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2309     }
2310   }
2311 }
2312
2313 /**
2314  * This method is called when the Actor is connected to the Stage.
2315  * The parent must have added its Node to the scene-graph.
2316  * The child must connect its Node to the parent's Node.
2317  * This is recursive; the child calls ConnectToStage() for its children.
2318  */
2319 void Actor::ConnectToSceneGraph()
2320 {
2321   DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2322
2323   if( NULL != mNode )
2324   {
2325     // Reparent Node in next Update
2326     ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2327   }
2328
2329   // Request relayout on all actors that are added to the scenegraph
2330   RelayoutRequest();
2331
2332   // Notification for Object::Observers
2333   OnSceneObjectAdd();
2334 }
2335
2336 void Actor::NotifyStageConnection()
2337 {
2338   // Actors can be removed (in a callback), before the on-stage stage is reported.
2339   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2340   if( OnStage() && !mOnStageSignalled )
2341   {
2342     // Notification for external (CustomActor) derived classes
2343     OnStageConnectionExternal( mDepth );
2344
2345     if( !mOnStageSignal.Empty() )
2346     {
2347       Dali::Actor handle( this );
2348       mOnStageSignal.Emit( handle );
2349     }
2350
2351     // Guard against Remove during callbacks
2352     if( OnStage() )
2353     {
2354       mOnStageSignalled = true; // signal required next time Actor is removed
2355     }
2356   }
2357 }
2358
2359 void Actor::DisconnectFromStage()
2360 {
2361   // This container is used instead of walking the Actor hierachy.
2362   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2363   ActorContainer disconnectionList;
2364
2365   StagePtr stage = Stage::GetCurrent();
2366   if( stage )
2367   {
2368     stage->RequestRebuildDepthTree();
2369   }
2370
2371   // This stage is atomic i.e. not interrupted by user callbacks
2372   RecursiveDisconnectFromStage( disconnectionList );
2373
2374   // Notify applications about the newly disconnected actors.
2375   const ActorIter endIter = disconnectionList.end();
2376   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2377   {
2378     (*iter)->NotifyStageDisconnection();
2379   }
2380 }
2381
2382 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2383 {
2384   DALI_ASSERT_ALWAYS( OnStage() );
2385
2386   // Recursively disconnect children
2387   if( mChildren )
2388   {
2389     ActorConstIter endIter = mChildren->end();
2390     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2391     {
2392       (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2393     }
2394   }
2395
2396   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2397   disconnectionList.push_back( ActorPtr( this ) );
2398
2399   // Notification for internal derived classes
2400   OnStageDisconnectionInternal();
2401
2402   DisconnectFromSceneGraph();
2403
2404   mIsOnStage = false;
2405 }
2406
2407 /**
2408  * This method is called by an actor or its parent, before a node removal message is sent.
2409  * This is recursive; the child calls DisconnectFromStage() for its children.
2410  */
2411 void Actor::DisconnectFromSceneGraph()
2412 {
2413   // Notification for Object::Observers
2414   OnSceneObjectRemove();
2415 }
2416
2417 void Actor::NotifyStageDisconnection()
2418 {
2419   // Actors can be added (in a callback), before the off-stage state is reported.
2420   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2421   // only do this step if there is a stage, i.e. Core is not being shut down
2422   if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2423   {
2424     // Notification for external (CustomeActor) derived classes
2425     OnStageDisconnectionExternal();
2426
2427     if( !mOffStageSignal.Empty() )
2428     {
2429       Dali::Actor handle( this );
2430       mOffStageSignal.Emit( handle );
2431     }
2432
2433     // Guard against Add during callbacks
2434     if( !OnStage() )
2435     {
2436       mOnStageSignalled = false; // signal required next time Actor is added
2437     }
2438   }
2439 }
2440
2441 bool Actor::IsNodeConnected() const
2442 {
2443   bool connected( false );
2444
2445   if( OnStage() && ( NULL != mNode ) )
2446   {
2447     if( IsRoot() || mNode->GetParent() )
2448     {
2449       connected = true;
2450     }
2451   }
2452
2453   return connected;
2454 }
2455
2456 // This method initiates traversal of the actor tree using depth-first
2457 // traversal to set a depth index based on traversal order. It sends a
2458 // single message to update manager to update all the actor's nodes in
2459 // this tree with the depth index. The sceneGraphNodeDepths vector's
2460 // elements are ordered by depth, and could be used to reduce sorting
2461 // in the update thread.
2462 void Actor::RebuildDepthTree()
2463 {
2464   DALI_LOG_TIMER_START(depthTimer);
2465
2466   // Vector of scene-graph nodes and their depths to send to UpdateManager
2467   // in a single message
2468   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2469
2470   int depthIndex = 1;
2471   DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2472
2473   SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2474   DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2475 }
2476
2477 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
2478 {
2479   mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2480   sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
2481
2482   // Create/add to children of this node
2483   if( mChildren )
2484   {
2485     for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2486     {
2487       Actor* childActor = (*it).Get();
2488       ++depthIndex;
2489       childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2490     }
2491   }
2492 }
2493
2494 unsigned int Actor::GetDefaultPropertyCount() const
2495 {
2496   return DEFAULT_PROPERTY_COUNT;
2497 }
2498
2499 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2500 {
2501   indices.Reserve( DEFAULT_PROPERTY_COUNT );
2502
2503   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2504   {
2505     indices.PushBack( i );
2506   }
2507 }
2508
2509 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2510 {
2511   if( index < DEFAULT_PROPERTY_COUNT )
2512   {
2513     return DEFAULT_PROPERTY_DETAILS[ index ].name;
2514   }
2515
2516   return NULL;
2517 }
2518
2519 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2520 {
2521   Property::Index index = Property::INVALID_INDEX;
2522
2523   // Look for name in default properties
2524   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2525   {
2526     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2527     if( 0 == name.compare( property->name ) )
2528     {
2529       index = i;
2530       break;
2531     }
2532   }
2533
2534   return index;
2535 }
2536
2537 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2538 {
2539   if( index < DEFAULT_PROPERTY_COUNT )
2540   {
2541     return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2542   }
2543
2544   return false;
2545 }
2546
2547 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2548 {
2549   if( index < DEFAULT_PROPERTY_COUNT )
2550   {
2551     return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2552   }
2553
2554   return false;
2555 }
2556
2557 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2558 {
2559   if( index < DEFAULT_PROPERTY_COUNT )
2560   {
2561     return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2562   }
2563
2564   return false;
2565 }
2566
2567 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2568 {
2569   if( index < DEFAULT_PROPERTY_COUNT )
2570   {
2571     return DEFAULT_PROPERTY_DETAILS[ index ].type;
2572   }
2573
2574   // index out of range...return Property::NONE
2575   return Property::NONE;
2576 }
2577
2578 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2579 {
2580   switch( index )
2581   {
2582     case Dali::Actor::Property::PARENT_ORIGIN:
2583     {
2584       Property::Type type = property.GetType();
2585       if( type == Property::VECTOR3 )
2586       {
2587         SetParentOrigin( property.Get< Vector3 >() );
2588       }
2589       else if ( type == Property::STRING )
2590       {
2591         std::string parentOriginString;
2592         property.Get( parentOriginString );
2593         Vector3 parentOrigin;
2594         if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2595         {
2596           SetParentOrigin( parentOrigin );
2597         }
2598       }
2599       break;
2600     }
2601
2602     case Dali::Actor::Property::PARENT_ORIGIN_X:
2603     {
2604       SetParentOriginX( property.Get< float >() );
2605       break;
2606     }
2607
2608     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2609     {
2610       SetParentOriginY( property.Get< float >() );
2611       break;
2612     }
2613
2614     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2615     {
2616       SetParentOriginZ( property.Get< float >() );
2617       break;
2618     }
2619
2620     case Dali::Actor::Property::ANCHOR_POINT:
2621     {
2622       Property::Type type = property.GetType();
2623       if( type == Property::VECTOR3 )
2624       {
2625         SetAnchorPoint( property.Get< Vector3 >() );
2626       }
2627       else if ( type == Property::STRING )
2628       {
2629         std::string anchorPointString;
2630         property.Get( anchorPointString );
2631         Vector3 anchor;
2632         if( GetAnchorPointConstant( anchorPointString, anchor ) )
2633         {
2634           SetAnchorPoint( anchor );
2635         }
2636       }
2637       break;
2638     }
2639
2640     case Dali::Actor::Property::ANCHOR_POINT_X:
2641     {
2642       SetAnchorPointX( property.Get< float >() );
2643       break;
2644     }
2645
2646     case Dali::Actor::Property::ANCHOR_POINT_Y:
2647     {
2648       SetAnchorPointY( property.Get< float >() );
2649       break;
2650     }
2651
2652     case Dali::Actor::Property::ANCHOR_POINT_Z:
2653     {
2654       SetAnchorPointZ( property.Get< float >() );
2655       break;
2656     }
2657
2658     case Dali::Actor::Property::SIZE:
2659     {
2660       SetSize( property.Get< Vector3 >() );
2661       break;
2662     }
2663
2664     case Dali::Actor::Property::SIZE_WIDTH:
2665     {
2666       SetWidth( property.Get< float >() );
2667       break;
2668     }
2669
2670     case Dali::Actor::Property::SIZE_HEIGHT:
2671     {
2672       SetHeight( property.Get< float >() );
2673       break;
2674     }
2675
2676     case Dali::Actor::Property::SIZE_DEPTH:
2677     {
2678       SetDepth( property.Get< float >() );
2679       break;
2680     }
2681
2682     case Dali::Actor::Property::POSITION:
2683     {
2684       SetPosition( property.Get< Vector3 >() );
2685       break;
2686     }
2687
2688     case Dali::Actor::Property::POSITION_X:
2689     {
2690       SetX( property.Get< float >() );
2691       break;
2692     }
2693
2694     case Dali::Actor::Property::POSITION_Y:
2695     {
2696       SetY( property.Get< float >() );
2697       break;
2698     }
2699
2700     case Dali::Actor::Property::POSITION_Z:
2701     {
2702       SetZ( property.Get< float >() );
2703       break;
2704     }
2705
2706     case Dali::Actor::Property::ORIENTATION:
2707     {
2708       SetOrientation( property.Get< Quaternion >() );
2709       break;
2710     }
2711
2712     case Dali::Actor::Property::SCALE:
2713     {
2714       SetScale( property.Get< Vector3 >() );
2715       break;
2716     }
2717
2718     case Dali::Actor::Property::SCALE_X:
2719     {
2720       SetScaleX( property.Get< float >() );
2721       break;
2722     }
2723
2724     case Dali::Actor::Property::SCALE_Y:
2725     {
2726       SetScaleY( property.Get< float >() );
2727       break;
2728     }
2729
2730     case Dali::Actor::Property::SCALE_Z:
2731     {
2732       SetScaleZ( property.Get< float >() );
2733       break;
2734     }
2735
2736     case Dali::Actor::Property::VISIBLE:
2737     {
2738       SetVisible( property.Get< bool >() );
2739       break;
2740     }
2741
2742     case Dali::Actor::Property::COLOR:
2743     {
2744       SetColor( property.Get< Vector4 >() );
2745       break;
2746     }
2747
2748     case Dali::Actor::Property::COLOR_RED:
2749     {
2750       SetColorRed( property.Get< float >() );
2751       break;
2752     }
2753
2754     case Dali::Actor::Property::COLOR_GREEN:
2755     {
2756       SetColorGreen( property.Get< float >() );
2757       break;
2758     }
2759
2760     case Dali::Actor::Property::COLOR_BLUE:
2761     {
2762       SetColorBlue( property.Get< float >() );
2763       break;
2764     }
2765
2766     case Dali::Actor::Property::COLOR_ALPHA:
2767     case Dali::DevelActor::Property::OPACITY:
2768     {
2769       float value;
2770       if( property.Get( value ) )
2771       {
2772         SetOpacity( value );
2773       }
2774       break;
2775     }
2776
2777     case Dali::Actor::Property::NAME:
2778     {
2779       SetName( property.Get< std::string >() );
2780       break;
2781     }
2782
2783     case Dali::Actor::Property::SENSITIVE:
2784     {
2785       SetSensitive( property.Get< bool >() );
2786       break;
2787     }
2788
2789     case Dali::Actor::Property::LEAVE_REQUIRED:
2790     {
2791       SetLeaveRequired( property.Get< bool >() );
2792       break;
2793     }
2794
2795     case Dali::Actor::Property::INHERIT_POSITION:
2796     {
2797       SetInheritPosition( property.Get< bool >() );
2798       break;
2799     }
2800
2801     case Dali::Actor::Property::INHERIT_ORIENTATION:
2802     {
2803       SetInheritOrientation( property.Get< bool >() );
2804       break;
2805     }
2806
2807     case Dali::Actor::Property::INHERIT_SCALE:
2808     {
2809       SetInheritScale( property.Get< bool >() );
2810       break;
2811     }
2812
2813     case Dali::Actor::Property::COLOR_MODE:
2814     {
2815       ColorMode mode = mColorMode;
2816       if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2817       {
2818         SetColorMode( mode );
2819       }
2820       break;
2821     }
2822
2823     case Dali::Actor::Property::POSITION_INHERITANCE:
2824     {
2825       PositionInheritanceMode mode = mPositionInheritanceMode;
2826       if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2827       {
2828         SetPositionInheritanceMode( mode );
2829       }
2830       break;
2831     }
2832
2833     case Dali::Actor::Property::DRAW_MODE:
2834     {
2835       DrawMode::Type mode = mDrawMode;
2836       if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2837       {
2838         SetDrawMode( mode );
2839       }
2840       break;
2841     }
2842
2843     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2844     {
2845       SetSizeModeFactor( property.Get< Vector3 >() );
2846       break;
2847     }
2848
2849     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2850     {
2851       ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2852       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2853       {
2854         SetResizePolicy( type, Dimension::WIDTH );
2855       }
2856       break;
2857     }
2858
2859     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2860     {
2861       ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2862       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2863       {
2864         SetResizePolicy( type, Dimension::HEIGHT );
2865       }
2866       break;
2867     }
2868
2869     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2870     {
2871       SizeScalePolicy::Type type;
2872       if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2873       {
2874         SetSizeScalePolicy( type );
2875       }
2876       break;
2877     }
2878
2879     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2880     {
2881       if( property.Get< bool >() )
2882       {
2883         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2884       }
2885       break;
2886     }
2887
2888     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2889     {
2890       if( property.Get< bool >() )
2891       {
2892         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2893       }
2894       break;
2895     }
2896
2897     case Dali::Actor::Property::PADDING:
2898     {
2899       Vector4 padding = property.Get< Vector4 >();
2900       SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2901       SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2902       break;
2903     }
2904
2905     case Dali::Actor::Property::MINIMUM_SIZE:
2906     {
2907       Vector2 size = property.Get< Vector2 >();
2908       SetMinimumSize( size.x, Dimension::WIDTH );
2909       SetMinimumSize( size.y, Dimension::HEIGHT );
2910       break;
2911     }
2912
2913     case Dali::Actor::Property::MAXIMUM_SIZE:
2914     {
2915       Vector2 size = property.Get< Vector2 >();
2916       SetMaximumSize( size.x, Dimension::WIDTH );
2917       SetMaximumSize( size.y, Dimension::HEIGHT );
2918       break;
2919     }
2920
2921     case Dali::DevelActor::Property::SIBLING_ORDER:
2922     {
2923       int value;
2924
2925       if( property.Get( value ) )
2926       {
2927         SetSiblingOrder( value );
2928       }
2929       break;
2930     }
2931
2932     case Dali::Actor::Property::CLIPPING_MODE:
2933     {
2934       ClippingMode::Type convertedValue = mClippingMode;
2935       if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2936       {
2937         mClippingMode = convertedValue;
2938         if( NULL != mNode )
2939         {
2940           SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2941         }
2942       }
2943       break;
2944     }
2945
2946     case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2947     {
2948       bool value = false;
2949       if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2950       {
2951         mPositionUsesAnchorPoint = value;
2952         if( NULL != mNode )
2953         {
2954           SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2955         }
2956       }
2957       break;
2958     }
2959
2960     case Dali::Actor::Property::LAYOUT_DIRECTION:
2961     {
2962       Dali::LayoutDirection::Type direction = mLayoutDirection;
2963       mInheritLayoutDirection = false;
2964
2965       if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2966       {
2967         InheritLayoutDirectionRecursively( this, direction, true );
2968       }
2969       break;
2970     }
2971
2972     case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2973     {
2974       bool value = false;
2975       if( property.Get( value ) )
2976       {
2977         SetInheritLayoutDirection( value );
2978       }
2979       break;
2980     }
2981
2982     default:
2983     {
2984       // this can happen in the case of a non-animatable default property so just do nothing
2985       break;
2986     }
2987   }
2988 }
2989
2990 // TODO: This method needs to be removed
2991 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2992 {
2993   switch( entry.GetType() )
2994   {
2995     case Property::BOOLEAN:
2996     {
2997       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2998       DALI_ASSERT_DEBUG( NULL != property );
2999
3000       // property is being used in a separate thread; queue a message to set the property
3001       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
3002
3003       break;
3004     }
3005
3006     case Property::INTEGER:
3007     {
3008       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
3009       DALI_ASSERT_DEBUG( NULL != property );
3010
3011       // property is being used in a separate thread; queue a message to set the property
3012       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
3013
3014       break;
3015     }
3016
3017     case Property::FLOAT:
3018     {
3019       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
3020       DALI_ASSERT_DEBUG( NULL != property );
3021
3022       // property is being used in a separate thread; queue a message to set the property
3023       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
3024
3025       break;
3026     }
3027
3028     case Property::VECTOR2:
3029     {
3030       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
3031       DALI_ASSERT_DEBUG( NULL != property );
3032
3033       // property is being used in a separate thread; queue a message to set the property
3034       if(entry.componentIndex == 0)
3035       {
3036         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
3037       }
3038       else if(entry.componentIndex == 1)
3039       {
3040         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
3041       }
3042       else
3043       {
3044         SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
3045       }
3046
3047       break;
3048     }
3049
3050     case Property::VECTOR3:
3051     {
3052       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
3053       DALI_ASSERT_DEBUG( NULL != property );
3054
3055       // property is being used in a separate thread; queue a message to set the property
3056       if(entry.componentIndex == 0)
3057       {
3058         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
3059       }
3060       else if(entry.componentIndex == 1)
3061       {
3062         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
3063       }
3064       else if(entry.componentIndex == 2)
3065       {
3066         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
3067       }
3068       else
3069       {
3070         SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
3071       }
3072
3073       break;
3074     }
3075
3076     case Property::VECTOR4:
3077     {
3078       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
3079       DALI_ASSERT_DEBUG( NULL != property );
3080
3081       // property is being used in a separate thread; queue a message to set the property
3082       if(entry.componentIndex == 0)
3083       {
3084         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3085       }
3086       else if(entry.componentIndex == 1)
3087       {
3088         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3089       }
3090       else if(entry.componentIndex == 2)
3091       {
3092         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3093       }
3094       else if(entry.componentIndex == 3)
3095       {
3096         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3097       }
3098       else
3099       {
3100         SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3101       }
3102
3103       break;
3104     }
3105
3106     case Property::ROTATION:
3107     {
3108       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3109       DALI_ASSERT_DEBUG( NULL != property );
3110
3111       // property is being used in a separate thread; queue a message to set the property
3112       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
3113
3114       break;
3115     }
3116
3117     case Property::MATRIX:
3118     {
3119       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3120       DALI_ASSERT_DEBUG( NULL != property );
3121
3122       // property is being used in a separate thread; queue a message to set the property
3123       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
3124
3125       break;
3126     }
3127
3128     case Property::MATRIX3:
3129     {
3130       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3131       DALI_ASSERT_DEBUG( NULL != property );
3132
3133       // property is being used in a separate thread; queue a message to set the property
3134       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
3135
3136       break;
3137     }
3138
3139     default:
3140     {
3141       // nothing to do for other types
3142     }
3143   } // entry.GetType
3144 }
3145
3146 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3147 {
3148   Property::Value value;
3149
3150   if( ! GetCachedPropertyValue( index, value ) )
3151   {
3152     // If property value is not stored in the event-side, then it must be a scene-graph only property
3153     GetCurrentPropertyValue( index, value );
3154   }
3155
3156   return value;
3157 }
3158
3159 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3160 {
3161   Property::Value value;
3162
3163   if( ! GetCurrentPropertyValue( index, value ) )
3164   {
3165     // If unable to retrieve scene-graph property value, then it must be an event-side only property
3166     GetCachedPropertyValue( index, value );
3167   }
3168
3169   return value;
3170 }
3171
3172 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3173 {
3174   switch( animationType )
3175   {
3176     case Animation::TO:
3177     case Animation::BETWEEN:
3178     {
3179       switch( index )
3180       {
3181         case Dali::Actor::Property::SIZE:
3182         {
3183           if( value.Get( mTargetSize ) )
3184           {
3185             // Notify deriving classes
3186             OnSizeAnimation( animation, mTargetSize );
3187           }
3188           break;
3189         }
3190
3191         case Dali::Actor::Property::SIZE_WIDTH:
3192         {
3193           if( value.Get( mTargetSize.width ) )
3194           {
3195             // Notify deriving classes
3196             OnSizeAnimation( animation, mTargetSize );
3197           }
3198           break;
3199         }
3200
3201         case Dali::Actor::Property::SIZE_HEIGHT:
3202         {
3203           if( value.Get( mTargetSize.height ) )
3204           {
3205             // Notify deriving classes
3206             OnSizeAnimation( animation, mTargetSize );
3207           }
3208           break;
3209         }
3210
3211         case Dali::Actor::Property::SIZE_DEPTH:
3212         {
3213           if( value.Get( mTargetSize.depth ) )
3214           {
3215             // Notify deriving classes
3216             OnSizeAnimation( animation, mTargetSize );
3217           }
3218           break;
3219         }
3220
3221         case Dali::Actor::Property::POSITION:
3222         {
3223           value.Get( mTargetPosition );
3224           break;
3225         }
3226
3227         case Dali::Actor::Property::POSITION_X:
3228         {
3229           value.Get( mTargetPosition.x );
3230           break;
3231         }
3232
3233         case Dali::Actor::Property::POSITION_Y:
3234         {
3235           value.Get( mTargetPosition.y );
3236           break;
3237         }
3238
3239         case Dali::Actor::Property::POSITION_Z:
3240         {
3241           value.Get( mTargetPosition.z );
3242           break;
3243         }
3244
3245         case Dali::Actor::Property::ORIENTATION:
3246         {
3247           value.Get( mTargetOrientation );
3248           break;
3249         }
3250
3251         case Dali::Actor::Property::SCALE:
3252         {
3253           value.Get( mTargetScale );
3254           break;
3255         }
3256
3257         case Dali::Actor::Property::SCALE_X:
3258         {
3259           value.Get( mTargetScale.x );
3260           break;
3261         }
3262
3263         case Dali::Actor::Property::SCALE_Y:
3264         {
3265           value.Get( mTargetScale.y );
3266           break;
3267         }
3268
3269         case Dali::Actor::Property::SCALE_Z:
3270         {
3271           value.Get( mTargetScale.z );
3272           break;
3273         }
3274
3275         case Dali::Actor::Property::VISIBLE:
3276         {
3277           SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3278           break;
3279         }
3280
3281         case Dali::Actor::Property::COLOR:
3282         {
3283           value.Get( mTargetColor );
3284           break;
3285         }
3286
3287         case Dali::Actor::Property::COLOR_RED:
3288         {
3289           value.Get( mTargetColor.r );
3290           break;
3291         }
3292
3293         case Dali::Actor::Property::COLOR_GREEN:
3294         {
3295           value.Get( mTargetColor.g );
3296           break;
3297         }
3298
3299         case Dali::Actor::Property::COLOR_BLUE:
3300         {
3301           value.Get( mTargetColor.b );
3302           break;
3303         }
3304
3305         case Dali::Actor::Property::COLOR_ALPHA:
3306         case Dali::DevelActor::Property::OPACITY:
3307         {
3308           value.Get( mTargetColor.a );
3309           break;
3310         }
3311
3312         default:
3313         {
3314           // Not an animatable property. Do nothing.
3315           break;
3316         }
3317       }
3318       break;
3319     }
3320
3321     case Animation::BY:
3322     {
3323       switch( index )
3324       {
3325         case Dali::Actor::Property::SIZE:
3326         {
3327           if( AdjustValue< Vector3 >( mTargetSize, value ) )
3328           {
3329             // Notify deriving classes
3330             OnSizeAnimation( animation, mTargetSize );
3331           }
3332           break;
3333         }
3334
3335         case Dali::Actor::Property::SIZE_WIDTH:
3336         {
3337           if( AdjustValue< float >( mTargetSize.width, value ) )
3338           {
3339             // Notify deriving classes
3340             OnSizeAnimation( animation, mTargetSize );
3341           }
3342           break;
3343         }
3344
3345         case Dali::Actor::Property::SIZE_HEIGHT:
3346         {
3347           if( AdjustValue< float >( mTargetSize.height, value ) )
3348           {
3349             // Notify deriving classes
3350             OnSizeAnimation( animation, mTargetSize );
3351           }
3352           break;
3353         }
3354
3355         case Dali::Actor::Property::SIZE_DEPTH:
3356         {
3357           if( AdjustValue< float >( mTargetSize.depth, value ) )
3358           {
3359             // Notify deriving classes
3360             OnSizeAnimation( animation, mTargetSize );
3361           }
3362           break;
3363         }
3364
3365         case Dali::Actor::Property::POSITION:
3366         {
3367           AdjustValue< Vector3 >( mTargetPosition, value );
3368           break;
3369         }
3370
3371         case Dali::Actor::Property::POSITION_X:
3372         {
3373           AdjustValue< float >( mTargetPosition.x, value );
3374           break;
3375         }
3376
3377         case Dali::Actor::Property::POSITION_Y:
3378         {
3379           AdjustValue< float >( mTargetPosition.y, value );
3380           break;
3381         }
3382
3383         case Dali::Actor::Property::POSITION_Z:
3384         {
3385           AdjustValue< float >( mTargetPosition.z, value );
3386           break;
3387         }
3388
3389         case Dali::Actor::Property::ORIENTATION:
3390         {
3391           Quaternion relativeValue;
3392           if( value.Get( relativeValue ) )
3393           {
3394             mTargetOrientation *= relativeValue;
3395           }
3396           break;
3397         }
3398
3399         case Dali::Actor::Property::SCALE:
3400         {
3401           AdjustValue< Vector3 >( mTargetScale, value );
3402           break;
3403         }
3404
3405         case Dali::Actor::Property::SCALE_X:
3406         {
3407           AdjustValue< float >( mTargetScale.x, value );
3408           break;
3409         }
3410
3411         case Dali::Actor::Property::SCALE_Y:
3412         {
3413           AdjustValue< float >( mTargetScale.y, value );
3414           break;
3415         }
3416
3417         case Dali::Actor::Property::SCALE_Z:
3418         {
3419           AdjustValue< float >( mTargetScale.z, value );
3420           break;
3421         }
3422
3423         case Dali::Actor::Property::VISIBLE:
3424         {
3425           bool relativeValue = false;
3426           if( value.Get( relativeValue ) )
3427           {
3428             bool visible = mVisible || relativeValue;
3429             SetVisibleInternal( visible, SendMessage::FALSE );
3430           }
3431           break;
3432         }
3433
3434         case Dali::Actor::Property::COLOR:
3435         {
3436           AdjustValue< Vector4 >( mTargetColor, value );
3437           break;
3438         }
3439
3440         case Dali::Actor::Property::COLOR_RED:
3441         {
3442           AdjustValue< float >( mTargetColor.r, value );
3443           break;
3444         }
3445
3446         case Dali::Actor::Property::COLOR_GREEN:
3447         {
3448           AdjustValue< float >( mTargetColor.g, value );
3449           break;
3450         }
3451
3452         case Dali::Actor::Property::COLOR_BLUE:
3453         {
3454           AdjustValue< float >( mTargetColor.b, value );
3455           break;
3456         }
3457
3458         case Dali::Actor::Property::COLOR_ALPHA:
3459         case Dali::DevelActor::Property::OPACITY:
3460         {
3461           AdjustValue< float >( mTargetColor.a, value );
3462           break;
3463         }
3464
3465         default:
3466         {
3467           // Not an animatable property. Do nothing.
3468           break;
3469         }
3470       }
3471       break;
3472     }
3473   }
3474 }
3475
3476 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3477 {
3478   return mNode;
3479 }
3480
3481 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3482 {
3483   // This method should only return an object connected to the scene-graph
3484   return OnStage() ? mNode : NULL;
3485 }
3486
3487 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3488 {
3489   DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3490
3491   const PropertyBase* property( NULL );
3492
3493   // This method should only return a property of an object connected to the scene-graph
3494   if( !OnStage() )
3495   {
3496     return property;
3497   }
3498
3499   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3500   {
3501     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3502     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3503
3504     property = animatable->GetSceneGraphProperty();
3505   }
3506   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3507             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3508   {
3509     CustomPropertyMetadata* custom = FindCustomProperty( index );
3510     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3511
3512     property = custom->GetSceneGraphProperty();
3513   }
3514   else if( NULL != mNode )
3515   {
3516     switch( index )
3517     {
3518       case Dali::Actor::Property::SIZE:
3519         property = &mNode->mSize;
3520         break;
3521
3522       case Dali::Actor::Property::SIZE_WIDTH:
3523         property = &mNode->mSize;
3524         break;
3525
3526       case Dali::Actor::Property::SIZE_HEIGHT:
3527         property = &mNode->mSize;
3528         break;
3529
3530       case Dali::Actor::Property::SIZE_DEPTH:
3531         property = &mNode->mSize;
3532         break;
3533
3534       case Dali::Actor::Property::POSITION:
3535         property = &mNode->mPosition;
3536         break;
3537
3538       case Dali::Actor::Property::POSITION_X:
3539         property = &mNode->mPosition;
3540         break;
3541
3542       case Dali::Actor::Property::POSITION_Y:
3543         property = &mNode->mPosition;
3544         break;
3545
3546       case Dali::Actor::Property::POSITION_Z:
3547         property = &mNode->mPosition;
3548         break;
3549
3550       case Dali::Actor::Property::ORIENTATION:
3551         property = &mNode->mOrientation;
3552         break;
3553
3554       case Dali::Actor::Property::SCALE:
3555         property = &mNode->mScale;
3556         break;
3557
3558       case Dali::Actor::Property::SCALE_X:
3559         property = &mNode->mScale;
3560         break;
3561
3562       case Dali::Actor::Property::SCALE_Y:
3563         property = &mNode->mScale;
3564         break;
3565
3566       case Dali::Actor::Property::SCALE_Z:
3567         property = &mNode->mScale;
3568         break;
3569
3570       case Dali::Actor::Property::VISIBLE:
3571         property = &mNode->mVisible;
3572         break;
3573
3574       case Dali::Actor::Property::COLOR:
3575         property = &mNode->mColor;
3576         break;
3577
3578       case Dali::Actor::Property::COLOR_RED:
3579         property = &mNode->mColor;
3580         break;
3581
3582       case Dali::Actor::Property::COLOR_GREEN:
3583         property = &mNode->mColor;
3584         break;
3585
3586       case Dali::Actor::Property::COLOR_BLUE:
3587         property = &mNode->mColor;
3588         break;
3589
3590       case Dali::Actor::Property::COLOR_ALPHA:
3591       case Dali::DevelActor::Property::OPACITY:
3592         property = &mNode->mColor;
3593         break;
3594
3595       default:
3596         break;
3597     }
3598   }
3599
3600   return property;
3601 }
3602
3603 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3604 {
3605   const PropertyInputImpl* property( NULL );
3606
3607   // This method should only return a property of an object connected to the scene-graph
3608   if( !OnStage() )
3609   {
3610     return property;
3611   }
3612
3613   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3614   {
3615     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3616     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3617
3618     property = animatable->GetSceneGraphProperty();
3619   }
3620   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3621             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3622   {
3623     CustomPropertyMetadata* custom = FindCustomProperty( index );
3624     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3625     property = custom->GetSceneGraphProperty();
3626   }
3627   else if( NULL != mNode )
3628   {
3629     switch( index )
3630     {
3631       case Dali::Actor::Property::PARENT_ORIGIN:
3632         property = &mNode->mParentOrigin;
3633         break;
3634
3635       case Dali::Actor::Property::PARENT_ORIGIN_X:
3636         property = &mNode->mParentOrigin;
3637         break;
3638
3639       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3640         property = &mNode->mParentOrigin;
3641         break;
3642
3643       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3644         property = &mNode->mParentOrigin;
3645         break;
3646
3647       case Dali::Actor::Property::ANCHOR_POINT:
3648         property = &mNode->mAnchorPoint;
3649         break;
3650
3651       case Dali::Actor::Property::ANCHOR_POINT_X:
3652         property = &mNode->mAnchorPoint;
3653         break;
3654
3655       case Dali::Actor::Property::ANCHOR_POINT_Y:
3656         property = &mNode->mAnchorPoint;
3657         break;
3658
3659       case Dali::Actor::Property::ANCHOR_POINT_Z:
3660         property = &mNode->mAnchorPoint;
3661         break;
3662
3663       case Dali::Actor::Property::SIZE:
3664         property = &mNode->mSize;
3665         break;
3666
3667       case Dali::Actor::Property::SIZE_WIDTH:
3668         property = &mNode->mSize;
3669         break;
3670
3671       case Dali::Actor::Property::SIZE_HEIGHT:
3672         property = &mNode->mSize;
3673         break;
3674
3675       case Dali::Actor::Property::SIZE_DEPTH:
3676         property = &mNode->mSize;
3677         break;
3678
3679       case Dali::Actor::Property::POSITION:
3680         property = &mNode->mPosition;
3681         break;
3682
3683       case Dali::Actor::Property::POSITION_X:
3684         property = &mNode->mPosition;
3685         break;
3686
3687       case Dali::Actor::Property::POSITION_Y:
3688         property = &mNode->mPosition;
3689         break;
3690
3691       case Dali::Actor::Property::POSITION_Z:
3692         property = &mNode->mPosition;
3693         break;
3694
3695       case Dali::Actor::Property::WORLD_POSITION:
3696         property = &mNode->mWorldPosition;
3697         break;
3698
3699       case Dali::Actor::Property::WORLD_POSITION_X:
3700         property = &mNode->mWorldPosition;
3701         break;
3702
3703       case Dali::Actor::Property::WORLD_POSITION_Y:
3704         property = &mNode->mWorldPosition;
3705         break;
3706
3707       case Dali::Actor::Property::WORLD_POSITION_Z:
3708         property = &mNode->mWorldPosition;
3709         break;
3710
3711       case Dali::Actor::Property::ORIENTATION:
3712         property = &mNode->mOrientation;
3713         break;
3714
3715       case Dali::Actor::Property::WORLD_ORIENTATION:
3716         property = &mNode->mWorldOrientation;
3717         break;
3718
3719       case Dali::Actor::Property::SCALE:
3720         property = &mNode->mScale;
3721         break;
3722
3723       case Dali::Actor::Property::SCALE_X:
3724         property = &mNode->mScale;
3725         break;
3726
3727       case Dali::Actor::Property::SCALE_Y:
3728         property = &mNode->mScale;
3729         break;
3730
3731       case Dali::Actor::Property::SCALE_Z:
3732         property = &mNode->mScale;
3733         break;
3734
3735       case Dali::Actor::Property::WORLD_SCALE:
3736         property = &mNode->mWorldScale;
3737         break;
3738
3739       case Dali::Actor::Property::VISIBLE:
3740         property = &mNode->mVisible;
3741         break;
3742
3743       case Dali::Actor::Property::COLOR:
3744         property = &mNode->mColor;
3745         break;
3746
3747       case Dali::Actor::Property::COLOR_RED:
3748         property = &mNode->mColor;
3749         break;
3750
3751       case Dali::Actor::Property::COLOR_GREEN:
3752         property = &mNode->mColor;
3753         break;
3754
3755       case Dali::Actor::Property::COLOR_BLUE:
3756         property = &mNode->mColor;
3757         break;
3758
3759       case Dali::Actor::Property::COLOR_ALPHA:
3760       case Dali::DevelActor::Property::OPACITY:
3761       {
3762         property = &mNode->mColor;
3763         break;
3764       }
3765
3766       case Dali::Actor::Property::WORLD_COLOR:
3767         property = &mNode->mWorldColor;
3768         break;
3769
3770       case Dali::Actor::Property::WORLD_MATRIX:
3771         property = &mNode->mWorldMatrix;
3772         break;
3773
3774       default:
3775         break;
3776     }
3777   }
3778
3779   return property;
3780 }
3781
3782 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3783 {
3784   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3785
3786   if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3787   {
3788     // check whether the animatable property is registered already, if not then register one.
3789     AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3790     if( animatableProperty )
3791     {
3792       componentIndex = animatableProperty->componentIndex;
3793     }
3794   }
3795   else
3796   {
3797     switch( index )
3798     {
3799       case Dali::Actor::Property::PARENT_ORIGIN_X:
3800       case Dali::Actor::Property::ANCHOR_POINT_X:
3801       case Dali::Actor::Property::SIZE_WIDTH:
3802       case Dali::Actor::Property::POSITION_X:
3803       case Dali::Actor::Property::WORLD_POSITION_X:
3804       case Dali::Actor::Property::SCALE_X:
3805       case Dali::Actor::Property::COLOR_RED:
3806       {
3807         componentIndex = 0;
3808         break;
3809       }
3810
3811       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3812       case Dali::Actor::Property::ANCHOR_POINT_Y:
3813       case Dali::Actor::Property::SIZE_HEIGHT:
3814       case Dali::Actor::Property::POSITION_Y:
3815       case Dali::Actor::Property::WORLD_POSITION_Y:
3816       case Dali::Actor::Property::SCALE_Y:
3817       case Dali::Actor::Property::COLOR_GREEN:
3818       {
3819         componentIndex = 1;
3820         break;
3821       }
3822
3823       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3824       case Dali::Actor::Property::ANCHOR_POINT_Z:
3825       case Dali::Actor::Property::SIZE_DEPTH:
3826       case Dali::Actor::Property::POSITION_Z:
3827       case Dali::Actor::Property::WORLD_POSITION_Z:
3828       case Dali::Actor::Property::SCALE_Z:
3829       case Dali::Actor::Property::COLOR_BLUE:
3830       {
3831         componentIndex = 2;
3832         break;
3833       }
3834
3835       case Dali::Actor::Property::COLOR_ALPHA:
3836       case Dali::DevelActor::Property::OPACITY:
3837       {
3838         componentIndex = 3;
3839         break;
3840       }
3841
3842       default:
3843       {
3844         // Do nothing
3845         break;
3846       }
3847     }
3848   }
3849
3850   return componentIndex;
3851 }
3852
3853 void Actor::SetParent( Actor* parent )
3854 {
3855   if( parent )
3856   {
3857     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3858
3859     mParent = parent;
3860
3861     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3862          parent->OnStage() )
3863     {
3864       // Instruct each actor to create a corresponding node in the scene graph
3865       ConnectToStage( parent->GetHierarchyDepth() );
3866     }
3867
3868     // Resolve the name and index for the child properties if any
3869     ResolveChildProperties();
3870   }
3871   else // parent being set to NULL
3872   {
3873     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3874
3875     mParent = NULL;
3876
3877     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3878          OnStage() )
3879     {
3880       DALI_ASSERT_ALWAYS( mNode != NULL );
3881
3882       if( NULL != mNode )
3883       {
3884         // Disconnect the Node & its children from the scene-graph.
3885         DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3886       }
3887
3888       // Instruct each actor to discard pointers to the scene-graph
3889       DisconnectFromStage();
3890     }
3891   }
3892 }
3893
3894 SceneGraph::Node* Actor::CreateNode() const
3895 {
3896   return Node::New();
3897 }
3898
3899 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3900 {
3901   bool done = false;
3902   Actor* actor = dynamic_cast< Actor* >( object );
3903
3904   if( actor )
3905   {
3906     if( 0 == actionName.compare( ACTION_SHOW ) )
3907     {
3908       actor->SetVisible( true );
3909       done = true;
3910     }
3911     else if( 0 == actionName.compare( ACTION_HIDE ) )
3912     {
3913       actor->SetVisible( false );
3914       done = true;
3915     }
3916   }
3917
3918   return done;
3919 }
3920
3921 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3922 {
3923   bool valueSet = true;
3924
3925   switch( index )
3926   {
3927     case Dali::Actor::Property::PARENT_ORIGIN:
3928     {
3929       value = GetCurrentParentOrigin();
3930       break;
3931     }
3932
3933     case Dali::Actor::Property::PARENT_ORIGIN_X:
3934     {
3935       value = GetCurrentParentOrigin().x;
3936       break;
3937     }
3938
3939     case Dali::Actor::Property::PARENT_ORIGIN_Y:
3940     {
3941       value = GetCurrentParentOrigin().y;
3942       break;
3943     }
3944
3945     case Dali::Actor::Property::PARENT_ORIGIN_Z:
3946     {
3947       value = GetCurrentParentOrigin().z;
3948       break;
3949     }
3950
3951     case Dali::Actor::Property::ANCHOR_POINT:
3952     {
3953       value = GetCurrentAnchorPoint();
3954       break;
3955     }
3956
3957     case Dali::Actor::Property::ANCHOR_POINT_X:
3958     {
3959       value = GetCurrentAnchorPoint().x;
3960       break;
3961     }
3962
3963     case Dali::Actor::Property::ANCHOR_POINT_Y:
3964     {
3965       value = GetCurrentAnchorPoint().y;
3966       break;
3967     }
3968
3969     case Dali::Actor::Property::ANCHOR_POINT_Z:
3970     {
3971       value = GetCurrentAnchorPoint().z;
3972       break;
3973     }
3974
3975     case Dali::Actor::Property::SIZE:
3976     {
3977       value = GetTargetSize();
3978       break;
3979     }
3980
3981     case Dali::Actor::Property::SIZE_WIDTH:
3982     {
3983       value = GetTargetSize().width;
3984       break;
3985     }
3986
3987     case Dali::Actor::Property::SIZE_HEIGHT:
3988     {
3989       value = GetTargetSize().height;
3990       break;
3991     }
3992
3993     case Dali::Actor::Property::SIZE_DEPTH:
3994     {
3995       value = GetTargetSize().depth;
3996       break;
3997     }
3998
3999     case Dali::Actor::Property::POSITION:
4000     {
4001       value = GetTargetPosition();
4002       break;
4003     }
4004
4005     case Dali::Actor::Property::POSITION_X:
4006     {
4007       value = GetTargetPosition().x;
4008       break;
4009     }
4010
4011     case Dali::Actor::Property::POSITION_Y:
4012     {
4013       value = GetTargetPosition().y;
4014       break;
4015     }
4016
4017     case Dali::Actor::Property::POSITION_Z:
4018     {
4019       value = GetTargetPosition().z;
4020       break;
4021     }
4022
4023     case Dali::Actor::Property::ORIENTATION:
4024     {
4025       value = mTargetOrientation;
4026       break;
4027     }
4028
4029     case Dali::Actor::Property::SCALE:
4030     {
4031       value = mTargetScale;
4032       break;
4033     }
4034
4035     case Dali::Actor::Property::SCALE_X:
4036     {
4037       value = mTargetScale.x;
4038       break;
4039     }
4040
4041     case Dali::Actor::Property::SCALE_Y:
4042     {
4043       value = mTargetScale.y;
4044       break;
4045     }
4046
4047     case Dali::Actor::Property::SCALE_Z:
4048     {
4049       value = mTargetScale.z;
4050       break;
4051     }
4052
4053     case Dali::Actor::Property::VISIBLE:
4054     {
4055       value = mVisible;
4056       break;
4057     }
4058
4059     case Dali::Actor::Property::COLOR:
4060     {
4061       value = mTargetColor;
4062       break;
4063     }
4064
4065     case Dali::Actor::Property::COLOR_RED:
4066     {
4067       value = mTargetColor.r;
4068       break;
4069     }
4070
4071     case Dali::Actor::Property::COLOR_GREEN:
4072     {
4073       value = mTargetColor.g;
4074       break;
4075     }
4076
4077     case Dali::Actor::Property::COLOR_BLUE:
4078     {
4079       value = mTargetColor.b;
4080       break;
4081     }
4082
4083     case Dali::Actor::Property::COLOR_ALPHA:
4084     case Dali::DevelActor::Property::OPACITY:
4085     {
4086       value = mTargetColor.a;
4087       break;
4088     }
4089
4090     case Dali::Actor::Property::NAME:
4091     {
4092       value = GetName();
4093       break;
4094     }
4095
4096     case Dali::Actor::Property::SENSITIVE:
4097     {
4098       value = IsSensitive();
4099       break;
4100     }
4101
4102     case Dali::Actor::Property::LEAVE_REQUIRED:
4103     {
4104       value = GetLeaveRequired();
4105       break;
4106     }
4107
4108     case Dali::Actor::Property::INHERIT_POSITION:
4109     {
4110       value = IsPositionInherited();
4111       break;
4112     }
4113
4114     case Dali::Actor::Property::INHERIT_ORIENTATION:
4115     {
4116       value = IsOrientationInherited();
4117       break;
4118     }
4119
4120     case Dali::Actor::Property::INHERIT_SCALE:
4121     {
4122       value = IsScaleInherited();
4123       break;
4124     }
4125
4126     case Dali::Actor::Property::COLOR_MODE:
4127     {
4128       value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4129       break;
4130     }
4131
4132     case Dali::Actor::Property::POSITION_INHERITANCE:
4133     {
4134       value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4135       break;
4136     }
4137
4138     case Dali::Actor::Property::DRAW_MODE:
4139     {
4140       value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4141       break;
4142     }
4143
4144     case Dali::Actor::Property::SIZE_MODE_FACTOR:
4145     {
4146       value = GetSizeModeFactor();
4147       break;
4148     }
4149
4150     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4151     {
4152       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4153       break;
4154     }
4155
4156     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4157     {
4158       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4159       break;
4160     }
4161
4162     case Dali::Actor::Property::SIZE_SCALE_POLICY:
4163     {
4164       value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4165       break;
4166     }
4167
4168     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4169     {
4170       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4171       break;
4172     }
4173
4174     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4175     {
4176       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4177       break;
4178     }
4179
4180     case Dali::Actor::Property::PADDING:
4181     {
4182       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4183       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4184       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4185       break;
4186     }
4187
4188     case Dali::Actor::Property::MINIMUM_SIZE:
4189     {
4190       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4191       break;
4192     }
4193
4194     case Dali::Actor::Property::MAXIMUM_SIZE:
4195     {
4196       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4197       break;
4198     }
4199
4200     case Dali::Actor::Property::CLIPPING_MODE:
4201     {
4202       value = mClippingMode;
4203       break;
4204     }
4205
4206     case Dali::DevelActor::Property::SIBLING_ORDER:
4207     {
4208       value = static_cast<int>( GetSiblingOrder() );
4209       break;
4210     }
4211
4212     case Dali::DevelActor::Property::SCREEN_POSITION:
4213     {
4214       value = GetCurrentScreenPosition();
4215       break;
4216     }
4217
4218     case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4219     {
4220       value = mPositionUsesAnchorPoint;
4221       break;
4222     }
4223
4224     case Dali::Actor::Property::LAYOUT_DIRECTION:
4225     {
4226       value = mLayoutDirection;
4227       break;
4228     }
4229
4230     case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
4231     {
4232       value = IsLayoutDirectionInherited();
4233       break;
4234     }
4235
4236     default:
4237     {
4238       // Must be a scene-graph only property
4239       valueSet = false;
4240       break;
4241     }
4242   }
4243
4244   return valueSet;
4245 }
4246
4247 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value  ) const
4248 {
4249   bool valueSet = true;
4250
4251   switch( index )
4252   {
4253     case Dali::Actor::Property::SIZE:
4254     {
4255       value = GetCurrentSize();
4256       break;
4257     }
4258
4259     case Dali::Actor::Property::SIZE_WIDTH:
4260     {
4261       value = GetCurrentSize().width;
4262       break;
4263     }
4264
4265     case Dali::Actor::Property::SIZE_HEIGHT:
4266     {
4267       value = GetCurrentSize().height;
4268       break;
4269     }
4270
4271     case Dali::Actor::Property::SIZE_DEPTH:
4272     {
4273       value = GetCurrentSize().depth;
4274       break;
4275     }
4276
4277     case Dali::Actor::Property::POSITION:
4278     {
4279       value = GetCurrentPosition();
4280       break;
4281     }
4282
4283     case Dali::Actor::Property::POSITION_X:
4284     {
4285       value = GetCurrentPosition().x;
4286       break;
4287     }
4288
4289     case Dali::Actor::Property::POSITION_Y:
4290     {
4291       value = GetCurrentPosition().y;
4292       break;
4293     }
4294
4295     case Dali::Actor::Property::POSITION_Z:
4296     {
4297       value = GetCurrentPosition().z;
4298       break;
4299     }
4300
4301     case Dali::Actor::Property::WORLD_POSITION:
4302     {
4303       value = GetCurrentWorldPosition();
4304       break;
4305     }
4306
4307     case Dali::Actor::Property::WORLD_POSITION_X:
4308     {
4309       value = GetCurrentWorldPosition().x;
4310       break;
4311     }
4312
4313     case Dali::Actor::Property::WORLD_POSITION_Y:
4314     {
4315       value = GetCurrentWorldPosition().y;
4316       break;
4317     }
4318
4319     case Dali::Actor::Property::WORLD_POSITION_Z:
4320     {
4321       value = GetCurrentWorldPosition().z;
4322       break;
4323     }
4324
4325     case Dali::Actor::Property::ORIENTATION:
4326     {
4327       value = GetCurrentOrientation();
4328       break;
4329     }
4330
4331     case Dali::Actor::Property::WORLD_ORIENTATION:
4332     {
4333       value = GetCurrentWorldOrientation();
4334       break;
4335     }
4336
4337     case Dali::Actor::Property::SCALE:
4338     {
4339       value = GetCurrentScale();
4340       break;
4341     }
4342
4343     case Dali::Actor::Property::SCALE_X:
4344     {
4345       value = GetCurrentScale().x;
4346       break;
4347     }
4348
4349     case Dali::Actor::Property::SCALE_Y:
4350     {
4351       value = GetCurrentScale().y;
4352       break;
4353     }
4354
4355     case Dali::Actor::Property::SCALE_Z:
4356     {
4357       value = GetCurrentScale().z;
4358       break;
4359     }
4360
4361     case Dali::Actor::Property::WORLD_SCALE:
4362     {
4363       value = GetCurrentWorldScale();
4364       break;
4365     }
4366
4367     case Dali::Actor::Property::COLOR:
4368     {
4369       value = GetCurrentColor();
4370       break;
4371     }
4372
4373     case Dali::Actor::Property::COLOR_RED:
4374     {
4375       value = GetCurrentColor().r;
4376       break;
4377     }
4378
4379     case Dali::Actor::Property::COLOR_GREEN:
4380     {
4381       value = GetCurrentColor().g;
4382       break;
4383     }
4384
4385     case Dali::Actor::Property::COLOR_BLUE:
4386     {
4387       value = GetCurrentColor().b;
4388       break;
4389     }
4390
4391     case Dali::Actor::Property::COLOR_ALPHA:
4392     case Dali::DevelActor::Property::OPACITY:
4393     {
4394       value = GetCurrentColor().a;
4395       break;
4396     }
4397
4398     case Dali::Actor::Property::WORLD_COLOR:
4399     {
4400       value = GetCurrentWorldColor();
4401       break;
4402     }
4403
4404     case Dali::Actor::Property::WORLD_MATRIX:
4405     {
4406       value = GetCurrentWorldMatrix();
4407       break;
4408     }
4409
4410     case Dali::Actor::Property::VISIBLE:
4411     {
4412       value = IsVisible();
4413       break;
4414     }
4415
4416     default:
4417     {
4418       // Must be an event-side only property
4419       valueSet = false;
4420       break;
4421     }
4422   }
4423
4424   return valueSet;
4425 }
4426
4427 void Actor::EnsureRelayoutData()
4428 {
4429   // Assign relayout data.
4430   if( !mRelayoutData )
4431   {
4432     mRelayoutData = new RelayoutData();
4433   }
4434 }
4435
4436 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4437 {
4438   // Check if actor is dependent on parent
4439   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4440   {
4441     if( ( dimension & ( 1 << i ) ) )
4442     {
4443       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4444       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4445       {
4446         return true;
4447       }
4448     }
4449   }
4450
4451   return false;
4452 }
4453
4454 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4455 {
4456   // Check if actor is dependent on children
4457   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4458   {
4459     if( ( dimension & ( 1 << i ) ) )
4460     {
4461       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4462       switch( resizePolicy )
4463       {
4464         case ResizePolicy::FIT_TO_CHILDREN:
4465         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
4466         {
4467           return true;
4468         }
4469
4470         default:
4471         {
4472           break;
4473         }
4474       }
4475     }
4476   }
4477
4478   return false;
4479 }
4480
4481 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4482 {
4483   return Actor::RelayoutDependentOnChildren( dimension );
4484 }
4485
4486 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4487 {
4488   // Check each possible dimension and see if it is dependent on the input one
4489   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4490   {
4491     if( dimension & ( 1 << i ) )
4492     {
4493       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4494     }
4495   }
4496
4497   return false;
4498 }
4499
4500 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4501 {
4502   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4503   {
4504     if( dimension & ( 1 << i ) )
4505     {
4506       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4507     }
4508   }
4509 }
4510
4511 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4512 {
4513   // If more than one dimension is requested, just return the first one found
4514   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4515   {
4516     if( ( dimension & ( 1 << i ) ) )
4517     {
4518       return mRelayoutData->negotiatedDimensions[ i ];
4519     }
4520   }
4521
4522   return 0.0f;   // Default
4523 }
4524
4525 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4526 {
4527   EnsureRelayoutData();
4528
4529   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4530   {
4531     if( dimension & ( 1 << i ) )
4532     {
4533       mRelayoutData->dimensionPadding[ i ] = padding;
4534     }
4535   }
4536 }
4537
4538 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4539 {
4540   if ( mRelayoutData )
4541   {
4542     // If more than one dimension is requested, just return the first one found
4543     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4544     {
4545       if( ( dimension & ( 1 << i ) ) )
4546       {
4547         return mRelayoutData->dimensionPadding[ i ];
4548       }
4549     }
4550   }
4551
4552   return GetDefaultDimensionPadding();
4553 }
4554
4555 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4556 {
4557   EnsureRelayoutData();
4558
4559   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4560   {
4561     if( dimension & ( 1 << i ) )
4562     {
4563       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4564     }
4565   }
4566 }
4567
4568 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4569 {
4570   if ( mRelayoutData )
4571   {
4572     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4573     {
4574       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4575       {
4576         return true;
4577       }
4578     }
4579   }
4580
4581   return false;
4582 }
4583
4584 float Actor::GetHeightForWidthBase( float width )
4585 {
4586   float height = 0.0f;
4587
4588   const Vector3 naturalSize = GetNaturalSize();
4589   if( naturalSize.width > 0.0f )
4590   {
4591     height = naturalSize.height * width / naturalSize.width;
4592   }
4593   else // we treat 0 as 1:1 aspect ratio
4594   {
4595     height = width;
4596   }
4597
4598   return height;
4599 }
4600
4601 float Actor::GetWidthForHeightBase( float height )
4602 {
4603   float width = 0.0f;
4604
4605   const Vector3 naturalSize = GetNaturalSize();
4606   if( naturalSize.height > 0.0f )
4607   {
4608     width = naturalSize.width * height / naturalSize.height;
4609   }
4610   else // we treat 0 as 1:1 aspect ratio
4611   {
4612     width = height;
4613   }
4614
4615   return width;
4616 }
4617
4618 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4619 {
4620   // Fill to parent, taking size mode factor into account
4621   switch( child.GetResizePolicy( dimension ) )
4622   {
4623     case ResizePolicy::FILL_TO_PARENT:
4624     {
4625       return GetLatestSize( dimension );
4626     }
4627
4628     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4629     {
4630       return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4631     }
4632
4633     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4634     {
4635       return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4636     }
4637
4638     default:
4639     {
4640       return GetLatestSize( dimension );
4641     }
4642   }
4643 }
4644
4645 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4646 {
4647   // Can be overridden in derived class
4648   return CalculateChildSizeBase( child, dimension );
4649 }
4650
4651 float Actor::GetHeightForWidth( float width )
4652 {
4653   // Can be overridden in derived class
4654   return GetHeightForWidthBase( width );
4655 }
4656
4657 float Actor::GetWidthForHeight( float height )
4658 {
4659   // Can be overridden in derived class
4660   return GetWidthForHeightBase( height );
4661 }
4662
4663 float Actor::GetLatestSize( Dimension::Type dimension ) const
4664 {
4665   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4666 }
4667
4668 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4669 {
4670   Vector2 padding = GetPadding( dimension );
4671
4672   return GetLatestSize( dimension ) + padding.x + padding.y;
4673 }
4674
4675 float Actor::NegotiateFromParent( Dimension::Type dimension )
4676 {
4677   Actor* parent = GetParent();
4678   if( parent )
4679   {
4680     Vector2 padding( GetPadding( dimension ) );
4681     Vector2 parentPadding( parent->GetPadding( dimension ) );
4682     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4683   }
4684
4685   return 0.0f;
4686 }
4687
4688 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4689 {
4690   float maxDimensionPoint = 0.0f;
4691
4692   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4693   {
4694     ActorPtr child = GetChildAt( i );
4695
4696     if( !child->RelayoutDependentOnParent( dimension ) )
4697     {
4698       // Calculate the min and max points that the children range across
4699       float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4700       float dimensionSize = child->GetRelayoutSize( dimension );
4701       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4702     }
4703   }
4704
4705   return maxDimensionPoint;
4706 }
4707
4708 float Actor::GetSize( Dimension::Type dimension ) const
4709 {
4710   return GetDimensionValue( mTargetSize, dimension );
4711 }
4712
4713 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4714 {
4715   return GetDimensionValue( GetNaturalSize(), dimension );
4716 }
4717
4718 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4719 {
4720   switch( GetResizePolicy( dimension ) )
4721   {
4722     case ResizePolicy::USE_NATURAL_SIZE:
4723     {
4724       return GetNaturalSize( dimension );
4725     }
4726
4727     case ResizePolicy::FIXED:
4728     {
4729       return GetDimensionValue( GetPreferredSize(), dimension );
4730     }
4731
4732     case ResizePolicy::USE_ASSIGNED_SIZE:
4733     {
4734       return GetDimensionValue( maximumSize, dimension );
4735     }
4736
4737     case ResizePolicy::FILL_TO_PARENT:
4738     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4739     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4740     {
4741       return NegotiateFromParent( dimension );
4742     }
4743
4744     case ResizePolicy::FIT_TO_CHILDREN:
4745     {
4746       return NegotiateFromChildren( dimension );
4747     }
4748
4749     case ResizePolicy::DIMENSION_DEPENDENCY:
4750     {
4751       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4752
4753       // Custom rules
4754       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4755       {
4756         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4757       }
4758
4759       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4760       {
4761         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4762       }
4763
4764       break;
4765     }
4766
4767     default:
4768     {
4769       break;
4770     }
4771   }
4772
4773   return 0.0f;  // Default
4774 }
4775
4776 float Actor::ClampDimension( float size, Dimension::Type dimension )
4777 {
4778   const float minSize = GetMinimumSize( dimension );
4779   const float maxSize = GetMaximumSize( dimension );
4780
4781   return std::max( minSize, std::min( size, maxSize ) );
4782 }
4783
4784 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4785 {
4786   // Check if it needs to be negotiated
4787   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4788   {
4789     // Check that we havn't gotten into an infinite loop
4790     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4791     bool recursionFound = false;
4792     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4793     {
4794       if( *it == searchActor )
4795       {
4796         recursionFound = true;
4797         break;
4798       }
4799     }
4800
4801     if( !recursionFound )
4802     {
4803       // Record the path that we have taken
4804       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4805
4806       // Dimension dependency check
4807       for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4808       {
4809         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4810
4811         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4812         {
4813           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4814         }
4815       }
4816
4817       // Parent dependency check
4818       Actor* parent = GetParent();
4819       if( parent && RelayoutDependentOnParent( dimension ) )
4820       {
4821         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4822       }
4823
4824       // Children dependency check
4825       if( RelayoutDependentOnChildren( dimension ) )
4826       {
4827         for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4828         {
4829           ActorPtr child = GetChildAt( i );
4830
4831           // Only relayout child first if it is not dependent on this actor
4832           if( !child->RelayoutDependentOnParent( dimension ) )
4833           {
4834             child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4835           }
4836         }
4837       }
4838
4839       // For deriving classes
4840       OnCalculateRelayoutSize( dimension );
4841
4842       // All dependencies checked, calculate the size and set negotiated flag
4843       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4844
4845       SetNegotiatedDimension( newSize, dimension );
4846       SetLayoutNegotiated( true, dimension );
4847
4848       // For deriving classes
4849       OnLayoutNegotiated( newSize, dimension );
4850
4851       // This actor has been successfully processed, pop it off the recursion stack
4852       recursionStack.pop_back();
4853     }
4854     else
4855     {
4856       // TODO: Break infinite loop
4857       SetLayoutNegotiated( true, dimension );
4858     }
4859   }
4860 }
4861
4862 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4863 {
4864   // Negotiate all dimensions that require it
4865   ActorDimensionStack recursionStack;
4866
4867   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4868   {
4869     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4870
4871     // Negotiate
4872     NegotiateDimension( dimension, allocatedSize, recursionStack );
4873   }
4874 }
4875
4876 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4877 {
4878   switch( mRelayoutData->sizeSetPolicy )
4879   {
4880     case SizeScalePolicy::USE_SIZE_SET:
4881     {
4882       return size;
4883     }
4884
4885     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4886     {
4887       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4888       const Vector3 naturalSize = GetNaturalSize();
4889       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4890       {
4891         const float sizeRatio = size.width / size.height;
4892         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4893
4894         if( naturalSizeRatio < sizeRatio )
4895         {
4896           return Vector2( naturalSizeRatio * size.height, size.height );
4897         }
4898         else if( naturalSizeRatio > sizeRatio )
4899         {
4900           return Vector2( size.width, size.width / naturalSizeRatio );
4901         }
4902         else
4903         {
4904           return size;
4905         }
4906       }
4907
4908       break;
4909     }
4910
4911     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4912     {
4913       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4914       const Vector3 naturalSize = GetNaturalSize();
4915       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4916       {
4917         const float sizeRatio = size.width / size.height;
4918         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4919
4920         if( naturalSizeRatio < sizeRatio )
4921         {
4922           return Vector2( size.width, size.width / naturalSizeRatio );
4923         }
4924         else if( naturalSizeRatio > sizeRatio )
4925         {
4926           return Vector2( naturalSizeRatio * size.height, size.height );
4927         }
4928         else
4929         {
4930           return size;
4931         }
4932       }
4933       break;
4934     }
4935
4936     default:
4937     {
4938       break;
4939     }
4940   }
4941
4942   return size;
4943 }
4944
4945 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4946 {
4947   // Do the set actor size
4948   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4949
4950   // Adjust for size set policy
4951   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4952
4953   // Lock the flag to stop recursive relayouts on set size
4954   mRelayoutData->insideRelayout = true;
4955   SetSize( negotiatedSize );
4956   mRelayoutData->insideRelayout = false;
4957
4958   // Clear flags for all dimensions
4959   SetLayoutDirty( false );
4960
4961   // Give deriving classes a chance to respond
4962   OnRelayout( negotiatedSize, container );
4963
4964   if( !mOnRelayoutSignal.Empty() )
4965   {
4966     Dali::Actor handle( this );
4967     mOnRelayoutSignal.Emit( handle );
4968   }
4969 }
4970
4971 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4972 {
4973   // Force a size negotiation for actors that has assigned size during relayout
4974   // This is required as otherwise the flags that force a relayout will not
4975   // necessarilly be set. This will occur if the actor has already been laid out.
4976   // The dirty flags are then cleared. Then if the actor is added back into the
4977   // relayout container afterwards, the dirty flags would still be clear...
4978   // causing a relayout to be skipped. Here we force any actors added to the
4979   // container to be relayed out.
4980   DALI_LOG_TIMER_START( NegSizeTimer1 );
4981
4982   if( GetUseAssignedSize(Dimension::WIDTH ) )
4983   {
4984     SetLayoutNegotiated( false, Dimension::WIDTH );
4985   }
4986   if( GetUseAssignedSize( Dimension::HEIGHT ) )
4987   {
4988     SetLayoutNegotiated( false, Dimension::HEIGHT );
4989   }
4990
4991   // Do the negotiation
4992   NegotiateDimensions( allocatedSize );
4993
4994   // Set the actor size
4995   SetNegotiatedSize( container );
4996
4997   // Negotiate down to children
4998   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4999   {
5000     ActorPtr child = GetChildAt( i );
5001
5002     // Forces children that have already been laid out to be relayed out
5003     // if they have assigned size during relayout.
5004     if( child->GetUseAssignedSize(Dimension::WIDTH) )
5005     {
5006       child->SetLayoutNegotiated(false, Dimension::WIDTH);
5007       child->SetLayoutDirty(true, Dimension::WIDTH);
5008     }
5009
5010     if( child->GetUseAssignedSize(Dimension::HEIGHT) )
5011     {
5012       child->SetLayoutNegotiated(false, Dimension::HEIGHT);
5013       child->SetLayoutDirty(true, Dimension::HEIGHT);
5014     }
5015
5016     // Only relayout if required
5017     if( child->RelayoutRequired() )
5018     {
5019       container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
5020     }
5021   }
5022   DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
5023 }
5024
5025 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
5026 {
5027   if( mRelayoutData )
5028   {
5029     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5030     {
5031       if( dimension & ( 1 << i ) )
5032       {
5033         mRelayoutData->useAssignedSize[ i ] = use;
5034       }
5035     }
5036   }
5037 }
5038
5039 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
5040 {
5041   if ( mRelayoutData )
5042   {
5043     // If more than one dimension is requested, just return the first one found
5044     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5045     {
5046       if( dimension & ( 1 << i ) )
5047       {
5048         return mRelayoutData->useAssignedSize[ i ];
5049       }
5050     }
5051   }
5052
5053   return false;
5054 }
5055
5056 void Actor::RelayoutRequest( Dimension::Type dimension )
5057 {
5058   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
5059   if( relayoutController )
5060   {
5061     Dali::Actor self( this );
5062     relayoutController->RequestRelayout( self, dimension );
5063   }
5064 }
5065
5066 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
5067 {
5068 }
5069
5070 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
5071 {
5072 }
5073
5074 void Actor::SetPreferredSize( const Vector2& size )
5075 {
5076   EnsureRelayoutData();
5077
5078   if( size.width > 0.0f )
5079   {
5080     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
5081   }
5082
5083   if( size.height > 0.0f )
5084   {
5085     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
5086   }
5087
5088   mRelayoutData->preferredSize = size;
5089
5090   RelayoutRequest();
5091 }
5092
5093 Vector2 Actor::GetPreferredSize() const
5094 {
5095   if ( mRelayoutData )
5096   {
5097     return Vector2( mRelayoutData->preferredSize );
5098   }
5099
5100   return GetDefaultPreferredSize();
5101 }
5102
5103 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
5104 {
5105   EnsureRelayoutData();
5106
5107   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5108   {
5109     if( dimension & ( 1 << i ) )
5110     {
5111       mRelayoutData->minimumSize[ i ] = size;
5112     }
5113   }
5114
5115   RelayoutRequest();
5116 }
5117
5118 float Actor::GetMinimumSize( Dimension::Type dimension ) const
5119 {
5120   if ( mRelayoutData )
5121   {
5122     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5123     {
5124       if( dimension & ( 1 << i ) )
5125       {
5126         return mRelayoutData->minimumSize[ i ];
5127       }
5128     }
5129   }
5130
5131   return 0.0f;  // Default
5132 }
5133
5134 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5135 {
5136   EnsureRelayoutData();
5137
5138   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5139   {
5140     if( dimension & ( 1 << i ) )
5141     {
5142       mRelayoutData->maximumSize[ i ] = size;
5143     }
5144   }
5145
5146   RelayoutRequest();
5147 }
5148
5149 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5150 {
5151   if ( mRelayoutData )
5152   {
5153     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5154     {
5155       if( dimension & ( 1 << i ) )
5156       {
5157         return mRelayoutData->maximumSize[ i ];
5158       }
5159     }
5160   }
5161
5162   return FLT_MAX;  // Default
5163 }
5164
5165 Object* Actor::GetParentObject() const
5166 {
5167   return mParent;
5168 }
5169
5170 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5171 {
5172   if( mVisible != visible )
5173   {
5174     if( sendMessage == SendMessage::TRUE && NULL != mNode )
5175     {
5176       // mNode is being used in a separate thread; queue a message to set the value & base value
5177       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5178     }
5179
5180     mVisible = visible;
5181
5182     // Emit the signal on this actor and all its children
5183     EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5184   }
5185 }
5186
5187 void Actor::SetSiblingOrder( unsigned int order )
5188 {
5189   if ( mParent )
5190   {
5191     ActorContainer& siblings = *(mParent->mChildren);
5192     unsigned int currentOrder = GetSiblingOrder();
5193
5194     if( order != currentOrder )
5195     {
5196       if( order == 0 )
5197       {
5198         LowerToBottom();
5199       }
5200       else if( order < siblings.size() -1 )
5201       {
5202         if( order > currentOrder )
5203         {
5204           RaiseAbove( *siblings[order] );
5205         }
5206         else
5207         {
5208           LowerBelow( *siblings[order] );
5209         }
5210       }
5211       else
5212       {
5213         RaiseToTop();
5214       }
5215     }
5216   }
5217 }
5218
5219 unsigned int Actor::GetSiblingOrder() const
5220 {
5221   unsigned int order = 0;
5222
5223   if ( mParent )
5224   {
5225     ActorContainer& siblings = *(mParent->mChildren);
5226     for( size_t i=0; i<siblings.size(); ++i )
5227     {
5228       if( siblings[i] == this )
5229       {
5230         order = i;
5231         break;
5232       }
5233     }
5234   }
5235
5236   return order;
5237 }
5238
5239 void Actor::RequestRebuildDepthTree()
5240 {
5241   if( mIsOnStage )
5242   {
5243     StagePtr stage = Stage::GetCurrent();
5244     if( stage )
5245     {
5246       stage->RequestRebuildDepthTree();
5247     }
5248   }
5249 }
5250
5251 void Actor::Raise()
5252 {
5253   if ( mParent )
5254   {
5255     ActorContainer& siblings = *(mParent->mChildren);
5256     if( siblings.back() != this ) // If not already at end
5257     {
5258       for( size_t i=0; i<siblings.size(); ++i )
5259       {
5260         if( siblings[i] == this )
5261         {
5262           // Swap with next
5263           ActorPtr next = siblings[i+1];
5264           siblings[i+1] = this;
5265           siblings[i] = next;
5266           break;
5267         }
5268       }
5269     }
5270     mParent->mChildOrderChangedSignal.Emit();
5271     RequestRebuildDepthTree();
5272   }
5273   else
5274   {
5275     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5276   }
5277 }
5278
5279 void Actor::Lower()
5280 {
5281   if ( mParent )
5282   {
5283     ActorContainer& siblings = *(mParent->mChildren);
5284     if( siblings.front() != this ) // If not already at beginning
5285     {
5286       for( size_t i=1; i<siblings.size(); ++i )
5287       {
5288         if( siblings[i] == this )
5289         {
5290           // Swap with previous
5291           ActorPtr previous = siblings[i-1];
5292           siblings[i-1] = this;
5293           siblings[i] = previous;
5294           break;
5295         }
5296       }
5297     }
5298     mParent->mChildOrderChangedSignal.Emit();
5299     RequestRebuildDepthTree();
5300   }
5301   else
5302   {
5303     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5304   }
5305 }
5306
5307 void Actor::RaiseToTop()
5308 {
5309   if ( mParent )
5310   {
5311     ActorContainer& siblings = *(mParent->mChildren);
5312     if( siblings.back() != this ) // If not already at end
5313     {
5314       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5315       if( iter != siblings.end() )
5316       {
5317         siblings.erase(iter);
5318         siblings.push_back(ActorPtr(this));
5319       }
5320     }
5321     mParent->mChildOrderChangedSignal.Emit();
5322     RequestRebuildDepthTree();
5323   }
5324   else
5325   {
5326     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5327   }
5328 }
5329
5330 void Actor::LowerToBottom()
5331 {
5332   if ( mParent )
5333   {
5334     ActorContainer& siblings = *(mParent->mChildren);
5335     if( siblings.front() != this ) // If not already at bottom,
5336     {
5337       ActorPtr thisPtr(this); // ensure this actor remains referenced.
5338
5339       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5340       if( iter != siblings.end() )
5341       {
5342         siblings.erase(iter);
5343         siblings.insert(siblings.begin(), thisPtr);
5344       }
5345     }
5346     mParent->mChildOrderChangedSignal.Emit();
5347     RequestRebuildDepthTree();
5348   }
5349   else
5350   {
5351     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5352   }
5353 }
5354
5355 void Actor::RaiseAbove( Internal::Actor& target )
5356 {
5357   if ( mParent )
5358   {
5359     ActorContainer& siblings = *(mParent->mChildren);
5360     if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5361     {
5362       ActorPtr thisPtr(this); // ensure this actor remains referenced.
5363
5364       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5365       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5366       if( thisIter < targetIter )
5367       {
5368         siblings.erase(thisIter);
5369         // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5370         // invalidate thisIter)
5371         targetIter = std::find( siblings.begin(), siblings.end(), &target );
5372         ++targetIter;
5373         siblings.insert(targetIter, thisPtr);
5374       }
5375
5376       mParent->mChildOrderChangedSignal.Emit();
5377       RequestRebuildDepthTree();
5378     }
5379   }
5380   else
5381   {
5382     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5383   }
5384 }
5385
5386 void Actor::LowerBelow( Internal::Actor& target )
5387 {
5388   if ( mParent )
5389   {
5390     ActorContainer& siblings = *(mParent->mChildren);
5391     if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5392     {
5393       ActorPtr thisPtr(this); // ensure this actor remains referenced.
5394
5395       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5396       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5397
5398       if( thisIter > targetIter )
5399       {
5400         siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5401         siblings.insert(targetIter, thisPtr);
5402       }
5403
5404       mParent->mChildOrderChangedSignal.Emit();
5405       RequestRebuildDepthTree();
5406     }
5407   }
5408   else
5409   {
5410     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5411   }
5412 }
5413
5414 void Actor::SetInheritLayoutDirection( bool inherit )
5415 {
5416   if( mInheritLayoutDirection != inherit )
5417   {
5418     mInheritLayoutDirection = inherit;
5419
5420     if( inherit && mParent )
5421     {
5422       InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5423     }
5424   }
5425 }
5426
5427 bool Actor::IsLayoutDirectionInherited() const
5428 {
5429   return mInheritLayoutDirection;
5430 }
5431
5432 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5433 {
5434   if( actor && ( actor->mInheritLayoutDirection || set ) )
5435   {
5436     if( actor->mLayoutDirection != direction)
5437     {
5438       actor->mLayoutDirection = direction;
5439       actor->EmitLayoutDirectionChangedSignal( direction );
5440       actor->RelayoutRequest();
5441     }
5442
5443     if( actor->GetChildCount() > 0 )
5444     {
5445       ActorContainer& children = actor->GetChildrenInternal();
5446       for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5447       {
5448         InheritLayoutDirectionRecursively( *iter, direction );
5449       }
5450     }
5451   }
5452 }
5453
5454 } // namespace Internal
5455
5456 } // namespace Dali