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