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