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