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