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