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