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