Actor size property should return preferred size if size is fixed as set by SetSize
[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   ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1299   ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1300
1301   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1302   {
1303     if( dimension & ( 1 << i ) )
1304     {
1305       mRelayoutData->resizePolicies[ i ] = policy;
1306     }
1307   }
1308
1309   if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1310   {
1311     if( dimension & Dimension::WIDTH )
1312     {
1313       SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1314     }
1315
1316     if( dimension & Dimension::HEIGHT )
1317     {
1318       SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1319     }
1320   }
1321
1322   // If calling SetResizePolicy, assume we want relayout enabled
1323   SetRelayoutEnabled( true );
1324
1325   // If the resize policy is set to be FIXED, the preferred size
1326   // should be overrided by the target size. Otherwise the target
1327   // size should be overrided by the preferred size.
1328
1329   if( dimension & Dimension::WIDTH )
1330   {
1331     if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1332     {
1333       mRelayoutData->preferredSize.width = mTargetSize.width;
1334     }
1335     else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1336     {
1337       mTargetSize.width = mRelayoutData->preferredSize.width;
1338     }
1339   }
1340
1341   if( dimension & Dimension::HEIGHT )
1342   {
1343     if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1344     {
1345       mRelayoutData->preferredSize.height = mTargetSize.height;
1346     }
1347     else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1348     {
1349       mTargetSize.height = mRelayoutData->preferredSize.height;
1350     }
1351   }
1352
1353   OnSetResizePolicy( policy, dimension );
1354
1355   // Trigger relayout on this control
1356   RelayoutRequest();
1357 }
1358
1359 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1360 {
1361   if ( mRelayoutData )
1362   {
1363     // If more than one dimension is requested, just return the first one found
1364     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1365     {
1366       if( ( dimension & ( 1 << i ) ) )
1367       {
1368         return mRelayoutData->resizePolicies[ i ];
1369       }
1370     }
1371   }
1372
1373   return ResizePolicy::DEFAULT;
1374 }
1375
1376 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1377 {
1378   EnsureRelayoutData();
1379
1380   mRelayoutData->sizeSetPolicy = policy;
1381 }
1382
1383 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1384 {
1385   if ( mRelayoutData )
1386   {
1387     return mRelayoutData->sizeSetPolicy;
1388   }
1389
1390   return DEFAULT_SIZE_SCALE_POLICY;
1391 }
1392
1393 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1394 {
1395   EnsureRelayoutData();
1396
1397   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1398   {
1399     if( dimension & ( 1 << i ) )
1400     {
1401       mRelayoutData->dimensionDependencies[ i ] = dependency;
1402     }
1403   }
1404 }
1405
1406 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1407 {
1408   if ( mRelayoutData )
1409   {
1410     // If more than one dimension is requested, just return the first one found
1411     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1412     {
1413       if( ( dimension & ( 1 << i ) ) )
1414       {
1415         return mRelayoutData->dimensionDependencies[ i ];
1416       }
1417     }
1418   }
1419
1420   return Dimension::ALL_DIMENSIONS;   // Default
1421 }
1422
1423 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1424 {
1425   // If relayout data has not been allocated yet and the client is requesting
1426   // to disable it, do nothing
1427   if( mRelayoutData || relayoutEnabled )
1428   {
1429     EnsureRelayoutData();
1430
1431     DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1432
1433     mRelayoutData->relayoutEnabled = relayoutEnabled;
1434   }
1435 }
1436
1437 bool Actor::IsRelayoutEnabled() const
1438 {
1439   // Assume that if relayout data has not been allocated yet then
1440   // relayout is disabled
1441   return mRelayoutData && mRelayoutData->relayoutEnabled;
1442 }
1443
1444 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1445 {
1446   EnsureRelayoutData();
1447
1448   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1449   {
1450     if( dimension & ( 1 << i ) )
1451     {
1452       mRelayoutData->dimensionDirty[ i ] = dirty;
1453     }
1454   }
1455 }
1456
1457 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1458 {
1459   if ( mRelayoutData )
1460   {
1461     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1462     {
1463       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1464       {
1465         return true;
1466       }
1467     }
1468   }
1469
1470   return false;
1471 }
1472
1473 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1474 {
1475   return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1476 }
1477
1478 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1479 {
1480   return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1481 }
1482
1483 unsigned int Actor::AddRenderer( Renderer& renderer )
1484 {
1485   if( !mRenderers )
1486   {
1487     mRenderers = new RendererContainer;
1488   }
1489
1490   unsigned int index = mRenderers->size();
1491   RendererPtr rendererPtr = RendererPtr( &renderer );
1492   mRenderers->push_back( rendererPtr );
1493   AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1494   return index;
1495 }
1496
1497 unsigned int Actor::GetRendererCount() const
1498 {
1499   unsigned int rendererCount(0);
1500   if( mRenderers )
1501   {
1502     rendererCount = mRenderers->size();
1503   }
1504
1505   return rendererCount;
1506 }
1507
1508 RendererPtr Actor::GetRendererAt( unsigned int index )
1509 {
1510   RendererPtr renderer;
1511   if( index < GetRendererCount() )
1512   {
1513     renderer = ( *mRenderers )[ index ];
1514   }
1515
1516   return renderer;
1517 }
1518
1519 void Actor::RemoveRenderer( Renderer& renderer )
1520 {
1521   if( mRenderers )
1522   {
1523     RendererIter end = mRenderers->end();
1524     for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1525     {
1526       if( (*iter).Get() == &renderer )
1527       {
1528         mRenderers->erase( iter );
1529         RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1530         break;
1531       }
1532     }
1533   }
1534 }
1535
1536 void Actor::RemoveRenderer( unsigned int index )
1537 {
1538   if( index < GetRendererCount() )
1539   {
1540     RendererPtr renderer = ( *mRenderers )[ index ];
1541     RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1542     mRenderers->erase( mRenderers->begin()+index );
1543   }
1544 }
1545
1546 bool Actor::IsOverlay() const
1547 {
1548   return ( DrawMode::OVERLAY_2D == mDrawMode );
1549 }
1550
1551 void Actor::SetDrawMode( DrawMode::Type drawMode )
1552 {
1553   // this flag is not animatable so keep the value
1554   mDrawMode = drawMode;
1555   if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1556   {
1557     // mNode is being used in a separate thread; queue a message to set the value
1558     SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1559   }
1560 }
1561
1562 DrawMode::Type Actor::GetDrawMode() const
1563 {
1564   return mDrawMode;
1565 }
1566
1567 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1568 {
1569   // only valid when on-stage
1570   StagePtr stage = Stage::GetCurrent();
1571   if( stage && OnStage() )
1572   {
1573     const RenderTaskList& taskList = stage->GetRenderTaskList();
1574
1575     Vector2 converted( screenX, screenY );
1576
1577     // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1578     const int taskCount = taskList.GetTaskCount();
1579     for( int i = taskCount - 1; i >= 0; --i )
1580     {
1581       Dali::RenderTask task = taskList.GetTask( i );
1582       if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1583       {
1584         // found a task where this conversion was ok so return
1585         return true;
1586       }
1587     }
1588   }
1589   return false;
1590 }
1591
1592 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1593 {
1594   bool retval = false;
1595   // only valid when on-stage
1596   if( OnStage() )
1597   {
1598     CameraActor* camera = renderTask.GetCameraActor();
1599     if( camera )
1600     {
1601       Viewport viewport;
1602       renderTask.GetViewport( viewport );
1603
1604       // need to translate coordinates to render tasks coordinate space
1605       Vector2 converted( screenX, screenY );
1606       if( renderTask.TranslateCoordinates( converted ) )
1607       {
1608         retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1609       }
1610     }
1611   }
1612   return retval;
1613 }
1614
1615 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1616 {
1617   // Early-out if mNode is NULL
1618   if( !OnStage() )
1619   {
1620     return false;
1621   }
1622
1623   // Get the ModelView matrix
1624   Matrix modelView;
1625   Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1626
1627   // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1628   Matrix invertedMvp( false/*don't init*/);
1629   Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1630   bool success = invertedMvp.Invert();
1631
1632   // Convert to GL coordinates
1633   Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1634
1635   Vector4 nearPos;
1636   if( success )
1637   {
1638     success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1639   }
1640
1641   Vector4 farPos;
1642   if( success )
1643   {
1644     screenPos.z = 1.0f;
1645     success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1646   }
1647
1648   if( success )
1649   {
1650     Vector4 local;
1651     if( XyPlaneIntersect( nearPos, farPos, local ) )
1652     {
1653       Vector3 size = GetCurrentSize();
1654       localX = local.x + size.x * 0.5f;
1655       localY = local.y + size.y * 0.5f;
1656     }
1657     else
1658     {
1659       success = false;
1660     }
1661   }
1662
1663   return success;
1664 }
1665
1666 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1667 {
1668   /*
1669    http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1670
1671    Mathematical Formulation
1672
1673    Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1674
1675    ( p - c ) dot ( p - c ) = r^2
1676
1677    Given a ray with a point of origin 'o', and a direction vector 'd':
1678
1679    ray(t) = o + td, t >= 0
1680
1681    we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1682
1683    (o + td - c ) dot ( o + td - c ) = r^2
1684
1685    To solve for t we first expand the above into a more recognisable quadratic equation form
1686
1687    ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1688
1689    or
1690
1691    At2 + Bt + C = 0
1692
1693    where
1694
1695    A = d dot d
1696    B = 2( o - c ) dot d
1697    C = ( o - c ) dot ( o - c ) - r^2
1698
1699    which can be solved using a standard quadratic formula.
1700
1701    Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1702
1703    Practical Simplification
1704
1705    In a renderer, we often differentiate between world space and object space. In the object space
1706    of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1707    into object space, the mathematical solution presented above can be simplified significantly.
1708
1709    If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1710
1711    p dot p = r^2
1712
1713    and we can find the t at which the (transformed) ray intersects the sphere by
1714
1715    ( o + td ) dot ( o + td ) = r^2
1716
1717    According to the reasoning above, we expand the above quadratic equation into the general form
1718
1719    At2 + Bt + C = 0
1720
1721    which now has coefficients:
1722
1723    A = d dot d
1724    B = 2( d dot o )
1725    C = o dot o - r^2
1726    */
1727
1728   // Early out if mNode is NULL
1729   if( !mNode )
1730   {
1731     return false;
1732   }
1733
1734   BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1735
1736   // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1737   const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1738   Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1739
1740   // Compute the radius is not needed, square radius it's enough.
1741   const Vector3& size( mNode->GetSize( bufferIndex ) );
1742
1743   // Scale the sphere.
1744   const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1745
1746   const float width = size.width * scale.width;
1747   const float height = size.height * scale.height;
1748
1749   float squareSphereRadius = 0.5f * ( width * width + height * height );
1750
1751   float a = rayDir.Dot( rayDir );                                       // a
1752   float b2 = rayDir.Dot( rayOriginLocal );                              // b/2
1753   float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius;  // c
1754
1755   return ( b2 * b2 - a * c ) >= 0.f;
1756 }
1757
1758 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1759 {
1760   bool hit = false;
1761
1762   if( OnStage() && NULL != mNode )
1763   {
1764     // Transforms the ray to the local reference system.
1765     // Calculate the inverse of Model matrix
1766     Matrix invModelMatrix( false/*don't init*/);
1767
1768     BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1769     invModelMatrix = mNode->GetWorldMatrix(0);
1770     invModelMatrix.Invert();
1771
1772     Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1773     Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1774
1775     // Test with the actor's XY plane (Normal = 0 0 1 1).
1776
1777     float a = -rayOriginLocal.z;
1778     float b = rayDirLocal.z;
1779
1780     if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1781     {
1782       // Ray travels distance * rayDirLocal to intersect with plane.
1783       distance = a / b;
1784
1785       const Vector3& size = mNode->GetSize( bufferIndex );
1786
1787       hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1788       hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1789
1790       // Test with the actor's geometry.
1791       hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1792     }
1793   }
1794
1795   return hit;
1796 }
1797
1798 void Actor::SetLeaveRequired( bool required )
1799 {
1800   mLeaveRequired = required;
1801 }
1802
1803 bool Actor::GetLeaveRequired() const
1804 {
1805   return mLeaveRequired;
1806 }
1807
1808 void Actor::SetKeyboardFocusable( bool focusable )
1809 {
1810   mKeyboardFocusable = focusable;
1811 }
1812
1813 bool Actor::IsKeyboardFocusable() const
1814 {
1815   return mKeyboardFocusable;
1816 }
1817
1818 bool Actor::GetTouchRequired() const
1819 {
1820   return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1821 }
1822
1823 bool Actor::GetHoverRequired() const
1824 {
1825   return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1826 }
1827
1828 bool Actor::GetWheelEventRequired() const
1829 {
1830   return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1831 }
1832
1833 bool Actor::IsHittable() const
1834 {
1835   return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1836 }
1837
1838 ActorGestureData& Actor::GetGestureData()
1839 {
1840   // Likely scenario is that once gesture-data is created for this actor, the actor will require
1841   // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1842   if( NULL == mGestureData )
1843   {
1844     mGestureData = new ActorGestureData;
1845   }
1846   return *mGestureData;
1847 }
1848
1849 bool Actor::IsGestureRequred( Gesture::Type type ) const
1850 {
1851   return mGestureData && mGestureData->IsGestureRequred( type );
1852 }
1853
1854 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1855 {
1856   bool consumed = false;
1857
1858   if( !mTouchSignal.Empty() )
1859   {
1860     Dali::Actor handle( this );
1861     consumed = mTouchSignal.Emit( handle, touch );
1862   }
1863
1864   if( !mTouchedSignal.Empty() )
1865   {
1866     Dali::Actor handle( this );
1867     consumed |= mTouchedSignal.Emit( handle, event );
1868   }
1869
1870   if( !consumed )
1871   {
1872     // Notification for derived classes
1873     consumed = OnTouchEvent( event ); // TODO
1874   }
1875
1876   return consumed;
1877 }
1878
1879 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1880 {
1881   bool consumed = false;
1882
1883   if( !mHoveredSignal.Empty() )
1884   {
1885     Dali::Actor handle( this );
1886     consumed = mHoveredSignal.Emit( handle, event );
1887   }
1888
1889   if( !consumed )
1890   {
1891     // Notification for derived classes
1892     consumed = OnHoverEvent( event );
1893   }
1894
1895   return consumed;
1896 }
1897
1898 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1899 {
1900   bool consumed = false;
1901
1902   if( !mWheelEventSignal.Empty() )
1903   {
1904     Dali::Actor handle( this );
1905     consumed = mWheelEventSignal.Emit( handle, event );
1906   }
1907
1908   if( !consumed )
1909   {
1910     // Notification for derived classes
1911     consumed = OnWheelEvent( event );
1912   }
1913
1914   return consumed;
1915 }
1916
1917 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1918 {
1919   return mTouchedSignal;
1920 }
1921
1922 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1923 {
1924   return mTouchSignal;
1925 }
1926
1927 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1928 {
1929   return mHoveredSignal;
1930 }
1931
1932 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1933 {
1934   return mWheelEventSignal;
1935 }
1936
1937 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1938 {
1939   return mOnStageSignal;
1940 }
1941
1942 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1943 {
1944   return mOffStageSignal;
1945 }
1946
1947 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1948 {
1949   return mOnRelayoutSignal;
1950 }
1951
1952 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1953 {
1954   bool connected( true );
1955   Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1956
1957   if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1958   {
1959     actor->TouchedSignal().Connect( tracker, functor );
1960   }
1961   else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1962   {
1963     actor->HoveredSignal().Connect( tracker, functor );
1964   }
1965   else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1966   {
1967     actor->WheelEventSignal().Connect( tracker, functor );
1968   }
1969   else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1970   {
1971     actor->OnStageSignal().Connect( tracker, functor );
1972   }
1973   else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1974   {
1975     actor->OffStageSignal().Connect( tracker, functor );
1976   }
1977   else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1978   {
1979     actor->OnRelayoutSignal().Connect( tracker, functor );
1980   }
1981   else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1982   {
1983     actor->TouchSignal().Connect( tracker, functor );
1984   }
1985   else
1986   {
1987     // signalName does not match any signal
1988     connected = false;
1989   }
1990
1991   return connected;
1992 }
1993
1994 Actor::Actor( DerivedType derivedType )
1995 : mParent( NULL ),
1996   mChildren( NULL ),
1997   mRenderers( NULL ),
1998   mNode( NULL ),
1999   mParentOrigin( NULL ),
2000   mAnchorPoint( NULL ),
2001   mRelayoutData( NULL ),
2002   mGestureData( NULL ),
2003   mTargetSize( 0.0f, 0.0f, 0.0f ),
2004   mName(),
2005   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2006   mDepth( 0u ),
2007   mSiblingOrder(0u),
2008   mIsRoot( ROOT_LAYER == derivedType ),
2009   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2010   mIsOnStage( false ),
2011   mSensitive( true ),
2012   mLeaveRequired( false ),
2013   mKeyboardFocusable( false ),
2014   mDerivedRequiresTouch( false ),
2015   mDerivedRequiresHover( false ),
2016   mDerivedRequiresWheelEvent( false ),
2017   mOnStageSignalled( false ),
2018   mInsideOnSizeSet( false ),
2019   mInheritPosition( true ),
2020   mInheritOrientation( true ),
2021   mInheritScale( true ),
2022   mDrawMode( DrawMode::NORMAL ),
2023   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2024   mColorMode( Node::DEFAULT_COLOR_MODE ),
2025   mClippingMode( ClippingMode::DISABLED )
2026 {
2027 }
2028
2029 void Actor::Initialize()
2030 {
2031   // Node creation
2032   SceneGraph::Node* node = CreateNode();
2033
2034   AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2035   mNode = node; // Keep raw-pointer to Node
2036
2037   OnInitialize();
2038
2039   GetEventThreadServices().RegisterObject( this );
2040 }
2041
2042 Actor::~Actor()
2043 {
2044   // Remove mParent pointers from children even if we're destroying core,
2045   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2046   if( mChildren )
2047   {
2048     ActorConstIter endIter = mChildren->end();
2049     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2050     {
2051       (*iter)->SetParent( NULL );
2052     }
2053   }
2054   delete mChildren;
2055   delete mRenderers;
2056
2057   // Guard to allow handle destruction after Core has been destroyed
2058   if( EventThreadServices::IsCoreRunning() )
2059   {
2060     if( NULL != mNode )
2061     {
2062       DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2063       mNode = NULL; // Node is about to be destroyed
2064     }
2065
2066     GetEventThreadServices().UnregisterObject( this );
2067   }
2068
2069   // Cleanup optional gesture data
2070   delete mGestureData;
2071
2072   // Cleanup optional parent origin and anchor
2073   delete mParentOrigin;
2074   delete mAnchorPoint;
2075
2076   // Delete optional relayout data
2077   if( mRelayoutData )
2078   {
2079     delete mRelayoutData;
2080   }
2081 }
2082
2083 void Actor::ConnectToStage( unsigned int parentDepth )
2084 {
2085   // This container is used instead of walking the Actor hierarchy.
2086   // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2087   ActorContainer connectionList;
2088
2089   // This stage is atomic i.e. not interrupted by user callbacks.
2090   RecursiveConnectToStage( connectionList, parentDepth + 1 );
2091
2092   // Notify applications about the newly connected actors.
2093   const ActorIter endIter = connectionList.end();
2094   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2095   {
2096     (*iter)->NotifyStageConnection();
2097   }
2098
2099   RelayoutRequest();
2100 }
2101
2102 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2103 {
2104   DALI_ASSERT_ALWAYS( !OnStage() );
2105
2106   mIsOnStage = true;
2107   mDepth = depth;
2108   SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2109
2110   ConnectToSceneGraph();
2111
2112   // Notification for internal derived classes
2113   OnStageConnectionInternal();
2114
2115   // This stage is atomic; avoid emitting callbacks until all Actors are connected
2116   connectionList.push_back( ActorPtr( this ) );
2117
2118   // Recursively connect children
2119   if( mChildren )
2120   {
2121     ActorConstIter endIter = mChildren->end();
2122     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2123     {
2124       (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2125     }
2126   }
2127 }
2128
2129 /**
2130  * This method is called when the Actor is connected to the Stage.
2131  * The parent must have added its Node to the scene-graph.
2132  * The child must connect its Node to the parent's Node.
2133  * This is recursive; the child calls ConnectToStage() for its children.
2134  */
2135 void Actor::ConnectToSceneGraph()
2136 {
2137   DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2138
2139   if( NULL != mNode )
2140   {
2141     // Reparent Node in next Update
2142     ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2143   }
2144
2145   // Request relayout on all actors that are added to the scenegraph
2146   RelayoutRequest();
2147
2148   // Notification for Object::Observers
2149   OnSceneObjectAdd();
2150 }
2151
2152 void Actor::NotifyStageConnection()
2153 {
2154   // Actors can be removed (in a callback), before the on-stage stage is reported.
2155   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2156   if( OnStage() && !mOnStageSignalled )
2157   {
2158     // Notification for external (CustomActor) derived classes
2159     OnStageConnectionExternal( mDepth );
2160
2161     if( !mOnStageSignal.Empty() )
2162     {
2163       Dali::Actor handle( this );
2164       mOnStageSignal.Emit( handle );
2165     }
2166
2167     // Guard against Remove during callbacks
2168     if( OnStage() )
2169     {
2170       mOnStageSignalled = true; // signal required next time Actor is removed
2171     }
2172   }
2173 }
2174
2175 void Actor::DisconnectFromStage()
2176 {
2177   // This container is used instead of walking the Actor hierachy.
2178   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2179   ActorContainer disconnectionList;
2180
2181   // This stage is atomic i.e. not interrupted by user callbacks
2182   RecursiveDisconnectFromStage( disconnectionList );
2183
2184   // Notify applications about the newly disconnected actors.
2185   const ActorIter endIter = disconnectionList.end();
2186   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2187   {
2188     (*iter)->NotifyStageDisconnection();
2189   }
2190 }
2191
2192 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2193 {
2194   DALI_ASSERT_ALWAYS( OnStage() );
2195
2196   // Recursively disconnect children
2197   if( mChildren )
2198   {
2199     ActorConstIter endIter = mChildren->end();
2200     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2201     {
2202       (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2203     }
2204   }
2205
2206   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2207   disconnectionList.push_back( ActorPtr( this ) );
2208
2209   // Notification for internal derived classes
2210   OnStageDisconnectionInternal();
2211
2212   DisconnectFromSceneGraph();
2213
2214   mIsOnStage = false;
2215 }
2216
2217 /**
2218  * This method is called by an actor or its parent, before a node removal message is sent.
2219  * This is recursive; the child calls DisconnectFromStage() for its children.
2220  */
2221 void Actor::DisconnectFromSceneGraph()
2222 {
2223   // Notification for Object::Observers
2224   OnSceneObjectRemove();
2225 }
2226
2227 void Actor::NotifyStageDisconnection()
2228 {
2229   // Actors can be added (in a callback), before the off-stage state is reported.
2230   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2231   // only do this step if there is a stage, i.e. Core is not being shut down
2232   if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2233   {
2234     // Notification for external (CustomeActor) derived classes
2235     OnStageDisconnectionExternal();
2236
2237     if( !mOffStageSignal.Empty() )
2238     {
2239       Dali::Actor handle( this );
2240       mOffStageSignal.Emit( handle );
2241     }
2242
2243     // Guard against Add during callbacks
2244     if( !OnStage() )
2245     {
2246       mOnStageSignalled = false; // signal required next time Actor is added
2247     }
2248   }
2249 }
2250
2251 bool Actor::IsNodeConnected() const
2252 {
2253   bool connected( false );
2254
2255   if( OnStage() && ( NULL != mNode ) )
2256   {
2257     if( IsRoot() || mNode->GetParent() )
2258     {
2259       connected = true;
2260     }
2261   }
2262
2263   return connected;
2264 }
2265
2266 unsigned int Actor::GetDefaultPropertyCount() const
2267 {
2268   return DEFAULT_PROPERTY_COUNT;
2269 }
2270
2271 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2272 {
2273   indices.Reserve( DEFAULT_PROPERTY_COUNT );
2274
2275   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2276   {
2277     indices.PushBack( i );
2278   }
2279 }
2280
2281 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2282 {
2283   if( index < DEFAULT_PROPERTY_COUNT )
2284   {
2285     return DEFAULT_PROPERTY_DETAILS[ index ].name;
2286   }
2287
2288   return NULL;
2289 }
2290
2291 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2292 {
2293   Property::Index index = Property::INVALID_INDEX;
2294
2295   // Look for name in default properties
2296   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2297   {
2298     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2299     if( 0 == name.compare( property->name ) )
2300     {
2301       index = i;
2302       break;
2303     }
2304   }
2305
2306   return index;
2307 }
2308
2309 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2310 {
2311   if( index < DEFAULT_PROPERTY_COUNT )
2312   {
2313     return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2314   }
2315
2316   return false;
2317 }
2318
2319 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2320 {
2321   if( index < DEFAULT_PROPERTY_COUNT )
2322   {
2323     return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2324   }
2325
2326   return false;
2327 }
2328
2329 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2330 {
2331   if( index < DEFAULT_PROPERTY_COUNT )
2332   {
2333     return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2334   }
2335
2336   return false;
2337 }
2338
2339 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2340 {
2341   if( index < DEFAULT_PROPERTY_COUNT )
2342   {
2343     return DEFAULT_PROPERTY_DETAILS[ index ].type;
2344   }
2345
2346   // index out of range...return Property::NONE
2347   return Property::NONE;
2348 }
2349
2350 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2351 {
2352   switch( index )
2353   {
2354     case Dali::Actor::Property::PARENT_ORIGIN:
2355     {
2356       Property::Type type = property.GetType();
2357       if( type == Property::VECTOR3 )
2358       {
2359         SetParentOrigin( property.Get< Vector3 >() );
2360       }
2361       else if ( type == Property::STRING )
2362       {
2363         std::string parentOriginString;
2364         property.Get( parentOriginString );
2365         Vector3 parentOrigin;
2366         if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2367         {
2368           SetParentOrigin( parentOrigin );
2369         }
2370       }
2371       break;
2372     }
2373
2374     case Dali::Actor::Property::PARENT_ORIGIN_X:
2375     {
2376       SetParentOriginX( property.Get< float >() );
2377       break;
2378     }
2379
2380     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2381     {
2382       SetParentOriginY( property.Get< float >() );
2383       break;
2384     }
2385
2386     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2387     {
2388       SetParentOriginZ( property.Get< float >() );
2389       break;
2390     }
2391
2392     case Dali::Actor::Property::ANCHOR_POINT:
2393     {
2394       Property::Type type = property.GetType();
2395       if( type == Property::VECTOR3 )
2396       {
2397         SetAnchorPoint( property.Get< Vector3 >() );
2398       }
2399       else if ( type == Property::STRING )
2400       {
2401         std::string anchorPointString;
2402         property.Get( anchorPointString );
2403         Vector3 anchor;
2404         if( GetAnchorPointConstant( anchorPointString, anchor ) )
2405         {
2406           SetAnchorPoint( anchor );
2407         }
2408       }
2409       break;
2410     }
2411
2412     case Dali::Actor::Property::ANCHOR_POINT_X:
2413     {
2414       SetAnchorPointX( property.Get< float >() );
2415       break;
2416     }
2417
2418     case Dali::Actor::Property::ANCHOR_POINT_Y:
2419     {
2420       SetAnchorPointY( property.Get< float >() );
2421       break;
2422     }
2423
2424     case Dali::Actor::Property::ANCHOR_POINT_Z:
2425     {
2426       SetAnchorPointZ( property.Get< float >() );
2427       break;
2428     }
2429
2430     case Dali::Actor::Property::SIZE:
2431     {
2432       SetSize( property.Get< Vector3 >() );
2433       break;
2434     }
2435
2436     case Dali::Actor::Property::SIZE_WIDTH:
2437     {
2438       SetWidth( property.Get< float >() );
2439       break;
2440     }
2441
2442     case Dali::Actor::Property::SIZE_HEIGHT:
2443     {
2444       SetHeight( property.Get< float >() );
2445       break;
2446     }
2447
2448     case Dali::Actor::Property::SIZE_DEPTH:
2449     {
2450       SetDepth( property.Get< float >() );
2451       break;
2452     }
2453
2454     case Dali::Actor::Property::POSITION:
2455     {
2456       SetPosition( property.Get< Vector3 >() );
2457       break;
2458     }
2459
2460     case Dali::Actor::Property::POSITION_X:
2461     {
2462       SetX( property.Get< float >() );
2463       break;
2464     }
2465
2466     case Dali::Actor::Property::POSITION_Y:
2467     {
2468       SetY( property.Get< float >() );
2469       break;
2470     }
2471
2472     case Dali::Actor::Property::POSITION_Z:
2473     {
2474       SetZ( property.Get< float >() );
2475       break;
2476     }
2477
2478     case Dali::Actor::Property::ORIENTATION:
2479     {
2480       SetOrientation( property.Get< Quaternion >() );
2481       break;
2482     }
2483
2484     case Dali::Actor::Property::SCALE:
2485     {
2486       SetScale( property.Get< Vector3 >() );
2487       break;
2488     }
2489
2490     case Dali::Actor::Property::SCALE_X:
2491     {
2492       SetScaleX( property.Get< float >() );
2493       break;
2494     }
2495
2496     case Dali::Actor::Property::SCALE_Y:
2497     {
2498       SetScaleY( property.Get< float >() );
2499       break;
2500     }
2501
2502     case Dali::Actor::Property::SCALE_Z:
2503     {
2504       SetScaleZ( property.Get< float >() );
2505       break;
2506     }
2507
2508     case Dali::Actor::Property::VISIBLE:
2509     {
2510       SetVisible( property.Get< bool >() );
2511       break;
2512     }
2513
2514     case Dali::Actor::Property::COLOR:
2515     {
2516       SetColor( property.Get< Vector4 >() );
2517       break;
2518     }
2519
2520     case Dali::Actor::Property::COLOR_RED:
2521     {
2522       SetColorRed( property.Get< float >() );
2523       break;
2524     }
2525
2526     case Dali::Actor::Property::COLOR_GREEN:
2527     {
2528       SetColorGreen( property.Get< float >() );
2529       break;
2530     }
2531
2532     case Dali::Actor::Property::COLOR_BLUE:
2533     {
2534       SetColorBlue( property.Get< float >() );
2535       break;
2536     }
2537
2538     case Dali::Actor::Property::COLOR_ALPHA:
2539     {
2540       SetOpacity( property.Get< float >() );
2541       break;
2542     }
2543
2544     case Dali::Actor::Property::NAME:
2545     {
2546       SetName( property.Get< std::string >() );
2547       break;
2548     }
2549
2550     case Dali::Actor::Property::SENSITIVE:
2551     {
2552       SetSensitive( property.Get< bool >() );
2553       break;
2554     }
2555
2556     case Dali::Actor::Property::LEAVE_REQUIRED:
2557     {
2558       SetLeaveRequired( property.Get< bool >() );
2559       break;
2560     }
2561
2562     case Dali::Actor::Property::INHERIT_POSITION:
2563     {
2564       SetInheritPosition( property.Get< bool >() );
2565       break;
2566     }
2567
2568     case Dali::Actor::Property::INHERIT_ORIENTATION:
2569     {
2570       SetInheritOrientation( property.Get< bool >() );
2571       break;
2572     }
2573
2574     case Dali::Actor::Property::INHERIT_SCALE:
2575     {
2576       SetInheritScale( property.Get< bool >() );
2577       break;
2578     }
2579
2580     case Dali::Actor::Property::COLOR_MODE:
2581     {
2582       ColorMode mode = mColorMode;
2583       if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2584       {
2585         SetColorMode( mode );
2586       }
2587       break;
2588     }
2589
2590     case Dali::Actor::Property::POSITION_INHERITANCE:
2591     {
2592       PositionInheritanceMode mode = mPositionInheritanceMode;
2593       if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2594       {
2595         SetPositionInheritanceMode( mode );
2596       }
2597       break;
2598     }
2599
2600     case Dali::Actor::Property::DRAW_MODE:
2601     {
2602       DrawMode::Type mode = mDrawMode;
2603       if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2604       {
2605         SetDrawMode( mode );
2606       }
2607       break;
2608     }
2609
2610     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2611     {
2612       SetSizeModeFactor( property.Get< Vector3 >() );
2613       break;
2614     }
2615
2616     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2617     {
2618       ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2619       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2620       {
2621         SetResizePolicy( type, Dimension::WIDTH );
2622       }
2623       break;
2624     }
2625
2626     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2627     {
2628       ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2629       if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2630       {
2631         SetResizePolicy( type, Dimension::HEIGHT );
2632       }
2633       break;
2634     }
2635
2636     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2637     {
2638       SizeScalePolicy::Type type;
2639       if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2640       {
2641         SetSizeScalePolicy( type );
2642       }
2643       break;
2644     }
2645
2646     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2647     {
2648       if( property.Get< bool >() )
2649       {
2650         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2651       }
2652       break;
2653     }
2654
2655     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2656     {
2657       if( property.Get< bool >() )
2658       {
2659         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2660       }
2661       break;
2662     }
2663
2664     case Dali::Actor::Property::PADDING:
2665     {
2666       Vector4 padding = property.Get< Vector4 >();
2667       SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2668       SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2669       break;
2670     }
2671
2672     case Dali::Actor::Property::MINIMUM_SIZE:
2673     {
2674       Vector2 size = property.Get< Vector2 >();
2675       SetMinimumSize( size.x, Dimension::WIDTH );
2676       SetMinimumSize( size.y, Dimension::HEIGHT );
2677       break;
2678     }
2679
2680     case Dali::Actor::Property::MAXIMUM_SIZE:
2681     {
2682       Vector2 size = property.Get< Vector2 >();
2683       SetMaximumSize( size.x, Dimension::WIDTH );
2684       SetMaximumSize( size.y, Dimension::HEIGHT );
2685       break;
2686     }
2687
2688     case Dali::DevelActor::Property::SIBLING_ORDER:
2689     {
2690       int value;
2691
2692       if( property.Get( value ) )
2693       {
2694         if( static_cast<unsigned int>(value) != mSiblingOrder )
2695         {
2696           mSiblingOrder = value;
2697           if( mIsOnStage )
2698           {
2699             SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2700           }
2701         }
2702       }
2703       break;
2704     }
2705
2706     case Dali::Actor::Property::CLIPPING_MODE:
2707     {
2708       ClippingMode::Type convertedValue = mClippingMode;
2709       if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2710       {
2711         mClippingMode = convertedValue;
2712         if( NULL != mNode )
2713         {
2714           SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2715         }
2716       }
2717       break;
2718     }
2719
2720     default:
2721     {
2722       // this can happen in the case of a non-animatable default property so just do nothing
2723       break;
2724     }
2725   }
2726 }
2727
2728 // TODO: This method needs to be removed
2729 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2730 {
2731   switch( entry.GetType() )
2732   {
2733     case Property::BOOLEAN:
2734     {
2735       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2736       DALI_ASSERT_DEBUG( NULL != property );
2737
2738       // property is being used in a separate thread; queue a message to set the property
2739       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2740
2741       break;
2742     }
2743
2744     case Property::INTEGER:
2745     {
2746       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2747       DALI_ASSERT_DEBUG( NULL != property );
2748
2749       // property is being used in a separate thread; queue a message to set the property
2750       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2751
2752       break;
2753     }
2754
2755     case Property::FLOAT:
2756     {
2757       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2758       DALI_ASSERT_DEBUG( NULL != property );
2759
2760       // property is being used in a separate thread; queue a message to set the property
2761       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2762
2763       break;
2764     }
2765
2766     case Property::VECTOR2:
2767     {
2768       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2769       DALI_ASSERT_DEBUG( NULL != property );
2770
2771       // property is being used in a separate thread; queue a message to set the property
2772       if(entry.componentIndex == 0)
2773       {
2774         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2775       }
2776       else if(entry.componentIndex == 1)
2777       {
2778         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2779       }
2780       else
2781       {
2782         SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2783       }
2784
2785       break;
2786     }
2787
2788     case Property::VECTOR3:
2789     {
2790       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2791       DALI_ASSERT_DEBUG( NULL != property );
2792
2793       // property is being used in a separate thread; queue a message to set the property
2794       if(entry.componentIndex == 0)
2795       {
2796         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2797       }
2798       else if(entry.componentIndex == 1)
2799       {
2800         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2801       }
2802       else if(entry.componentIndex == 2)
2803       {
2804         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2805       }
2806       else
2807       {
2808         SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2809       }
2810
2811       break;
2812     }
2813
2814     case Property::VECTOR4:
2815     {
2816       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2817       DALI_ASSERT_DEBUG( NULL != property );
2818
2819       // property is being used in a separate thread; queue a message to set the property
2820       if(entry.componentIndex == 0)
2821       {
2822         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2823       }
2824       else if(entry.componentIndex == 1)
2825       {
2826         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2827       }
2828       else if(entry.componentIndex == 2)
2829       {
2830         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2831       }
2832       else if(entry.componentIndex == 3)
2833       {
2834         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2835       }
2836       else
2837       {
2838         SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2839       }
2840
2841       break;
2842     }
2843
2844     case Property::ROTATION:
2845     {
2846       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2847       DALI_ASSERT_DEBUG( NULL != property );
2848
2849       // property is being used in a separate thread; queue a message to set the property
2850       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
2851
2852       break;
2853     }
2854
2855     case Property::MATRIX:
2856     {
2857       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2858       DALI_ASSERT_DEBUG( NULL != property );
2859
2860       // property is being used in a separate thread; queue a message to set the property
2861       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
2862
2863       break;
2864     }
2865
2866     case Property::MATRIX3:
2867     {
2868       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2869       DALI_ASSERT_DEBUG( NULL != property );
2870
2871       // property is being used in a separate thread; queue a message to set the property
2872       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
2873
2874       break;
2875     }
2876
2877     default:
2878     {
2879       // nothing to do for other types
2880     }
2881   } // entry.GetType
2882 }
2883
2884 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2885 {
2886   Property::Value value;
2887
2888   if( index >= DEFAULT_PROPERTY_COUNT )
2889   {
2890     return value;
2891   }
2892
2893   switch( index )
2894   {
2895     case Dali::Actor::Property::PARENT_ORIGIN:
2896     {
2897       value = GetCurrentParentOrigin();
2898       break;
2899     }
2900
2901     case Dali::Actor::Property::PARENT_ORIGIN_X:
2902     {
2903       value = GetCurrentParentOrigin().x;
2904       break;
2905     }
2906
2907     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2908     {
2909       value = GetCurrentParentOrigin().y;
2910       break;
2911     }
2912
2913     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2914     {
2915       value = GetCurrentParentOrigin().z;
2916       break;
2917     }
2918
2919     case Dali::Actor::Property::ANCHOR_POINT:
2920     {
2921       value = GetCurrentAnchorPoint();
2922       break;
2923     }
2924
2925     case Dali::Actor::Property::ANCHOR_POINT_X:
2926     {
2927       value = GetCurrentAnchorPoint().x;
2928       break;
2929     }
2930
2931     case Dali::Actor::Property::ANCHOR_POINT_Y:
2932     {
2933       value = GetCurrentAnchorPoint().y;
2934       break;
2935     }
2936
2937     case Dali::Actor::Property::ANCHOR_POINT_Z:
2938     {
2939       value = GetCurrentAnchorPoint().z;
2940       break;
2941     }
2942
2943     case Dali::Actor::Property::SIZE:
2944     {
2945       Vector3 size = GetTargetSize();
2946
2947       // Should return preferred size if size is fixed as set by SetSize
2948       if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
2949       {
2950         size.width = GetPreferredSize().width;
2951       }
2952       if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
2953       {
2954         size.height = GetPreferredSize().height;
2955       }
2956
2957       value = size;
2958
2959       break;
2960     }
2961
2962     case Dali::Actor::Property::SIZE_WIDTH:
2963     {
2964       if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
2965       {
2966         // Should return preferred size if size is fixed as set by SetSize
2967         value = GetPreferredSize().width;
2968       }
2969       else
2970       {
2971         value = GetTargetSize().width;
2972       }
2973       break;
2974     }
2975
2976     case Dali::Actor::Property::SIZE_HEIGHT:
2977     {
2978       if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
2979       {
2980         // Should return preferred size if size is fixed as set by SetSize
2981         value = GetPreferredSize().height;
2982       }
2983       else
2984       {
2985         value = GetTargetSize().height;
2986       }
2987       break;
2988     }
2989
2990     case Dali::Actor::Property::SIZE_DEPTH:
2991     {
2992       value = GetTargetSize().depth;
2993       break;
2994     }
2995
2996     case Dali::Actor::Property::POSITION:
2997     {
2998       value = GetTargetPosition();
2999       break;
3000     }
3001
3002     case Dali::Actor::Property::POSITION_X:
3003     {
3004       value = GetTargetPosition().x;
3005       break;
3006     }
3007
3008     case Dali::Actor::Property::POSITION_Y:
3009     {
3010       value = GetTargetPosition().y;
3011       break;
3012     }
3013
3014     case Dali::Actor::Property::POSITION_Z:
3015     {
3016       value = GetTargetPosition().z;
3017       break;
3018     }
3019
3020     case Dali::Actor::Property::WORLD_POSITION:
3021     {
3022       value = GetCurrentWorldPosition();
3023       break;
3024     }
3025
3026     case Dali::Actor::Property::WORLD_POSITION_X:
3027     {
3028       value = GetCurrentWorldPosition().x;
3029       break;
3030     }
3031
3032     case Dali::Actor::Property::WORLD_POSITION_Y:
3033     {
3034       value = GetCurrentWorldPosition().y;
3035       break;
3036     }
3037
3038     case Dali::Actor::Property::WORLD_POSITION_Z:
3039     {
3040       value = GetCurrentWorldPosition().z;
3041       break;
3042     }
3043
3044     case Dali::Actor::Property::ORIENTATION:
3045     {
3046       value = GetCurrentOrientation();
3047       break;
3048     }
3049
3050     case Dali::Actor::Property::WORLD_ORIENTATION:
3051     {
3052       value = GetCurrentWorldOrientation();
3053       break;
3054     }
3055
3056     case Dali::Actor::Property::SCALE:
3057     {
3058       value = GetCurrentScale();
3059       break;
3060     }
3061
3062     case Dali::Actor::Property::SCALE_X:
3063     {
3064       value = GetCurrentScale().x;
3065       break;
3066     }
3067
3068     case Dali::Actor::Property::SCALE_Y:
3069     {
3070       value = GetCurrentScale().y;
3071       break;
3072     }
3073
3074     case Dali::Actor::Property::SCALE_Z:
3075     {
3076       value = GetCurrentScale().z;
3077       break;
3078     }
3079
3080     case Dali::Actor::Property::WORLD_SCALE:
3081     {
3082       value = GetCurrentWorldScale();
3083       break;
3084     }
3085
3086     case Dali::Actor::Property::VISIBLE:
3087     {
3088       value = IsVisible();
3089       break;
3090     }
3091
3092     case Dali::Actor::Property::COLOR:
3093     {
3094       value = GetCurrentColor();
3095       break;
3096     }
3097
3098     case Dali::Actor::Property::COLOR_RED:
3099     {
3100       value = GetCurrentColor().r;
3101       break;
3102     }
3103
3104     case Dali::Actor::Property::COLOR_GREEN:
3105     {
3106       value = GetCurrentColor().g;
3107       break;
3108     }
3109
3110     case Dali::Actor::Property::COLOR_BLUE:
3111     {
3112       value = GetCurrentColor().b;
3113       break;
3114     }
3115
3116     case Dali::Actor::Property::COLOR_ALPHA:
3117     {
3118       value = GetCurrentColor().a;
3119       break;
3120     }
3121
3122     case Dali::Actor::Property::WORLD_COLOR:
3123     {
3124       value = GetCurrentWorldColor();
3125       break;
3126     }
3127
3128     case Dali::Actor::Property::WORLD_MATRIX:
3129     {
3130       value = GetCurrentWorldMatrix();
3131       break;
3132     }
3133
3134     case Dali::Actor::Property::NAME:
3135     {
3136       value = GetName();
3137       break;
3138     }
3139
3140     case Dali::Actor::Property::SENSITIVE:
3141     {
3142       value = IsSensitive();
3143       break;
3144     }
3145
3146     case Dali::Actor::Property::LEAVE_REQUIRED:
3147     {
3148       value = GetLeaveRequired();
3149       break;
3150     }
3151
3152     case Dali::Actor::Property::INHERIT_POSITION:
3153     {
3154       value = IsPositionInherited();
3155       break;
3156     }
3157
3158     case Dali::Actor::Property::INHERIT_ORIENTATION:
3159     {
3160       value = IsOrientationInherited();
3161       break;
3162     }
3163
3164     case Dali::Actor::Property::INHERIT_SCALE:
3165     {
3166       value = IsScaleInherited();
3167       break;
3168     }
3169
3170     case Dali::Actor::Property::COLOR_MODE:
3171     {
3172       value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3173       break;
3174     }
3175
3176     case Dali::Actor::Property::POSITION_INHERITANCE:
3177     {
3178       value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3179       break;
3180     }
3181
3182     case Dali::Actor::Property::DRAW_MODE:
3183     {
3184       value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3185       break;
3186     }
3187
3188     case Dali::Actor::Property::SIZE_MODE_FACTOR:
3189     {
3190       value = GetSizeModeFactor();
3191       break;
3192     }
3193
3194     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3195     {
3196       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3197       break;
3198     }
3199
3200     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3201     {
3202       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3203       break;
3204     }
3205
3206     case Dali::Actor::Property::SIZE_SCALE_POLICY:
3207     {
3208       value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3209       break;
3210     }
3211
3212     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3213     {
3214       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3215       break;
3216     }
3217
3218     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3219     {
3220       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3221       break;
3222     }
3223
3224     case Dali::Actor::Property::PADDING:
3225     {
3226       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3227       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3228       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3229       break;
3230     }
3231
3232     case Dali::Actor::Property::MINIMUM_SIZE:
3233     {
3234       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3235       break;
3236     }
3237
3238     case Dali::Actor::Property::MAXIMUM_SIZE:
3239     {
3240       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3241       break;
3242     }
3243
3244     case Dali::DevelActor::Property::SIBLING_ORDER:
3245     {
3246       value = static_cast<int>(mSiblingOrder);
3247       break;
3248     }
3249
3250     case Dali::Actor::Property::CLIPPING_MODE:
3251     {
3252       value = mClippingMode;
3253       break;
3254     }
3255   }
3256
3257   return value;
3258 }
3259
3260 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3261 {
3262   return mNode;
3263 }
3264
3265 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3266 {
3267   // This method should only return an object connected to the scene-graph
3268   return OnStage() ? mNode : NULL;
3269 }
3270
3271 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3272 {
3273   DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3274
3275   const PropertyBase* property( NULL );
3276
3277   // This method should only return a property of an object connected to the scene-graph
3278   if( !OnStage() )
3279   {
3280     return property;
3281   }
3282
3283   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3284   {
3285     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3286     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3287
3288     property = animatable->GetSceneGraphProperty();
3289   }
3290   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3291             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3292   {
3293     CustomPropertyMetadata* custom = FindCustomProperty( index );
3294     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3295
3296     property = custom->GetSceneGraphProperty();
3297   }
3298   else if( NULL != mNode )
3299   {
3300     switch( index )
3301     {
3302       case Dali::Actor::Property::SIZE:
3303         property = &mNode->mSize;
3304         break;
3305
3306       case Dali::Actor::Property::SIZE_WIDTH:
3307         property = &mNode->mSize;
3308         break;
3309
3310       case Dali::Actor::Property::SIZE_HEIGHT:
3311         property = &mNode->mSize;
3312         break;
3313
3314       case Dali::Actor::Property::SIZE_DEPTH:
3315         property = &mNode->mSize;
3316         break;
3317
3318       case Dali::Actor::Property::POSITION:
3319         property = &mNode->mPosition;
3320         break;
3321
3322       case Dali::Actor::Property::POSITION_X:
3323         property = &mNode->mPosition;
3324         break;
3325
3326       case Dali::Actor::Property::POSITION_Y:
3327         property = &mNode->mPosition;
3328         break;
3329
3330       case Dali::Actor::Property::POSITION_Z:
3331         property = &mNode->mPosition;
3332         break;
3333
3334       case Dali::Actor::Property::ORIENTATION:
3335         property = &mNode->mOrientation;
3336         break;
3337
3338       case Dali::Actor::Property::SCALE:
3339         property = &mNode->mScale;
3340         break;
3341
3342       case Dali::Actor::Property::SCALE_X:
3343         property = &mNode->mScale;
3344         break;
3345
3346       case Dali::Actor::Property::SCALE_Y:
3347         property = &mNode->mScale;
3348         break;
3349
3350       case Dali::Actor::Property::SCALE_Z:
3351         property = &mNode->mScale;
3352         break;
3353
3354       case Dali::Actor::Property::VISIBLE:
3355         property = &mNode->mVisible;
3356         break;
3357
3358       case Dali::Actor::Property::COLOR:
3359         property = &mNode->mColor;
3360         break;
3361
3362       case Dali::Actor::Property::COLOR_RED:
3363         property = &mNode->mColor;
3364         break;
3365
3366       case Dali::Actor::Property::COLOR_GREEN:
3367         property = &mNode->mColor;
3368         break;
3369
3370       case Dali::Actor::Property::COLOR_BLUE:
3371         property = &mNode->mColor;
3372         break;
3373
3374       case Dali::Actor::Property::COLOR_ALPHA:
3375         property = &mNode->mColor;
3376         break;
3377
3378       default:
3379         break;
3380     }
3381   }
3382
3383   return property;
3384 }
3385
3386 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3387 {
3388   const PropertyInputImpl* property( NULL );
3389
3390   // This method should only return a property of an object connected to the scene-graph
3391   if( !OnStage() )
3392   {
3393     return property;
3394   }
3395
3396   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3397   {
3398     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3399     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3400
3401     property = animatable->GetSceneGraphProperty();
3402   }
3403   else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3404             ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3405   {
3406     CustomPropertyMetadata* custom = FindCustomProperty( index );
3407     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3408     property = custom->GetSceneGraphProperty();
3409   }
3410   else if( NULL != mNode )
3411   {
3412     switch( index )
3413     {
3414       case Dali::Actor::Property::PARENT_ORIGIN:
3415         property = &mNode->mParentOrigin;
3416         break;
3417
3418       case Dali::Actor::Property::PARENT_ORIGIN_X:
3419         property = &mNode->mParentOrigin;
3420         break;
3421
3422       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3423         property = &mNode->mParentOrigin;
3424         break;
3425
3426       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3427         property = &mNode->mParentOrigin;
3428         break;
3429
3430       case Dali::Actor::Property::ANCHOR_POINT:
3431         property = &mNode->mAnchorPoint;
3432         break;
3433
3434       case Dali::Actor::Property::ANCHOR_POINT_X:
3435         property = &mNode->mAnchorPoint;
3436         break;
3437
3438       case Dali::Actor::Property::ANCHOR_POINT_Y:
3439         property = &mNode->mAnchorPoint;
3440         break;
3441
3442       case Dali::Actor::Property::ANCHOR_POINT_Z:
3443         property = &mNode->mAnchorPoint;
3444         break;
3445
3446       case Dali::Actor::Property::SIZE:
3447         property = &mNode->mSize;
3448         break;
3449
3450       case Dali::Actor::Property::SIZE_WIDTH:
3451         property = &mNode->mSize;
3452         break;
3453
3454       case Dali::Actor::Property::SIZE_HEIGHT:
3455         property = &mNode->mSize;
3456         break;
3457
3458       case Dali::Actor::Property::SIZE_DEPTH:
3459         property = &mNode->mSize;
3460         break;
3461
3462       case Dali::Actor::Property::POSITION:
3463         property = &mNode->mPosition;
3464         break;
3465
3466       case Dali::Actor::Property::POSITION_X:
3467         property = &mNode->mPosition;
3468         break;
3469
3470       case Dali::Actor::Property::POSITION_Y:
3471         property = &mNode->mPosition;
3472         break;
3473
3474       case Dali::Actor::Property::POSITION_Z:
3475         property = &mNode->mPosition;
3476         break;
3477
3478       case Dali::Actor::Property::WORLD_POSITION:
3479         property = &mNode->mWorldPosition;
3480         break;
3481
3482       case Dali::Actor::Property::WORLD_POSITION_X:
3483         property = &mNode->mWorldPosition;
3484         break;
3485
3486       case Dali::Actor::Property::WORLD_POSITION_Y:
3487         property = &mNode->mWorldPosition;
3488         break;
3489
3490       case Dali::Actor::Property::WORLD_POSITION_Z:
3491         property = &mNode->mWorldPosition;
3492         break;
3493
3494       case Dali::Actor::Property::ORIENTATION:
3495         property = &mNode->mOrientation;
3496         break;
3497
3498       case Dali::Actor::Property::WORLD_ORIENTATION:
3499         property = &mNode->mWorldOrientation;
3500         break;
3501
3502       case Dali::Actor::Property::SCALE:
3503         property = &mNode->mScale;
3504         break;
3505
3506       case Dali::Actor::Property::SCALE_X:
3507         property = &mNode->mScale;
3508         break;
3509
3510       case Dali::Actor::Property::SCALE_Y:
3511         property = &mNode->mScale;
3512         break;
3513
3514       case Dali::Actor::Property::SCALE_Z:
3515         property = &mNode->mScale;
3516         break;
3517
3518       case Dali::Actor::Property::WORLD_SCALE:
3519         property = &mNode->mWorldScale;
3520         break;
3521
3522       case Dali::Actor::Property::VISIBLE:
3523         property = &mNode->mVisible;
3524         break;
3525
3526       case Dali::Actor::Property::COLOR:
3527         property = &mNode->mColor;
3528         break;
3529
3530       case Dali::Actor::Property::COLOR_RED:
3531         property = &mNode->mColor;
3532         break;
3533
3534       case Dali::Actor::Property::COLOR_GREEN:
3535         property = &mNode->mColor;
3536         break;
3537
3538       case Dali::Actor::Property::COLOR_BLUE:
3539         property = &mNode->mColor;
3540         break;
3541
3542       case Dali::Actor::Property::COLOR_ALPHA:
3543         property = &mNode->mColor;
3544         break;
3545
3546       case Dali::Actor::Property::WORLD_COLOR:
3547         property = &mNode->mWorldColor;
3548         break;
3549
3550       case Dali::Actor::Property::WORLD_MATRIX:
3551         property = &mNode->mWorldMatrix;
3552         break;
3553
3554       default:
3555         break;
3556     }
3557   }
3558
3559   return property;
3560 }
3561
3562 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3563 {
3564   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3565
3566   if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3567   {
3568     // check whether the animatable property is registered already, if not then register one.
3569     AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3570     if( animatableProperty )
3571     {
3572       componentIndex = animatableProperty->componentIndex;
3573     }
3574   }
3575   else
3576   {
3577     switch( index )
3578     {
3579       case Dali::Actor::Property::PARENT_ORIGIN_X:
3580       case Dali::Actor::Property::ANCHOR_POINT_X:
3581       case Dali::Actor::Property::SIZE_WIDTH:
3582       case Dali::Actor::Property::POSITION_X:
3583       case Dali::Actor::Property::WORLD_POSITION_X:
3584       case Dali::Actor::Property::SCALE_X:
3585       case Dali::Actor::Property::COLOR_RED:
3586       {
3587         componentIndex = 0;
3588         break;
3589       }
3590
3591       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3592       case Dali::Actor::Property::ANCHOR_POINT_Y:
3593       case Dali::Actor::Property::SIZE_HEIGHT:
3594       case Dali::Actor::Property::POSITION_Y:
3595       case Dali::Actor::Property::WORLD_POSITION_Y:
3596       case Dali::Actor::Property::SCALE_Y:
3597       case Dali::Actor::Property::COLOR_GREEN:
3598       {
3599         componentIndex = 1;
3600         break;
3601       }
3602
3603       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3604       case Dali::Actor::Property::ANCHOR_POINT_Z:
3605       case Dali::Actor::Property::SIZE_DEPTH:
3606       case Dali::Actor::Property::POSITION_Z:
3607       case Dali::Actor::Property::WORLD_POSITION_Z:
3608       case Dali::Actor::Property::SCALE_Z:
3609       case Dali::Actor::Property::COLOR_BLUE:
3610       {
3611         componentIndex = 2;
3612         break;
3613       }
3614
3615       case Dali::Actor::Property::COLOR_ALPHA:
3616       {
3617         componentIndex = 3;
3618         break;
3619       }
3620
3621       default:
3622       {
3623         // Do nothing
3624         break;
3625       }
3626     }
3627   }
3628
3629   return componentIndex;
3630 }
3631
3632 void Actor::SetParent( Actor* parent )
3633 {
3634   if( parent )
3635   {
3636     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3637
3638     mParent = parent;
3639
3640     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3641          parent->OnStage() )
3642     {
3643       // Instruct each actor to create a corresponding node in the scene graph
3644       ConnectToStage( parent->GetHierarchyDepth() );
3645     }
3646
3647     // Resolve the name and index for the child properties if any
3648     ResolveChildProperties();
3649   }
3650   else // parent being set to NULL
3651   {
3652     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3653
3654     mParent = NULL;
3655
3656     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3657          OnStage() )
3658     {
3659       DALI_ASSERT_ALWAYS( mNode != NULL );
3660
3661       if( NULL != mNode )
3662       {
3663         // Disconnect the Node & its children from the scene-graph.
3664         DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3665       }
3666
3667       // Instruct each actor to discard pointers to the scene-graph
3668       DisconnectFromStage();
3669     }
3670   }
3671 }
3672
3673 SceneGraph::Node* Actor::CreateNode() const
3674 {
3675   return Node::New();
3676 }
3677
3678 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3679 {
3680   bool done = false;
3681   Actor* actor = dynamic_cast< Actor* >( object );
3682
3683   if( actor )
3684   {
3685     if( 0 == actionName.compare( ACTION_SHOW ) )
3686     {
3687       actor->SetVisible( true );
3688       done = true;
3689     }
3690     else if( 0 == actionName.compare( ACTION_HIDE ) )
3691     {
3692       actor->SetVisible( false );
3693       done = true;
3694     }
3695   }
3696
3697   return done;
3698 }
3699
3700 void Actor::EnsureRelayoutData()
3701 {
3702   // Assign relayout data.
3703   if( !mRelayoutData )
3704   {
3705     mRelayoutData = new RelayoutData();
3706   }
3707 }
3708
3709 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3710 {
3711   // Check if actor is dependent on parent
3712   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3713   {
3714     if( ( dimension & ( 1 << i ) ) )
3715     {
3716       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3717       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3718       {
3719         return true;
3720       }
3721     }
3722   }
3723
3724   return false;
3725 }
3726
3727 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3728 {
3729   // Check if actor is dependent on children
3730   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3731   {
3732     if( ( dimension & ( 1 << i ) ) )
3733     {
3734       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3735       switch( resizePolicy )
3736       {
3737         case ResizePolicy::FIT_TO_CHILDREN:
3738         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
3739         {
3740           return true;
3741         }
3742
3743         default:
3744         {
3745           break;
3746         }
3747       }
3748     }
3749   }
3750
3751   return false;
3752 }
3753
3754 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3755 {
3756   return Actor::RelayoutDependentOnChildren( dimension );
3757 }
3758
3759 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3760 {
3761   // Check each possible dimension and see if it is dependent on the input one
3762   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3763   {
3764     if( dimension & ( 1 << i ) )
3765     {
3766       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3767     }
3768   }
3769
3770   return false;
3771 }
3772
3773 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3774 {
3775   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3776   {
3777     if( dimension & ( 1 << i ) )
3778     {
3779       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3780     }
3781   }
3782 }
3783
3784 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3785 {
3786   // If more than one dimension is requested, just return the first one found
3787   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3788   {
3789     if( ( dimension & ( 1 << i ) ) )
3790     {
3791       return mRelayoutData->negotiatedDimensions[ i ];
3792     }
3793   }
3794
3795   return 0.0f;   // Default
3796 }
3797
3798 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3799 {
3800   EnsureRelayoutData();
3801
3802   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3803   {
3804     if( dimension & ( 1 << i ) )
3805     {
3806       mRelayoutData->dimensionPadding[ i ] = padding;
3807     }
3808   }
3809 }
3810
3811 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3812 {
3813   if ( mRelayoutData )
3814   {
3815     // If more than one dimension is requested, just return the first one found
3816     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3817     {
3818       if( ( dimension & ( 1 << i ) ) )
3819       {
3820         return mRelayoutData->dimensionPadding[ i ];
3821       }
3822     }
3823   }
3824
3825   return GetDefaultDimensionPadding();
3826 }
3827
3828 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3829 {
3830   EnsureRelayoutData();
3831
3832   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3833   {
3834     if( dimension & ( 1 << i ) )
3835     {
3836       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3837     }
3838   }
3839 }
3840
3841 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3842 {
3843   if ( mRelayoutData )
3844   {
3845     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3846     {
3847       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3848       {
3849         return true;
3850       }
3851     }
3852   }
3853
3854   return false;
3855 }
3856
3857 float Actor::GetHeightForWidthBase( float width )
3858 {
3859   float height = 0.0f;
3860
3861   const Vector3 naturalSize = GetNaturalSize();
3862   if( naturalSize.width > 0.0f )
3863   {
3864     height = naturalSize.height * width / naturalSize.width;
3865   }
3866   else // we treat 0 as 1:1 aspect ratio
3867   {
3868     height = width;
3869   }
3870
3871   return height;
3872 }
3873
3874 float Actor::GetWidthForHeightBase( float height )
3875 {
3876   float width = 0.0f;
3877
3878   const Vector3 naturalSize = GetNaturalSize();
3879   if( naturalSize.height > 0.0f )
3880   {
3881     width = naturalSize.width * height / naturalSize.height;
3882   }
3883   else // we treat 0 as 1:1 aspect ratio
3884   {
3885     width = height;
3886   }
3887
3888   return width;
3889 }
3890
3891 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3892 {
3893   // Fill to parent, taking size mode factor into account
3894   switch( child.GetResizePolicy( dimension ) )
3895   {
3896     case ResizePolicy::FILL_TO_PARENT:
3897     {
3898       return GetLatestSize( dimension );
3899     }
3900
3901     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3902     {
3903       return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3904     }
3905
3906     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3907     {
3908       return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3909     }
3910
3911     default:
3912     {
3913       return GetLatestSize( dimension );
3914     }
3915   }
3916 }
3917
3918 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3919 {
3920   // Can be overridden in derived class
3921   return CalculateChildSizeBase( child, dimension );
3922 }
3923
3924 float Actor::GetHeightForWidth( float width )
3925 {
3926   // Can be overridden in derived class
3927   return GetHeightForWidthBase( width );
3928 }
3929
3930 float Actor::GetWidthForHeight( float height )
3931 {
3932   // Can be overridden in derived class
3933   return GetWidthForHeightBase( height );
3934 }
3935
3936 float Actor::GetLatestSize( Dimension::Type dimension ) const
3937 {
3938   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3939 }
3940
3941 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3942 {
3943   Vector2 padding = GetPadding( dimension );
3944
3945   return GetLatestSize( dimension ) + padding.x + padding.y;
3946 }
3947
3948 float Actor::NegotiateFromParent( Dimension::Type dimension )
3949 {
3950   Actor* parent = GetParent();
3951   if( parent )
3952   {
3953     Vector2 padding( GetPadding( dimension ) );
3954     Vector2 parentPadding( parent->GetPadding( dimension ) );
3955     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3956   }
3957
3958   return 0.0f;
3959 }
3960
3961 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3962 {
3963   float maxDimensionPoint = 0.0f;
3964
3965   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3966   {
3967     ActorPtr child = GetChildAt( i );
3968
3969     if( !child->RelayoutDependentOnParent( dimension ) )
3970     {
3971       // Calculate the min and max points that the children range across
3972       float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3973       float dimensionSize = child->GetRelayoutSize( dimension );
3974       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3975     }
3976   }
3977
3978   return maxDimensionPoint;
3979 }
3980
3981 float Actor::GetSize( Dimension::Type dimension ) const
3982 {
3983   return GetDimensionValue( GetTargetSize(), dimension );
3984 }
3985
3986 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3987 {
3988   return GetDimensionValue( GetNaturalSize(), dimension );
3989 }
3990
3991 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3992 {
3993   switch( GetResizePolicy( dimension ) )
3994   {
3995     case ResizePolicy::USE_NATURAL_SIZE:
3996     {
3997       return GetNaturalSize( dimension );
3998     }
3999
4000     case ResizePolicy::FIXED:
4001     {
4002       return GetDimensionValue( GetPreferredSize(), dimension );
4003     }
4004
4005     case ResizePolicy::USE_ASSIGNED_SIZE:
4006     {
4007       return GetDimensionValue( maximumSize, dimension );
4008     }
4009
4010     case ResizePolicy::FILL_TO_PARENT:
4011     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4012     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4013     {
4014       return NegotiateFromParent( dimension );
4015     }
4016
4017     case ResizePolicy::FIT_TO_CHILDREN:
4018     {
4019       return NegotiateFromChildren( dimension );
4020     }
4021
4022     case ResizePolicy::DIMENSION_DEPENDENCY:
4023     {
4024       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4025
4026       // Custom rules
4027       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4028       {
4029         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4030       }
4031
4032       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4033       {
4034         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4035       }
4036
4037       break;
4038     }
4039
4040     default:
4041     {
4042       break;
4043     }
4044   }
4045
4046   return 0.0f;  // Default
4047 }
4048
4049 float Actor::ClampDimension( float size, Dimension::Type dimension )
4050 {
4051   const float minSize = GetMinimumSize( dimension );
4052   const float maxSize = GetMaximumSize( dimension );
4053
4054   return std::max( minSize, std::min( size, maxSize ) );
4055 }
4056
4057 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4058 {
4059   // Check if it needs to be negotiated
4060   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4061   {
4062     // Check that we havn't gotten into an infinite loop
4063     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4064     bool recursionFound = false;
4065     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4066     {
4067       if( *it == searchActor )
4068       {
4069         recursionFound = true;
4070         break;
4071       }
4072     }
4073
4074     if( !recursionFound )
4075     {
4076       // Record the path that we have taken
4077       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4078
4079       // Dimension dependency check
4080       for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4081       {
4082         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4083
4084         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4085         {
4086           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4087         }
4088       }
4089
4090       // Parent dependency check
4091       Actor* parent = GetParent();
4092       if( parent && RelayoutDependentOnParent( dimension ) )
4093       {
4094         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4095       }
4096
4097       // Children dependency check
4098       if( RelayoutDependentOnChildren( dimension ) )
4099       {
4100         for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4101         {
4102           ActorPtr child = GetChildAt( i );
4103
4104           // Only relayout child first if it is not dependent on this actor
4105           if( !child->RelayoutDependentOnParent( dimension ) )
4106           {
4107             child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4108           }
4109         }
4110       }
4111
4112       // For deriving classes
4113       OnCalculateRelayoutSize( dimension );
4114
4115       // All dependencies checked, calculate the size and set negotiated flag
4116       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4117
4118       SetNegotiatedDimension( newSize, dimension );
4119       SetLayoutNegotiated( true, dimension );
4120
4121       // For deriving classes
4122       OnLayoutNegotiated( newSize, dimension );
4123
4124       // This actor has been successfully processed, pop it off the recursion stack
4125       recursionStack.pop_back();
4126     }
4127     else
4128     {
4129       // TODO: Break infinite loop
4130       SetLayoutNegotiated( true, dimension );
4131     }
4132   }
4133 }
4134
4135 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4136 {
4137   // Negotiate all dimensions that require it
4138   ActorDimensionStack recursionStack;
4139
4140   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4141   {
4142     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4143
4144     // Negotiate
4145     NegotiateDimension( dimension, allocatedSize, recursionStack );
4146   }
4147 }
4148
4149 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4150 {
4151   switch( mRelayoutData->sizeSetPolicy )
4152   {
4153     case SizeScalePolicy::USE_SIZE_SET:
4154     {
4155       return size;
4156     }
4157
4158     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4159     {
4160       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4161       const Vector3 naturalSize = GetNaturalSize();
4162       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4163       {
4164         const float sizeRatio = size.width / size.height;
4165         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4166
4167         if( naturalSizeRatio < sizeRatio )
4168         {
4169           return Vector2( naturalSizeRatio * size.height, size.height );
4170         }
4171         else if( naturalSizeRatio > sizeRatio )
4172         {
4173           return Vector2( size.width, size.width / naturalSizeRatio );
4174         }
4175         else
4176         {
4177           return size;
4178         }
4179       }
4180
4181       break;
4182     }
4183
4184     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4185     {
4186       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4187       const Vector3 naturalSize = GetNaturalSize();
4188       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4189       {
4190         const float sizeRatio = size.width / size.height;
4191         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4192
4193         if( naturalSizeRatio < sizeRatio )
4194         {
4195           return Vector2( size.width, size.width / naturalSizeRatio );
4196         }
4197         else if( naturalSizeRatio > sizeRatio )
4198         {
4199           return Vector2( naturalSizeRatio * size.height, size.height );
4200         }
4201         else
4202         {
4203           return size;
4204         }
4205       }
4206       break;
4207     }
4208
4209     default:
4210     {
4211       break;
4212     }
4213   }
4214
4215   return size;
4216 }
4217
4218 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4219 {
4220   // Do the set actor size
4221   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4222
4223   // Adjust for size set policy
4224   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4225
4226   // Lock the flag to stop recursive relayouts on set size
4227   mRelayoutData->insideRelayout = true;
4228   SetSize( negotiatedSize );
4229   mRelayoutData->insideRelayout = false;
4230
4231   // Clear flags for all dimensions
4232   SetLayoutDirty( false );
4233
4234   // Give deriving classes a chance to respond
4235   OnRelayout( negotiatedSize, container );
4236
4237   if( !mOnRelayoutSignal.Empty() )
4238   {
4239     Dali::Actor handle( this );
4240     mOnRelayoutSignal.Emit( handle );
4241   }
4242 }
4243
4244 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4245 {
4246   // Force a size negotiation for actors that has assigned size during relayout
4247   // This is required as otherwise the flags that force a relayout will not
4248   // necessarilly be set. This will occur if the actor has already been laid out.
4249   // The dirty flags are then cleared. Then if the actor is added back into the
4250   // relayout container afterwards, the dirty flags would still be clear...
4251   // causing a relayout to be skipped. Here we force any actors added to the
4252   // container to be relayed out.
4253   if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4254   {
4255     SetLayoutNegotiated(false, Dimension::WIDTH);
4256   }
4257   if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4258   {
4259     SetLayoutNegotiated(false, Dimension::HEIGHT);
4260   }
4261
4262   // Do the negotiation
4263   NegotiateDimensions( allocatedSize );
4264
4265   // Set the actor size
4266   SetNegotiatedSize( container );
4267
4268   // Negotiate down to children
4269   const Vector2 newBounds = GetTargetSize().GetVectorXY();
4270
4271   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4272   {
4273     ActorPtr child = GetChildAt( i );
4274
4275     // Forces children that have already been laid out to be relayed out
4276     // if they have assigned size during relayout.
4277     if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4278     {
4279       child->SetLayoutNegotiated(false, Dimension::WIDTH);
4280       child->SetLayoutDirty(true, Dimension::WIDTH);
4281     }
4282     if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4283     {
4284       child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4285       child->SetLayoutDirty(true, Dimension::HEIGHT);
4286     }
4287
4288     // Only relayout if required
4289     if( child->RelayoutRequired() )
4290     {
4291       container.Add( Dali::Actor( child.Get() ), newBounds );
4292     }
4293   }
4294 }
4295
4296 void Actor::RelayoutRequest( Dimension::Type dimension )
4297 {
4298   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4299   if( relayoutController )
4300   {
4301     Dali::Actor self( this );
4302     relayoutController->RequestRelayout( self, dimension );
4303   }
4304 }
4305
4306 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4307 {
4308 }
4309
4310 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4311 {
4312 }
4313
4314 void Actor::SetPreferredSize( const Vector2& size )
4315 {
4316   EnsureRelayoutData();
4317
4318   if( size.width > 0.0f )
4319   {
4320     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4321   }
4322
4323   if( size.height > 0.0f )
4324   {
4325     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4326   }
4327
4328   mRelayoutData->preferredSize = size;
4329
4330   RelayoutRequest();
4331 }
4332
4333 Vector2 Actor::GetPreferredSize() const
4334 {
4335   if ( mRelayoutData )
4336   {
4337     return Vector2( mRelayoutData->preferredSize );
4338   }
4339
4340   return GetDefaultPreferredSize();
4341 }
4342
4343 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4344 {
4345   EnsureRelayoutData();
4346
4347   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4348   {
4349     if( dimension & ( 1 << i ) )
4350     {
4351       mRelayoutData->minimumSize[ i ] = size;
4352     }
4353   }
4354
4355   RelayoutRequest();
4356 }
4357
4358 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4359 {
4360   if ( mRelayoutData )
4361   {
4362     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4363     {
4364       if( dimension & ( 1 << i ) )
4365       {
4366         return mRelayoutData->minimumSize[ i ];
4367       }
4368     }
4369   }
4370
4371   return 0.0f;  // Default
4372 }
4373
4374 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4375 {
4376   EnsureRelayoutData();
4377
4378   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4379   {
4380     if( dimension & ( 1 << i ) )
4381     {
4382       mRelayoutData->maximumSize[ i ] = size;
4383     }
4384   }
4385
4386   RelayoutRequest();
4387 }
4388
4389 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4390 {
4391   if ( mRelayoutData )
4392   {
4393     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4394     {
4395       if( dimension & ( 1 << i ) )
4396       {
4397         return mRelayoutData->maximumSize[ i ];
4398       }
4399     }
4400   }
4401
4402   return FLT_MAX;  // Default
4403 }
4404
4405 Object* Actor::GetParentObject() const
4406 {
4407   return mParent;
4408 }
4409
4410 } // namespace Internal
4411
4412 } // namespace Dali