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