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