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