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