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