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