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