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