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