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