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