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