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