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