Merge "Fixed Actor not callind mAttachment->Connect if Actor::AddRenderer is called...
[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     if( mIsOnStage )
1367     {
1368       mAttachment->Connect();
1369     }
1370   }
1371
1372   return 0;
1373 }
1374
1375 unsigned int Actor::GetRendererCount() const
1376 {
1377   //TODO: MESH_REWORK : Add support for multiple renderers
1378   RendererAttachment* attachment = dynamic_cast<RendererAttachment*>(mAttachment.Get());
1379   return attachment ? 1u : 0u;
1380 }
1381
1382 Renderer& Actor::GetRendererAt( unsigned int index )
1383 {
1384   //TODO: MESH_REWORK : Add support for multiple renderers
1385   DALI_ASSERT_DEBUG( index == 0 && "Only one renderer is supported." );
1386
1387   //TODO: MESH_REWORK : Temporary code
1388   RendererAttachment* attachment = dynamic_cast<RendererAttachment*>(mAttachment.Get());
1389   DALI_ASSERT_ALWAYS( attachment && "Actor doesn't have a renderer" );
1390
1391   return attachment->GetRenderer();
1392 }
1393
1394 void Actor::RemoveRenderer( Renderer& renderer )
1395 {
1396   //TODO: MESH_REWORK : Add support for multiple renderers
1397   mAttachment = NULL;
1398 }
1399
1400 void Actor::RemoveRenderer( unsigned int index )
1401 {
1402   //TODO: MESH_REWORK : Add support for multiple renderers
1403   mAttachment = NULL;
1404 }
1405
1406 void Actor::SetOverlay( bool enable )
1407 {
1408   // Setting STENCIL will override OVERLAY_2D
1409   if( DrawMode::STENCIL != mDrawMode )
1410   {
1411     SetDrawMode( enable ? DrawMode::OVERLAY_2D : DrawMode::NORMAL );
1412   }
1413 }
1414
1415 bool Actor::IsOverlay() const
1416 {
1417   return ( DrawMode::OVERLAY_2D == mDrawMode );
1418 }
1419
1420 void Actor::SetDrawMode( DrawMode::Type drawMode )
1421 {
1422   // this flag is not animatable so keep the value
1423   mDrawMode = drawMode;
1424   if( NULL != mNode )
1425   {
1426     // mNode is being used in a separate thread; queue a message to set the value
1427     SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1428   }
1429 }
1430
1431 DrawMode::Type Actor::GetDrawMode() const
1432 {
1433   return mDrawMode;
1434 }
1435
1436 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1437 {
1438   // only valid when on-stage
1439   StagePtr stage = Stage::GetCurrent();
1440   if( stage && OnStage() )
1441   {
1442     const RenderTaskList& taskList = stage->GetRenderTaskList();
1443
1444     Vector2 converted( screenX, screenY );
1445
1446     // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1447     const int taskCount = taskList.GetTaskCount();
1448     for( int i = taskCount - 1; i >= 0; --i )
1449     {
1450       Dali::RenderTask task = taskList.GetTask( i );
1451       if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1452       {
1453         // found a task where this conversion was ok so return
1454         return true;
1455       }
1456     }
1457   }
1458   return false;
1459 }
1460
1461 bool Actor::ScreenToLocal( RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1462 {
1463   bool retval = false;
1464   // only valid when on-stage
1465   if( OnStage() )
1466   {
1467     CameraActor* camera = renderTask.GetCameraActor();
1468     if( camera )
1469     {
1470       Viewport viewport;
1471       renderTask.GetViewport( viewport );
1472
1473       // need to translate coordinates to render tasks coordinate space
1474       Vector2 converted( screenX, screenY );
1475       if( renderTask.TranslateCoordinates( converted ) )
1476       {
1477         retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1478       }
1479     }
1480   }
1481   return retval;
1482 }
1483
1484 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1485 {
1486   // Early-out if mNode is NULL
1487   if( !OnStage() )
1488   {
1489     return false;
1490   }
1491
1492   BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1493
1494   // Calculate the ModelView matrix
1495   Matrix modelView( false/*don't init*/);
1496   // need to use the components as world matrix is only updated for actors that need it
1497   modelView.SetTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) );
1498   Matrix::Multiply( modelView, modelView, viewMatrix );
1499
1500   // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1501   Matrix invertedMvp( false/*don't init*/);
1502   Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1503   bool success = invertedMvp.Invert();
1504
1505   // Convert to GL coordinates
1506   Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1507
1508   Vector4 nearPos;
1509   if( success )
1510   {
1511     success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1512   }
1513
1514   Vector4 farPos;
1515   if( success )
1516   {
1517     screenPos.z = 1.0f;
1518     success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1519   }
1520
1521   if( success )
1522   {
1523     Vector4 local;
1524     if( XyPlaneIntersect( nearPos, farPos, local ) )
1525     {
1526       Vector3 size = GetCurrentSize();
1527       localX = local.x + size.x * 0.5f;
1528       localY = local.y + size.y * 0.5f;
1529     }
1530     else
1531     {
1532       success = false;
1533     }
1534   }
1535
1536   return success;
1537 }
1538
1539 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1540 {
1541   /*
1542    http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1543
1544    Mathematical Formulation
1545
1546    Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1547
1548    ( p - c ) dot ( p - c ) = r^2
1549
1550    Given a ray with a point of origin 'o', and a direction vector 'd':
1551
1552    ray(t) = o + td, t >= 0
1553
1554    we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1555
1556    (o + td - c ) dot ( o + td - c ) = r^2
1557
1558    To solve for t we first expand the above into a more recognisable quadratic equation form
1559
1560    ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1561
1562    or
1563
1564    At2 + Bt + C = 0
1565
1566    where
1567
1568    A = d dot d
1569    B = 2( o - c ) dot d
1570    C = ( o - c ) dot ( o - c ) - r^2
1571
1572    which can be solved using a standard quadratic formula.
1573
1574    Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1575
1576    Practical Simplification
1577
1578    In a renderer, we often differentiate between world space and object space. In the object space
1579    of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1580    into object space, the mathematical solution presented above can be simplified significantly.
1581
1582    If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1583
1584    p dot p = r^2
1585
1586    and we can find the t at which the (transformed) ray intersects the sphere by
1587
1588    ( o + td ) dot ( o + td ) = r^2
1589
1590    According to the reasoning above, we expand the above quadratic equation into the general form
1591
1592    At2 + Bt + C = 0
1593
1594    which now has coefficients:
1595
1596    A = d dot d
1597    B = 2( d dot o )
1598    C = o dot o - r^2
1599    */
1600
1601   // Early out if mNode is NULL
1602   if( !mNode )
1603   {
1604     return false;
1605   }
1606
1607   BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1608
1609   // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1610   const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1611   Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1612
1613   // Compute the radius is not needed, square radius it's enough.
1614   const Vector3& size( mNode->GetSize( bufferIndex ) );
1615
1616   // Scale the sphere.
1617   const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1618
1619   const float width = size.width * scale.width;
1620   const float height = size.height * scale.height;
1621
1622   float squareSphereRadius = 0.5f * ( width * width + height * height );
1623
1624   float a = rayDir.Dot( rayDir );                                       // a
1625   float b2 = rayDir.Dot( rayOriginLocal );                              // b/2
1626   float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius;  // c
1627
1628   return ( b2 * b2 - a * c ) >= 0.f;
1629 }
1630
1631 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1632 {
1633   bool hit = false;
1634
1635   if( OnStage() &&
1636   NULL != mNode )
1637   {
1638     BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1639
1640     // Transforms the ray to the local reference system.
1641
1642     // Calculate the inverse of Model matrix
1643     Matrix invModelMatrix( false/*don't init*/);
1644     // need to use the components as world matrix is only updated for actors that need it
1645     invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) );
1646
1647     Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1648     Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1649
1650     // Test with the actor's XY plane (Normal = 0 0 1 1).
1651
1652     float a = -rayOriginLocal.z;
1653     float b = rayDirLocal.z;
1654
1655     if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1656     {
1657       // Ray travels distance * rayDirLocal to intersect with plane.
1658       distance = a / b;
1659
1660       const Vector3& size = mNode->GetSize( bufferIndex );
1661
1662       hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1663       hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1664
1665       // Test with the actor's geometry.
1666       hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1667     }
1668   }
1669
1670   return hit;
1671 }
1672
1673 void Actor::SetLeaveRequired( bool required )
1674 {
1675   mLeaveRequired = required;
1676 }
1677
1678 bool Actor::GetLeaveRequired() const
1679 {
1680   return mLeaveRequired;
1681 }
1682
1683 void Actor::SetKeyboardFocusable( bool focusable )
1684 {
1685   mKeyboardFocusable = focusable;
1686 }
1687
1688 bool Actor::IsKeyboardFocusable() const
1689 {
1690   return mKeyboardFocusable;
1691 }
1692
1693 bool Actor::GetTouchRequired() const
1694 {
1695   return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
1696 }
1697
1698 bool Actor::GetHoverRequired() const
1699 {
1700   return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1701 }
1702
1703 bool Actor::GetWheelEventRequired() const
1704 {
1705   return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1706 }
1707
1708 bool Actor::IsHittable() const
1709 {
1710   return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1711 }
1712
1713 ActorGestureData& Actor::GetGestureData()
1714 {
1715   // Likely scenario is that once gesture-data is created for this actor, the actor will require
1716   // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1717   if( NULL == mGestureData )
1718   {
1719     mGestureData = new ActorGestureData;
1720   }
1721   return *mGestureData;
1722 }
1723
1724 bool Actor::IsGestureRequred( Gesture::Type type ) const
1725 {
1726   return mGestureData && mGestureData->IsGestureRequred( type );
1727 }
1728
1729 bool Actor::EmitTouchEventSignal( const TouchEvent& event )
1730 {
1731   bool consumed = false;
1732
1733   if( !mTouchedSignal.Empty() )
1734   {
1735     Dali::Actor handle( this );
1736     consumed = mTouchedSignal.Emit( handle, event );
1737   }
1738
1739   if( !consumed )
1740   {
1741     // Notification for derived classes
1742     consumed = OnTouchEvent( event );
1743   }
1744
1745   return consumed;
1746 }
1747
1748 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1749 {
1750   bool consumed = false;
1751
1752   if( !mHoveredSignal.Empty() )
1753   {
1754     Dali::Actor handle( this );
1755     consumed = mHoveredSignal.Emit( handle, event );
1756   }
1757
1758   if( !consumed )
1759   {
1760     // Notification for derived classes
1761     consumed = OnHoverEvent( event );
1762   }
1763
1764   return consumed;
1765 }
1766
1767 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1768 {
1769   bool consumed = false;
1770
1771   if( !mWheelEventSignal.Empty() )
1772   {
1773     Dali::Actor handle( this );
1774     consumed = mWheelEventSignal.Emit( handle, event );
1775   }
1776
1777   if( !consumed )
1778   {
1779     // Notification for derived classes
1780     consumed = OnWheelEvent( event );
1781   }
1782
1783   return consumed;
1784 }
1785
1786 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1787 {
1788   return mTouchedSignal;
1789 }
1790
1791 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1792 {
1793   return mHoveredSignal;
1794 }
1795
1796 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1797 {
1798   return mWheelEventSignal;
1799 }
1800
1801 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1802 {
1803   return mOnStageSignal;
1804 }
1805
1806 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1807 {
1808   return mOffStageSignal;
1809 }
1810
1811 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1812 {
1813   return mOnRelayoutSignal;
1814 }
1815
1816 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1817 {
1818   bool connected( true );
1819   Actor* actor = dynamic_cast< Actor* >( object );
1820
1821   if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1822   {
1823     actor->TouchedSignal().Connect( tracker, functor );
1824   }
1825   else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1826   {
1827     actor->HoveredSignal().Connect( tracker, functor );
1828   }
1829   else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1830   {
1831     actor->WheelEventSignal().Connect( tracker, functor );
1832   }
1833   else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1834   {
1835     actor->OnStageSignal().Connect( tracker, functor );
1836   }
1837   else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1838   {
1839     actor->OffStageSignal().Connect( tracker, functor );
1840   }
1841   else
1842   {
1843     // signalName does not match any signal
1844     connected = false;
1845   }
1846
1847   return connected;
1848 }
1849
1850 Actor::Actor( DerivedType derivedType )
1851 : mParent( NULL ),
1852   mChildren( NULL ),
1853   mNode( NULL ),
1854   mParentOrigin( NULL ),
1855   mAnchorPoint( NULL ),
1856   mRelayoutData( NULL ),
1857   mGestureData( NULL ),
1858   mAttachment(),
1859   mTargetSize( 0.0f, 0.0f, 0.0f ),
1860   mName(),
1861   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1862   mDepth( 0u ),
1863   mIsRoot( ROOT_LAYER == derivedType ),
1864   mIsRenderable( RENDERABLE == derivedType ),
1865   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1866   mIsOnStage( false ),
1867   mSensitive( true ),
1868   mLeaveRequired( false ),
1869   mKeyboardFocusable( false ),
1870   mDerivedRequiresTouch( false ),
1871   mDerivedRequiresHover( false ),
1872   mDerivedRequiresWheelEvent( false ),
1873   mOnStageSignalled( false ),
1874   mInsideOnSizeSet( false ),
1875   mInheritOrientation( true ),
1876   mInheritScale( true ),
1877   mDrawMode( DrawMode::NORMAL ),
1878   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1879   mColorMode( Node::DEFAULT_COLOR_MODE )
1880 {
1881 }
1882
1883 void Actor::Initialize()
1884 {
1885   // Node creation
1886   SceneGraph::Node* node = CreateNode();
1887
1888   AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
1889   mNode = node; // Keep raw-pointer to Node
1890
1891   OnInitialize();
1892
1893   GetEventThreadServices().RegisterObject( this );
1894 }
1895
1896 Actor::~Actor()
1897 {
1898   // Remove mParent pointers from children even if we're destroying core,
1899   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1900   if( mChildren )
1901   {
1902     ActorConstIter endIter = mChildren->end();
1903     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
1904     {
1905       (*iter)->SetParent( NULL );
1906     }
1907   }
1908   delete mChildren;
1909
1910   // Guard to allow handle destruction after Core has been destroyed
1911   if( EventThreadServices::IsCoreRunning() )
1912   {
1913     if( NULL != mNode )
1914     {
1915       DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
1916       mNode = NULL; // Node is about to be destroyed
1917     }
1918
1919     GetEventThreadServices().UnregisterObject( this );
1920   }
1921
1922   // Cleanup optional gesture data
1923   delete mGestureData;
1924
1925   // Cleanup optional parent origin and anchor
1926   delete mParentOrigin;
1927   delete mAnchorPoint;
1928
1929   // Delete optional relayout data
1930   if( mRelayoutData )
1931   {
1932     delete mRelayoutData;
1933   }
1934 }
1935
1936 void Actor::ConnectToStage( unsigned int parentDepth, int index )
1937 {
1938   // This container is used instead of walking the Actor hierachy.
1939   // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
1940   ActorContainer connectionList;
1941
1942
1943   // This stage is atomic i.e. not interrupted by user callbacks
1944   RecursiveConnectToStage( connectionList, parentDepth+1, index );
1945
1946   // Notify applications about the newly connected actors.
1947   const ActorIter endIter = connectionList.end();
1948   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
1949   {
1950     (*iter)->NotifyStageConnection();
1951   }
1952
1953   RelayoutRequest();
1954 }
1955
1956 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth, int index )
1957 {
1958   DALI_ASSERT_ALWAYS( !OnStage() );
1959
1960   mIsOnStage = true;
1961   mDepth = depth;
1962
1963   ConnectToSceneGraph( index );
1964
1965   // Notification for internal derived classes
1966   OnStageConnectionInternal();
1967
1968   // This stage is atomic; avoid emitting callbacks until all Actors are connected
1969   connectionList.push_back( ActorPtr( this ) );
1970
1971   // Recursively connect children
1972   if( mChildren )
1973   {
1974     ActorConstIter endIter = mChildren->end();
1975     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
1976     {
1977       (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
1978     }
1979   }
1980 }
1981
1982 /**
1983  * This method is called when the Actor is connected to the Stage.
1984  * The parent must have added its Node to the scene-graph.
1985  * The child must connect its Node to the parent's Node.
1986  * This is resursive; the child calls ConnectToStage() for its children.
1987  */
1988 void Actor::ConnectToSceneGraph( int index )
1989 {
1990   DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
1991
1992   if( NULL != mNode )
1993   {
1994     // Reparent Node in next Update
1995     ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode, index );
1996   }
1997
1998   // Notify attachment
1999   if( mAttachment )
2000   {
2001     mAttachment->Connect();
2002   }
2003
2004   // Request relayout on all actors that are added to the scenegraph
2005   RelayoutRequest();
2006
2007   // Notification for Object::Observers
2008   OnSceneObjectAdd();
2009 }
2010
2011 void Actor::NotifyStageConnection()
2012 {
2013   // Actors can be removed (in a callback), before the on-stage stage is reported.
2014   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2015   if( OnStage() && !mOnStageSignalled )
2016   {
2017     // Notification for external (CustomActor) derived classes
2018     OnStageConnectionExternal( mDepth );
2019
2020     if( !mOnStageSignal.Empty() )
2021     {
2022       Dali::Actor handle( this );
2023       mOnStageSignal.Emit( handle );
2024     }
2025
2026     // Guard against Remove during callbacks
2027     if( OnStage() )
2028     {
2029       mOnStageSignalled = true; // signal required next time Actor is removed
2030     }
2031   }
2032 }
2033
2034 void Actor::DisconnectFromStage()
2035 {
2036   // This container is used instead of walking the Actor hierachy.
2037   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2038   ActorContainer disconnectionList;
2039
2040   // This stage is atomic i.e. not interrupted by user callbacks
2041   RecursiveDisconnectFromStage( disconnectionList );
2042
2043   // Notify applications about the newly disconnected actors.
2044   const ActorIter endIter = disconnectionList.end();
2045   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2046   {
2047     (*iter)->NotifyStageDisconnection();
2048   }
2049 }
2050
2051 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2052 {
2053   DALI_ASSERT_ALWAYS( OnStage() );
2054
2055   // Recursively disconnect children
2056   if( mChildren )
2057   {
2058     ActorConstIter endIter = mChildren->end();
2059     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2060     {
2061       (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2062     }
2063   }
2064
2065   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2066   disconnectionList.push_back( ActorPtr( this ) );
2067
2068   // Notification for internal derived classes
2069   OnStageDisconnectionInternal();
2070
2071   DisconnectFromSceneGraph();
2072
2073   mIsOnStage = false;
2074 }
2075
2076 /**
2077  * This method is called by an actor or its parent, before a node removal message is sent.
2078  * This is recursive; the child calls DisconnectFromStage() for its children.
2079  */
2080 void Actor::DisconnectFromSceneGraph()
2081 {
2082   // Notification for Object::Observers
2083   OnSceneObjectRemove();
2084
2085   // Notify attachment
2086   if( mAttachment )
2087   {
2088     mAttachment->Disconnect();
2089   }
2090 }
2091
2092 void Actor::NotifyStageDisconnection()
2093 {
2094   // Actors can be added (in a callback), before the off-stage state is reported.
2095   // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2096   // only do this step if there is a stage, i.e. Core is not being shut down
2097   if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2098   {
2099     // Notification for external (CustomeActor) derived classes
2100     OnStageDisconnectionExternal();
2101
2102     if( !mOffStageSignal.Empty() )
2103     {
2104       Dali::Actor handle( this );
2105       mOffStageSignal.Emit( handle );
2106     }
2107
2108     // Guard against Add during callbacks
2109     if( !OnStage() )
2110     {
2111       mOnStageSignalled = false; // signal required next time Actor is added
2112     }
2113   }
2114 }
2115
2116 bool Actor::IsNodeConnected() const
2117 {
2118   bool connected( false );
2119
2120   if( OnStage() &&
2121   NULL != mNode )
2122   {
2123     if( mNode->IsRoot() || mNode->GetParent() )
2124     {
2125       connected = true;
2126     }
2127   }
2128
2129   return connected;
2130 }
2131
2132 unsigned int Actor::GetDefaultPropertyCount() const
2133 {
2134   return DEFAULT_PROPERTY_COUNT;
2135 }
2136
2137 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2138 {
2139   indices.Reserve( DEFAULT_PROPERTY_COUNT );
2140
2141   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2142   {
2143     indices.PushBack( i );
2144   }
2145 }
2146
2147 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2148 {
2149   if( index < DEFAULT_PROPERTY_COUNT )
2150   {
2151     return DEFAULT_PROPERTY_DETAILS[ index ].name;
2152   }
2153
2154   return NULL;
2155 }
2156
2157 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2158 {
2159   Property::Index index = Property::INVALID_INDEX;
2160
2161   // Look for name in default properties
2162   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2163   {
2164     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2165     if( 0 == name.compare( property->name ) )
2166     {
2167       index = i;
2168       break;
2169     }
2170   }
2171
2172   return index;
2173 }
2174
2175 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2176 {
2177   if( index < DEFAULT_PROPERTY_COUNT )
2178   {
2179     return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2180   }
2181
2182   return false;
2183 }
2184
2185 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2186 {
2187   if( index < DEFAULT_PROPERTY_COUNT )
2188   {
2189     return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2190   }
2191
2192   return false;
2193 }
2194
2195 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2196 {
2197   if( index < DEFAULT_PROPERTY_COUNT )
2198   {
2199     return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2200   }
2201
2202   return false;
2203 }
2204
2205 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2206 {
2207   if( index < DEFAULT_PROPERTY_COUNT )
2208   {
2209     return DEFAULT_PROPERTY_DETAILS[ index ].type;
2210   }
2211
2212   // index out of range...return Property::NONE
2213   return Property::NONE;
2214 }
2215
2216 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2217 {
2218   switch( index )
2219   {
2220     case Dali::Actor::Property::PARENT_ORIGIN:
2221     {
2222       SetParentOrigin( property.Get< Vector3 >() );
2223       break;
2224     }
2225
2226     case Dali::Actor::Property::PARENT_ORIGIN_X:
2227     {
2228       SetParentOriginX( property.Get< float >() );
2229       break;
2230     }
2231
2232     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2233     {
2234       SetParentOriginY( property.Get< float >() );
2235       break;
2236     }
2237
2238     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2239     {
2240       SetParentOriginZ( property.Get< float >() );
2241       break;
2242     }
2243
2244     case Dali::Actor::Property::ANCHOR_POINT:
2245     {
2246       SetAnchorPoint( property.Get< Vector3 >() );
2247       break;
2248     }
2249
2250     case Dali::Actor::Property::ANCHOR_POINT_X:
2251     {
2252       SetAnchorPointX( property.Get< float >() );
2253       break;
2254     }
2255
2256     case Dali::Actor::Property::ANCHOR_POINT_Y:
2257     {
2258       SetAnchorPointY( property.Get< float >() );
2259       break;
2260     }
2261
2262     case Dali::Actor::Property::ANCHOR_POINT_Z:
2263     {
2264       SetAnchorPointZ( property.Get< float >() );
2265       break;
2266     }
2267
2268     case Dali::Actor::Property::SIZE:
2269     {
2270       SetSize( property.Get< Vector3 >() );
2271       break;
2272     }
2273
2274     case Dali::Actor::Property::SIZE_WIDTH:
2275     {
2276       SetWidth( property.Get< float >() );
2277       break;
2278     }
2279
2280     case Dali::Actor::Property::SIZE_HEIGHT:
2281     {
2282       SetHeight( property.Get< float >() );
2283       break;
2284     }
2285
2286     case Dali::Actor::Property::SIZE_DEPTH:
2287     {
2288       SetDepth( property.Get< float >() );
2289       break;
2290     }
2291
2292     case Dali::Actor::Property::POSITION:
2293     {
2294       SetPosition( property.Get< Vector3 >() );
2295       break;
2296     }
2297
2298     case Dali::Actor::Property::POSITION_X:
2299     {
2300       SetX( property.Get< float >() );
2301       break;
2302     }
2303
2304     case Dali::Actor::Property::POSITION_Y:
2305     {
2306       SetY( property.Get< float >() );
2307       break;
2308     }
2309
2310     case Dali::Actor::Property::POSITION_Z:
2311     {
2312       SetZ( property.Get< float >() );
2313       break;
2314     }
2315
2316     case Dali::Actor::Property::ORIENTATION:
2317     {
2318       SetOrientation( property.Get< Quaternion >() );
2319       break;
2320     }
2321
2322     case Dali::Actor::Property::SCALE:
2323     {
2324       SetScale( property.Get< Vector3 >() );
2325       break;
2326     }
2327
2328     case Dali::Actor::Property::SCALE_X:
2329     {
2330       SetScaleX( property.Get< float >() );
2331       break;
2332     }
2333
2334     case Dali::Actor::Property::SCALE_Y:
2335     {
2336       SetScaleY( property.Get< float >() );
2337       break;
2338     }
2339
2340     case Dali::Actor::Property::SCALE_Z:
2341     {
2342       SetScaleZ( property.Get< float >() );
2343       break;
2344     }
2345
2346     case Dali::Actor::Property::VISIBLE:
2347     {
2348       SetVisible( property.Get< bool >() );
2349       break;
2350     }
2351
2352     case Dali::Actor::Property::COLOR:
2353     {
2354       SetColor( property.Get< Vector4 >() );
2355       break;
2356     }
2357
2358     case Dali::Actor::Property::COLOR_RED:
2359     {
2360       SetColorRed( property.Get< float >() );
2361       break;
2362     }
2363
2364     case Dali::Actor::Property::COLOR_GREEN:
2365     {
2366       SetColorGreen( property.Get< float >() );
2367       break;
2368     }
2369
2370     case Dali::Actor::Property::COLOR_BLUE:
2371     {
2372       SetColorBlue( property.Get< float >() );
2373       break;
2374     }
2375
2376     case Dali::Actor::Property::COLOR_ALPHA:
2377     {
2378       SetOpacity( property.Get< float >() );
2379       break;
2380     }
2381
2382     case Dali::Actor::Property::NAME:
2383     {
2384       SetName( property.Get< std::string >() );
2385       break;
2386     }
2387
2388     case Dali::Actor::Property::SENSITIVE:
2389     {
2390       SetSensitive( property.Get< bool >() );
2391       break;
2392     }
2393
2394     case Dali::Actor::Property::LEAVE_REQUIRED:
2395     {
2396       SetLeaveRequired( property.Get< bool >() );
2397       break;
2398     }
2399
2400     case Dali::Actor::Property::INHERIT_ORIENTATION:
2401     {
2402       SetInheritOrientation( property.Get< bool >() );
2403       break;
2404     }
2405
2406     case Dali::Actor::Property::INHERIT_SCALE:
2407     {
2408       SetInheritScale( property.Get< bool >() );
2409       break;
2410     }
2411
2412     case Dali::Actor::Property::COLOR_MODE:
2413     {
2414       SetColorMode( Scripting::GetColorMode( property.Get< std::string >() ) );
2415       break;
2416     }
2417
2418     case Dali::Actor::Property::POSITION_INHERITANCE:
2419     {
2420       SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get< std::string >() ) );
2421       break;
2422     }
2423
2424     case Dali::Actor::Property::DRAW_MODE:
2425     {
2426       SetDrawMode( Scripting::GetDrawMode( property.Get< std::string >() ) );
2427       break;
2428     }
2429
2430     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2431     {
2432       SetSizeModeFactor( property.Get< Vector3 >() );
2433       break;
2434     }
2435
2436     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2437     {
2438       ResizePolicy::Type type;
2439       if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount, type ) )
2440       {
2441         SetResizePolicy( type, Dimension::WIDTH );
2442       }
2443       break;
2444     }
2445
2446     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2447     {
2448       ResizePolicy::Type type;
2449       if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount, type ) )
2450       {
2451         SetResizePolicy( type, Dimension::HEIGHT );
2452       }
2453       break;
2454     }
2455
2456     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2457     {
2458       SizeScalePolicy::Type type;
2459       if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount, type ) )
2460       {
2461         SetSizeScalePolicy( type );
2462       }
2463       break;
2464     }
2465
2466     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2467     {
2468       if( property.Get< bool >() )
2469       {
2470         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2471       }
2472       break;
2473     }
2474
2475     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2476     {
2477       if( property.Get< bool >() )
2478       {
2479         SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2480       }
2481       break;
2482     }
2483
2484     case Dali::Actor::Property::PADDING:
2485     {
2486       Vector4 padding = property.Get< Vector4 >();
2487       SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2488       SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2489       break;
2490     }
2491
2492     case Dali::Actor::Property::MINIMUM_SIZE:
2493     {
2494       Vector2 size = property.Get< Vector2 >();
2495       SetMinimumSize( size.x, Dimension::WIDTH );
2496       SetMinimumSize( size.y, Dimension::HEIGHT );
2497       break;
2498     }
2499
2500     case Dali::Actor::Property::MAXIMUM_SIZE:
2501     {
2502       Vector2 size = property.Get< Vector2 >();
2503       SetMaximumSize( size.x, Dimension::WIDTH );
2504       SetMaximumSize( size.y, Dimension::HEIGHT );
2505       break;
2506     }
2507
2508     default:
2509     {
2510       // this can happen in the case of a non-animatable default property so just do nothing
2511       break;
2512     }
2513   }
2514 }
2515
2516 // TODO: This method needs to be removed
2517 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2518 {
2519   switch( entry.type )
2520   {
2521     case Property::BOOLEAN:
2522     {
2523       const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2524       DALI_ASSERT_DEBUG( NULL != property );
2525
2526       // property is being used in a separate thread; queue a message to set the property
2527       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2528
2529       break;
2530     }
2531
2532     case Property::INTEGER:
2533     {
2534       const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2535       DALI_ASSERT_DEBUG( NULL != property );
2536
2537       // property is being used in a separate thread; queue a message to set the property
2538       SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2539
2540       break;
2541     }
2542
2543     case Property::FLOAT:
2544     {
2545       const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2546       DALI_ASSERT_DEBUG( NULL != property );
2547
2548       // property is being used in a separate thread; queue a message to set the property
2549       SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2550
2551       break;
2552     }
2553
2554     case Property::VECTOR2:
2555     {
2556       const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2557       DALI_ASSERT_DEBUG( NULL != property );
2558
2559       // property is being used in a separate thread; queue a message to set the property
2560       if(entry.componentIndex == 0)
2561       {
2562         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2563       }
2564       else if(entry.componentIndex == 1)
2565       {
2566         SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2567       }
2568       else
2569       {
2570         SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2571       }
2572
2573       break;
2574     }
2575
2576     case Property::VECTOR3:
2577     {
2578       const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2579       DALI_ASSERT_DEBUG( NULL != property );
2580
2581       // property is being used in a separate thread; queue a message to set the property
2582       if(entry.componentIndex == 0)
2583       {
2584         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2585       }
2586       else if(entry.componentIndex == 1)
2587       {
2588         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2589       }
2590       else if(entry.componentIndex == 2)
2591       {
2592         SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2593       }
2594       else
2595       {
2596         SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2597       }
2598
2599       break;
2600     }
2601
2602     case Property::VECTOR4:
2603     {
2604       const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2605       DALI_ASSERT_DEBUG( NULL != property );
2606
2607       // property is being used in a separate thread; queue a message to set the property
2608       if(entry.componentIndex == 0)
2609       {
2610         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2611       }
2612       else if(entry.componentIndex == 1)
2613       {
2614         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2615       }
2616       else if(entry.componentIndex == 2)
2617       {
2618         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2619       }
2620       else if(entry.componentIndex == 3)
2621       {
2622         SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2623       }
2624       else
2625       {
2626         SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2627       }
2628
2629       break;
2630     }
2631
2632     case Property::ROTATION:
2633     {
2634       const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2635       DALI_ASSERT_DEBUG( NULL != property );
2636
2637       // property is being used in a separate thread; queue a message to set the property
2638       SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
2639
2640       break;
2641     }
2642
2643     case Property::MATRIX:
2644     {
2645       const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2646       DALI_ASSERT_DEBUG( NULL != property );
2647
2648       // property is being used in a separate thread; queue a message to set the property
2649       SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
2650
2651       break;
2652     }
2653
2654     case Property::MATRIX3:
2655     {
2656       const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2657       DALI_ASSERT_DEBUG( NULL != property );
2658
2659       // property is being used in a separate thread; queue a message to set the property
2660       SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
2661
2662       break;
2663     }
2664
2665     default:
2666     {
2667       DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2668       break;
2669     }
2670   }
2671 }
2672
2673 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2674 {
2675   Property::Value value;
2676
2677   switch( index )
2678   {
2679     case Dali::Actor::Property::PARENT_ORIGIN:
2680     {
2681       value = GetCurrentParentOrigin();
2682       break;
2683     }
2684
2685     case Dali::Actor::Property::PARENT_ORIGIN_X:
2686     {
2687       value = GetCurrentParentOrigin().x;
2688       break;
2689     }
2690
2691     case Dali::Actor::Property::PARENT_ORIGIN_Y:
2692     {
2693       value = GetCurrentParentOrigin().y;
2694       break;
2695     }
2696
2697     case Dali::Actor::Property::PARENT_ORIGIN_Z:
2698     {
2699       value = GetCurrentParentOrigin().z;
2700       break;
2701     }
2702
2703     case Dali::Actor::Property::ANCHOR_POINT:
2704     {
2705       value = GetCurrentAnchorPoint();
2706       break;
2707     }
2708
2709     case Dali::Actor::Property::ANCHOR_POINT_X:
2710     {
2711       value = GetCurrentAnchorPoint().x;
2712       break;
2713     }
2714
2715     case Dali::Actor::Property::ANCHOR_POINT_Y:
2716     {
2717       value = GetCurrentAnchorPoint().y;
2718       break;
2719     }
2720
2721     case Dali::Actor::Property::ANCHOR_POINT_Z:
2722     {
2723       value = GetCurrentAnchorPoint().z;
2724       break;
2725     }
2726
2727     case Dali::Actor::Property::SIZE:
2728     {
2729       value = GetCurrentSize();
2730       break;
2731     }
2732
2733     case Dali::Actor::Property::SIZE_WIDTH:
2734     {
2735       value = GetCurrentSize().width;
2736       break;
2737     }
2738
2739     case Dali::Actor::Property::SIZE_HEIGHT:
2740     {
2741       value = GetCurrentSize().height;
2742       break;
2743     }
2744
2745     case Dali::Actor::Property::SIZE_DEPTH:
2746     {
2747       value = GetCurrentSize().depth;
2748       break;
2749     }
2750
2751     case Dali::Actor::Property::POSITION:
2752     {
2753       value = GetCurrentPosition();
2754       break;
2755     }
2756
2757     case Dali::Actor::Property::POSITION_X:
2758     {
2759       value = GetCurrentPosition().x;
2760       break;
2761     }
2762
2763     case Dali::Actor::Property::POSITION_Y:
2764     {
2765       value = GetCurrentPosition().y;
2766       break;
2767     }
2768
2769     case Dali::Actor::Property::POSITION_Z:
2770     {
2771       value = GetCurrentPosition().z;
2772       break;
2773     }
2774
2775     case Dali::Actor::Property::WORLD_POSITION:
2776     {
2777       value = GetCurrentWorldPosition();
2778       break;
2779     }
2780
2781     case Dali::Actor::Property::WORLD_POSITION_X:
2782     {
2783       value = GetCurrentWorldPosition().x;
2784       break;
2785     }
2786
2787     case Dali::Actor::Property::WORLD_POSITION_Y:
2788     {
2789       value = GetCurrentWorldPosition().y;
2790       break;
2791     }
2792
2793     case Dali::Actor::Property::WORLD_POSITION_Z:
2794     {
2795       value = GetCurrentWorldPosition().z;
2796       break;
2797     }
2798
2799     case Dali::Actor::Property::ORIENTATION:
2800     {
2801       value = GetCurrentOrientation();
2802       break;
2803     }
2804
2805     case Dali::Actor::Property::WORLD_ORIENTATION:
2806     {
2807       value = GetCurrentWorldOrientation();
2808       break;
2809     }
2810
2811     case Dali::Actor::Property::SCALE:
2812     {
2813       value = GetCurrentScale();
2814       break;
2815     }
2816
2817     case Dali::Actor::Property::SCALE_X:
2818     {
2819       value = GetCurrentScale().x;
2820       break;
2821     }
2822
2823     case Dali::Actor::Property::SCALE_Y:
2824     {
2825       value = GetCurrentScale().y;
2826       break;
2827     }
2828
2829     case Dali::Actor::Property::SCALE_Z:
2830     {
2831       value = GetCurrentScale().z;
2832       break;
2833     }
2834
2835     case Dali::Actor::Property::WORLD_SCALE:
2836     {
2837       value = GetCurrentWorldScale();
2838       break;
2839     }
2840
2841     case Dali::Actor::Property::VISIBLE:
2842     {
2843       value = IsVisible();
2844       break;
2845     }
2846
2847     case Dali::Actor::Property::COLOR:
2848     {
2849       value = GetCurrentColor();
2850       break;
2851     }
2852
2853     case Dali::Actor::Property::COLOR_RED:
2854     {
2855       value = GetCurrentColor().r;
2856       break;
2857     }
2858
2859     case Dali::Actor::Property::COLOR_GREEN:
2860     {
2861       value = GetCurrentColor().g;
2862       break;
2863     }
2864
2865     case Dali::Actor::Property::COLOR_BLUE:
2866     {
2867       value = GetCurrentColor().b;
2868       break;
2869     }
2870
2871     case Dali::Actor::Property::COLOR_ALPHA:
2872     {
2873       value = GetCurrentColor().a;
2874       break;
2875     }
2876
2877     case Dali::Actor::Property::WORLD_COLOR:
2878     {
2879       value = GetCurrentWorldColor();
2880       break;
2881     }
2882
2883     case Dali::Actor::Property::WORLD_MATRIX:
2884     {
2885       value = GetCurrentWorldMatrix();
2886       break;
2887     }
2888
2889     case Dali::Actor::Property::NAME:
2890     {
2891       value = GetName();
2892       break;
2893     }
2894
2895     case Dali::Actor::Property::SENSITIVE:
2896     {
2897       value = IsSensitive();
2898       break;
2899     }
2900
2901     case Dali::Actor::Property::LEAVE_REQUIRED:
2902     {
2903       value = GetLeaveRequired();
2904       break;
2905     }
2906
2907     case Dali::Actor::Property::INHERIT_ORIENTATION:
2908     {
2909       value = IsOrientationInherited();
2910       break;
2911     }
2912
2913     case Dali::Actor::Property::INHERIT_SCALE:
2914     {
2915       value = IsScaleInherited();
2916       break;
2917     }
2918
2919     case Dali::Actor::Property::COLOR_MODE:
2920     {
2921       value = Scripting::GetColorMode( GetColorMode() );
2922       break;
2923     }
2924
2925     case Dali::Actor::Property::POSITION_INHERITANCE:
2926     {
2927       value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2928       break;
2929     }
2930
2931     case Dali::Actor::Property::DRAW_MODE:
2932     {
2933       value = Scripting::GetDrawMode( GetDrawMode() );
2934       break;
2935     }
2936
2937     case Dali::Actor::Property::SIZE_MODE_FACTOR:
2938     {
2939       value = GetSizeModeFactor();
2940       break;
2941     }
2942
2943     case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2944     {
2945       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount );
2946       break;
2947     }
2948
2949     case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2950     {
2951       value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount );
2952       break;
2953     }
2954
2955     case Dali::Actor::Property::SIZE_SCALE_POLICY:
2956     {
2957       value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount );
2958       break;
2959     }
2960
2961     case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2962     {
2963       value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
2964       break;
2965     }
2966
2967     case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2968     {
2969       value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
2970       break;
2971     }
2972
2973     case Dali::Actor::Property::PADDING:
2974     {
2975       Vector2 widthPadding = GetPadding( Dimension::WIDTH );
2976       Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
2977       value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
2978       break;
2979     }
2980
2981     case Dali::Actor::Property::MINIMUM_SIZE:
2982     {
2983       value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
2984       break;
2985     }
2986
2987     case Dali::Actor::Property::MAXIMUM_SIZE:
2988     {
2989       value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
2990       break;
2991     }
2992
2993     default:
2994     {
2995       DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
2996       break;
2997     }
2998   }
2999
3000   return value;
3001 }
3002
3003 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3004 {
3005   return mNode;
3006 }
3007
3008 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3009 {
3010   // This method should only return an object connected to the scene-graph
3011   return OnStage() ? mNode : NULL;
3012 }
3013
3014 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3015 {
3016   DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3017
3018   const PropertyBase* property( NULL );
3019
3020   // This method should only return a property of an object connected to the scene-graph
3021   if( !OnStage() )
3022   {
3023     return property;
3024   }
3025
3026   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3027   {
3028     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3029     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3030
3031     property = animatable->GetSceneGraphProperty();
3032   }
3033   else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3034   {
3035     CustomPropertyMetadata* custom = FindCustomProperty( index );
3036     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3037
3038     property = custom->GetSceneGraphProperty();
3039   }
3040   else if( NULL != mNode )
3041   {
3042     switch( index )
3043     {
3044       case Dali::Actor::Property::SIZE:
3045         property = &mNode->mSize;
3046         break;
3047
3048       case Dali::Actor::Property::SIZE_WIDTH:
3049         property = &mNode->mSize;
3050         break;
3051
3052       case Dali::Actor::Property::SIZE_HEIGHT:
3053         property = &mNode->mSize;
3054         break;
3055
3056       case Dali::Actor::Property::SIZE_DEPTH:
3057         property = &mNode->mSize;
3058         break;
3059
3060       case Dali::Actor::Property::POSITION:
3061         property = &mNode->mPosition;
3062         break;
3063
3064       case Dali::Actor::Property::POSITION_X:
3065         property = &mNode->mPosition;
3066         break;
3067
3068       case Dali::Actor::Property::POSITION_Y:
3069         property = &mNode->mPosition;
3070         break;
3071
3072       case Dali::Actor::Property::POSITION_Z:
3073         property = &mNode->mPosition;
3074         break;
3075
3076       case Dali::Actor::Property::ORIENTATION:
3077         property = &mNode->mOrientation;
3078         break;
3079
3080       case Dali::Actor::Property::SCALE:
3081         property = &mNode->mScale;
3082         break;
3083
3084       case Dali::Actor::Property::SCALE_X:
3085         property = &mNode->mScale;
3086         break;
3087
3088       case Dali::Actor::Property::SCALE_Y:
3089         property = &mNode->mScale;
3090         break;
3091
3092       case Dali::Actor::Property::SCALE_Z:
3093         property = &mNode->mScale;
3094         break;
3095
3096       case Dali::Actor::Property::VISIBLE:
3097         property = &mNode->mVisible;
3098         break;
3099
3100       case Dali::Actor::Property::COLOR:
3101         property = &mNode->mColor;
3102         break;
3103
3104       case Dali::Actor::Property::COLOR_RED:
3105         property = &mNode->mColor;
3106         break;
3107
3108       case Dali::Actor::Property::COLOR_GREEN:
3109         property = &mNode->mColor;
3110         break;
3111
3112       case Dali::Actor::Property::COLOR_BLUE:
3113         property = &mNode->mColor;
3114         break;
3115
3116       case Dali::Actor::Property::COLOR_ALPHA:
3117         property = &mNode->mColor;
3118         break;
3119
3120       default:
3121         break;
3122     }
3123   }
3124
3125   return property;
3126 }
3127
3128 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3129 {
3130   const PropertyInputImpl* property( NULL );
3131
3132   // This method should only return a property of an object connected to the scene-graph
3133   if( !OnStage() )
3134   {
3135     return property;
3136   }
3137
3138   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3139   {
3140     AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3141     DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3142
3143     property = animatable->GetSceneGraphProperty();
3144   }
3145   else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3146   {
3147     CustomPropertyMetadata* custom = FindCustomProperty( index );
3148     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3149     property = custom->GetSceneGraphProperty();
3150   }
3151   else if( NULL != mNode )
3152   {
3153     switch( index )
3154     {
3155       case Dali::Actor::Property::PARENT_ORIGIN:
3156         property = &mNode->mParentOrigin;
3157         break;
3158
3159       case Dali::Actor::Property::PARENT_ORIGIN_X:
3160         property = &mNode->mParentOrigin;
3161         break;
3162
3163       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3164         property = &mNode->mParentOrigin;
3165         break;
3166
3167       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3168         property = &mNode->mParentOrigin;
3169         break;
3170
3171       case Dali::Actor::Property::ANCHOR_POINT:
3172         property = &mNode->mAnchorPoint;
3173         break;
3174
3175       case Dali::Actor::Property::ANCHOR_POINT_X:
3176         property = &mNode->mAnchorPoint;
3177         break;
3178
3179       case Dali::Actor::Property::ANCHOR_POINT_Y:
3180         property = &mNode->mAnchorPoint;
3181         break;
3182
3183       case Dali::Actor::Property::ANCHOR_POINT_Z:
3184         property = &mNode->mAnchorPoint;
3185         break;
3186
3187       case Dali::Actor::Property::SIZE:
3188         property = &mNode->mSize;
3189         break;
3190
3191       case Dali::Actor::Property::SIZE_WIDTH:
3192         property = &mNode->mSize;
3193         break;
3194
3195       case Dali::Actor::Property::SIZE_HEIGHT:
3196         property = &mNode->mSize;
3197         break;
3198
3199       case Dali::Actor::Property::SIZE_DEPTH:
3200         property = &mNode->mSize;
3201         break;
3202
3203       case Dali::Actor::Property::POSITION:
3204         property = &mNode->mPosition;
3205         break;
3206
3207       case Dali::Actor::Property::POSITION_X:
3208         property = &mNode->mPosition;
3209         break;
3210
3211       case Dali::Actor::Property::POSITION_Y:
3212         property = &mNode->mPosition;
3213         break;
3214
3215       case Dali::Actor::Property::POSITION_Z:
3216         property = &mNode->mPosition;
3217         break;
3218
3219       case Dali::Actor::Property::WORLD_POSITION:
3220         property = &mNode->mWorldPosition;
3221         break;
3222
3223       case Dali::Actor::Property::WORLD_POSITION_X:
3224         property = &mNode->mWorldPosition;
3225         break;
3226
3227       case Dali::Actor::Property::WORLD_POSITION_Y:
3228         property = &mNode->mWorldPosition;
3229         break;
3230
3231       case Dali::Actor::Property::WORLD_POSITION_Z:
3232         property = &mNode->mWorldPosition;
3233         break;
3234
3235       case Dali::Actor::Property::ORIENTATION:
3236         property = &mNode->mOrientation;
3237         break;
3238
3239       case Dali::Actor::Property::WORLD_ORIENTATION:
3240         property = &mNode->mWorldOrientation;
3241         break;
3242
3243       case Dali::Actor::Property::SCALE:
3244         property = &mNode->mScale;
3245         break;
3246
3247       case Dali::Actor::Property::SCALE_X:
3248         property = &mNode->mScale;
3249         break;
3250
3251       case Dali::Actor::Property::SCALE_Y:
3252         property = &mNode->mScale;
3253         break;
3254
3255       case Dali::Actor::Property::SCALE_Z:
3256         property = &mNode->mScale;
3257         break;
3258
3259       case Dali::Actor::Property::WORLD_SCALE:
3260         property = &mNode->mWorldScale;
3261         break;
3262
3263       case Dali::Actor::Property::VISIBLE:
3264         property = &mNode->mVisible;
3265         break;
3266
3267       case Dali::Actor::Property::COLOR:
3268         property = &mNode->mColor;
3269         break;
3270
3271       case Dali::Actor::Property::COLOR_RED:
3272         property = &mNode->mColor;
3273         break;
3274
3275       case Dali::Actor::Property::COLOR_GREEN:
3276         property = &mNode->mColor;
3277         break;
3278
3279       case Dali::Actor::Property::COLOR_BLUE:
3280         property = &mNode->mColor;
3281         break;
3282
3283       case Dali::Actor::Property::COLOR_ALPHA:
3284         property = &mNode->mColor;
3285         break;
3286
3287       case Dali::Actor::Property::WORLD_COLOR:
3288         property = &mNode->mWorldColor;
3289         break;
3290
3291       case Dali::Actor::Property::WORLD_MATRIX:
3292         property = &mNode->mWorldMatrix;
3293         break;
3294
3295       default:
3296         break;
3297     }
3298   }
3299
3300   return property;
3301 }
3302
3303 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3304 {
3305   int componentIndex( Property::INVALID_COMPONENT_INDEX );
3306
3307   if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3308   {
3309     // check whether the animatable property is registered already, if not then register one.
3310     AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3311     if( animatableProperty )
3312     {
3313       componentIndex = animatableProperty->componentIndex;
3314     }
3315   }
3316   else
3317   {
3318     switch( index )
3319     {
3320       case Dali::Actor::Property::PARENT_ORIGIN_X:
3321       case Dali::Actor::Property::ANCHOR_POINT_X:
3322       case Dali::Actor::Property::SIZE_WIDTH:
3323       case Dali::Actor::Property::POSITION_X:
3324       case Dali::Actor::Property::WORLD_POSITION_X:
3325       case Dali::Actor::Property::SCALE_X:
3326       case Dali::Actor::Property::COLOR_RED:
3327       {
3328         componentIndex = 0;
3329         break;
3330       }
3331
3332       case Dali::Actor::Property::PARENT_ORIGIN_Y:
3333       case Dali::Actor::Property::ANCHOR_POINT_Y:
3334       case Dali::Actor::Property::SIZE_HEIGHT:
3335       case Dali::Actor::Property::POSITION_Y:
3336       case Dali::Actor::Property::WORLD_POSITION_Y:
3337       case Dali::Actor::Property::SCALE_Y:
3338       case Dali::Actor::Property::COLOR_GREEN:
3339       {
3340         componentIndex = 1;
3341         break;
3342       }
3343
3344       case Dali::Actor::Property::PARENT_ORIGIN_Z:
3345       case Dali::Actor::Property::ANCHOR_POINT_Z:
3346       case Dali::Actor::Property::SIZE_DEPTH:
3347       case Dali::Actor::Property::POSITION_Z:
3348       case Dali::Actor::Property::WORLD_POSITION_Z:
3349       case Dali::Actor::Property::SCALE_Z:
3350       case Dali::Actor::Property::COLOR_BLUE:
3351       {
3352         componentIndex = 2;
3353         break;
3354       }
3355
3356       case Dali::Actor::Property::COLOR_ALPHA:
3357       {
3358         componentIndex = 3;
3359         break;
3360       }
3361
3362       default:
3363       {
3364         // Do nothing
3365         break;
3366       }
3367     }
3368   }
3369
3370   return componentIndex;
3371 }
3372
3373 void Actor::SetParent( Actor* parent, int index )
3374 {
3375   if( parent )
3376   {
3377     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3378
3379     mParent = parent;
3380
3381     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3382          parent->OnStage() )
3383     {
3384       // Instruct each actor to create a corresponding node in the scene graph
3385       ConnectToStage( parent->GetHierarchyDepth(), index );
3386     }
3387   }
3388   else // parent being set to NULL
3389   {
3390     DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3391
3392     mParent = NULL;
3393
3394     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3395          OnStage() )
3396     {
3397       DALI_ASSERT_ALWAYS( mNode != NULL );
3398
3399       if( NULL != mNode )
3400       {
3401         // Disconnect the Node & its children from the scene-graph.
3402         DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3403       }
3404
3405       // Instruct each actor to discard pointers to the scene-graph
3406       DisconnectFromStage();
3407     }
3408   }
3409 }
3410
3411 SceneGraph::Node* Actor::CreateNode() const
3412 {
3413   return Node::New();
3414 }
3415
3416 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3417 {
3418   bool done = false;
3419   Actor* actor = dynamic_cast< Actor* >( object );
3420
3421   if( actor )
3422   {
3423     if( 0 == actionName.compare( ACTION_SHOW ) )
3424     {
3425       actor->SetVisible( true );
3426       done = true;
3427     }
3428     else if( 0 == actionName.compare( ACTION_HIDE ) )
3429     {
3430       actor->SetVisible( false );
3431       done = true;
3432     }
3433   }
3434
3435   return done;
3436 }
3437
3438 void Actor::EnsureRelayoutData()
3439 {
3440   // Assign relayout data.
3441   if( !mRelayoutData )
3442   {
3443     mRelayoutData = new RelayoutData();
3444   }
3445 }
3446
3447 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3448 {
3449   // Check if actor is dependent on parent
3450   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3451   {
3452     if( ( dimension & ( 1 << i ) ) )
3453     {
3454       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3455       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3456       {
3457         return true;
3458       }
3459     }
3460   }
3461
3462   return false;
3463 }
3464
3465 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3466 {
3467   // Check if actor is dependent on children
3468   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3469   {
3470     if( ( dimension & ( 1 << i ) ) )
3471     {
3472       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3473       switch( resizePolicy )
3474       {
3475         case ResizePolicy::FIT_TO_CHILDREN:
3476         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
3477         {
3478           return true;
3479         }
3480
3481         default:
3482         {
3483           break;
3484         }
3485       }
3486     }
3487   }
3488
3489   return false;
3490 }
3491
3492 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3493 {
3494   return Actor::RelayoutDependentOnChildren( dimension );
3495 }
3496
3497 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3498 {
3499   // Check each possible dimension and see if it is dependent on the input one
3500   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3501   {
3502     if( dimension & ( 1 << i ) )
3503     {
3504       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3505     }
3506   }
3507
3508   return false;
3509 }
3510
3511 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3512 {
3513   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3514   {
3515     if( dimension & ( 1 << i ) )
3516     {
3517       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3518     }
3519   }
3520 }
3521
3522 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3523 {
3524   // If more than one dimension is requested, just return the first one found
3525   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3526   {
3527     if( ( dimension & ( 1 << i ) ) )
3528     {
3529       return mRelayoutData->negotiatedDimensions[ i ];
3530     }
3531   }
3532
3533   return 0.0f;   // Default
3534 }
3535
3536 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3537 {
3538   EnsureRelayoutData();
3539
3540   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3541   {
3542     if( dimension & ( 1 << i ) )
3543     {
3544       mRelayoutData->dimensionPadding[ i ] = padding;
3545     }
3546   }
3547 }
3548
3549 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3550 {
3551   if ( mRelayoutData )
3552   {
3553     // If more than one dimension is requested, just return the first one found
3554     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3555     {
3556       if( ( dimension & ( 1 << i ) ) )
3557       {
3558         return mRelayoutData->dimensionPadding[ i ];
3559       }
3560     }
3561   }
3562
3563   return GetDefaultDimensionPadding();
3564 }
3565
3566 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3567 {
3568   EnsureRelayoutData();
3569
3570   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3571   {
3572     if( dimension & ( 1 << i ) )
3573     {
3574       mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3575     }
3576   }
3577 }
3578
3579 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3580 {
3581   if ( mRelayoutData )
3582   {
3583     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3584     {
3585       if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3586       {
3587         return true;
3588       }
3589     }
3590   }
3591
3592   return false;
3593 }
3594
3595 float Actor::GetHeightForWidthBase( float width )
3596 {
3597   float height = 0.0f;
3598
3599   const Vector3 naturalSize = GetNaturalSize();
3600   if( naturalSize.width > 0.0f )
3601   {
3602     height = naturalSize.height * width / naturalSize.width;
3603   }
3604   else // we treat 0 as 1:1 aspect ratio
3605   {
3606     height = width;
3607   }
3608
3609   return height;
3610 }
3611
3612 float Actor::GetWidthForHeightBase( float height )
3613 {
3614   float width = 0.0f;
3615
3616   const Vector3 naturalSize = GetNaturalSize();
3617   if( naturalSize.height > 0.0f )
3618   {
3619     width = naturalSize.width * height / naturalSize.height;
3620   }
3621   else // we treat 0 as 1:1 aspect ratio
3622   {
3623     width = height;
3624   }
3625
3626   return width;
3627 }
3628
3629 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3630 {
3631   // Fill to parent, taking size mode factor into account
3632   switch( child.GetResizePolicy( dimension ) )
3633   {
3634     case ResizePolicy::FILL_TO_PARENT:
3635     {
3636       return GetLatestSize( dimension );
3637     }
3638
3639     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3640     {
3641       return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3642     }
3643
3644     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3645     {
3646       return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3647     }
3648
3649     default:
3650     {
3651       return GetLatestSize( dimension );
3652     }
3653   }
3654 }
3655
3656 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3657 {
3658   // Can be overridden in derived class
3659   return CalculateChildSizeBase( child, dimension );
3660 }
3661
3662 float Actor::GetHeightForWidth( float width )
3663 {
3664   // Can be overridden in derived class
3665   return GetHeightForWidthBase( width );
3666 }
3667
3668 float Actor::GetWidthForHeight( float height )
3669 {
3670   // Can be overridden in derived class
3671   return GetWidthForHeightBase( height );
3672 }
3673
3674 float Actor::GetLatestSize( Dimension::Type dimension ) const
3675 {
3676   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3677 }
3678
3679 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3680 {
3681   Vector2 padding = GetPadding( dimension );
3682
3683   return GetLatestSize( dimension ) + padding.x + padding.y;
3684 }
3685
3686 float Actor::NegotiateFromParent( Dimension::Type dimension )
3687 {
3688   Actor* parent = GetParent();
3689   if( parent )
3690   {
3691     Vector2 padding( GetPadding( dimension ) );
3692     Vector2 parentPadding( parent->GetPadding( dimension ) );
3693     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3694   }
3695
3696   return 0.0f;
3697 }
3698
3699 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3700 {
3701   float maxDimensionPoint = 0.0f;
3702
3703   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3704   {
3705     ActorPtr child = GetChildAt( i );
3706
3707     if( !child->RelayoutDependentOnParent( dimension ) )
3708     {
3709       // Calculate the min and max points that the children range across
3710       float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3711       float dimensionSize = child->GetRelayoutSize( dimension );
3712       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3713     }
3714   }
3715
3716   return maxDimensionPoint;
3717 }
3718
3719 float Actor::GetSize( Dimension::Type dimension ) const
3720 {
3721   return GetDimensionValue( GetTargetSize(), dimension );
3722 }
3723
3724 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3725 {
3726   return GetDimensionValue( GetNaturalSize(), dimension );
3727 }
3728
3729 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3730 {
3731   switch( GetResizePolicy( dimension ) )
3732   {
3733     case ResizePolicy::USE_NATURAL_SIZE:
3734     {
3735       return GetNaturalSize( dimension );
3736     }
3737
3738     case ResizePolicy::FIXED:
3739     {
3740       return GetDimensionValue( GetPreferredSize(), dimension );
3741     }
3742
3743     case ResizePolicy::USE_ASSIGNED_SIZE:
3744     {
3745       return GetDimensionValue( maximumSize, dimension );
3746     }
3747
3748     case ResizePolicy::FILL_TO_PARENT:
3749     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3750     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3751     {
3752       return NegotiateFromParent( dimension );
3753     }
3754
3755     case ResizePolicy::FIT_TO_CHILDREN:
3756     {
3757       return NegotiateFromChildren( dimension );
3758     }
3759
3760     case ResizePolicy::DIMENSION_DEPENDENCY:
3761     {
3762       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3763
3764       // Custom rules
3765       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3766       {
3767         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3768       }
3769
3770       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3771       {
3772         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3773       }
3774
3775       break;
3776     }
3777
3778     default:
3779     {
3780       break;
3781     }
3782   }
3783
3784   return 0.0f;  // Default
3785 }
3786
3787 float Actor::ClampDimension( float size, Dimension::Type dimension )
3788 {
3789   const float minSize = GetMinimumSize( dimension );
3790   const float maxSize = GetMaximumSize( dimension );
3791
3792   return std::max( minSize, std::min( size, maxSize ) );
3793 }
3794
3795 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
3796 {
3797   // Check if it needs to be negotiated
3798   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
3799   {
3800     // Check that we havn't gotten into an infinite loop
3801     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
3802     bool recursionFound = false;
3803     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
3804     {
3805       if( *it == searchActor )
3806       {
3807         recursionFound = true;
3808         break;
3809       }
3810     }
3811
3812     if( !recursionFound )
3813     {
3814       // Record the path that we have taken
3815       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
3816
3817       // Dimension dependency check
3818       for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3819       {
3820         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
3821
3822         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
3823         {
3824           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
3825         }
3826       }
3827
3828       // Parent dependency check
3829       Actor* parent = GetParent();
3830       if( parent && RelayoutDependentOnParent( dimension ) )
3831       {
3832         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
3833       }
3834
3835       // Children dependency check
3836       if( RelayoutDependentOnChildren( dimension ) )
3837       {
3838         for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3839         {
3840           ActorPtr child = GetChildAt( i );
3841
3842           // Only relayout child first if it is not dependent on this actor
3843           if( !child->RelayoutDependentOnParent( dimension ) )
3844           {
3845             child->NegotiateDimension( dimension, allocatedSize, recursionStack );
3846           }
3847         }
3848       }
3849
3850       // For deriving classes
3851       OnCalculateRelayoutSize( dimension );
3852
3853       // All dependencies checked, calculate the size and set negotiated flag
3854       const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
3855
3856       SetNegotiatedDimension( newSize, dimension );
3857       SetLayoutNegotiated( true, dimension );
3858
3859       // For deriving classes
3860       OnLayoutNegotiated( newSize, dimension );
3861
3862       // This actor has been successfully processed, pop it off the recursion stack
3863       recursionStack.pop_back();
3864     }
3865     else
3866     {
3867       // TODO: Break infinite loop
3868       SetLayoutNegotiated( true, dimension );
3869     }
3870   }
3871 }
3872
3873 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
3874 {
3875   // Negotiate all dimensions that require it
3876   ActorDimensionStack recursionStack;
3877
3878   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3879   {
3880     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
3881
3882     // Negotiate
3883     NegotiateDimension( dimension, allocatedSize, recursionStack );
3884   }
3885 }
3886
3887 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
3888 {
3889   switch( mRelayoutData->sizeSetPolicy )
3890   {
3891     case SizeScalePolicy::USE_SIZE_SET:
3892     {
3893       return size;
3894     }
3895
3896     case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
3897     {
3898       // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
3899       const Vector3 naturalSize = GetNaturalSize();
3900       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
3901       {
3902         const float sizeRatio = size.width / size.height;
3903         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
3904
3905         if( naturalSizeRatio < sizeRatio )
3906         {
3907           return Vector2( naturalSizeRatio * size.height, size.height );
3908         }
3909         else if( naturalSizeRatio > sizeRatio )
3910         {
3911           return Vector2( size.width, size.width / naturalSizeRatio );
3912         }
3913         else
3914         {
3915           return size;
3916         }
3917       }
3918
3919       break;
3920     }
3921
3922     case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
3923     {
3924       // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
3925       const Vector3 naturalSize = GetNaturalSize();
3926       if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
3927       {
3928         const float sizeRatio = size.width / size.height;
3929         const float naturalSizeRatio = naturalSize.width / naturalSize.height;
3930
3931         if( naturalSizeRatio < sizeRatio )
3932         {
3933           return Vector2( size.width, size.width / naturalSizeRatio );
3934         }
3935         else if( naturalSizeRatio > sizeRatio )
3936         {
3937           return Vector2( naturalSizeRatio * size.height, size.height );
3938         }
3939         else
3940         {
3941           return size;
3942         }
3943       }
3944     }
3945
3946     default:
3947     {
3948       break;
3949     }
3950   }
3951
3952   return size;
3953 }
3954
3955 void Actor::SetNegotiatedSize( RelayoutContainer& container )
3956 {
3957   // Do the set actor size
3958   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
3959
3960   // Adjust for size set policy
3961   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
3962
3963   // Lock the flag to stop recursive relayouts on set size
3964   mRelayoutData->insideRelayout = true;
3965   SetSize( negotiatedSize );
3966   mRelayoutData->insideRelayout = false;
3967
3968   // Clear flags for all dimensions
3969   SetLayoutDirty( false );
3970
3971   // Give deriving classes a chance to respond
3972   OnRelayout( negotiatedSize, container );
3973
3974   if( !mOnRelayoutSignal.Empty() )
3975   {
3976     Dali::Actor handle( this );
3977     mOnRelayoutSignal.Emit( handle );
3978   }
3979 }
3980
3981 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
3982 {
3983   // Do the negotiation
3984   NegotiateDimensions( allocatedSize );
3985
3986   // Set the actor size
3987   SetNegotiatedSize( container );
3988
3989   // Negotiate down to children
3990   const Vector2 newBounds = GetTargetSize().GetVectorXY();
3991
3992   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3993   {
3994     ActorPtr child = GetChildAt( i );
3995
3996     // Only relayout if required
3997     if( child->RelayoutRequired() )
3998     {
3999       container.Add( Dali::Actor( child.Get() ), newBounds );
4000     }
4001   }
4002 }
4003
4004 void Actor::RelayoutRequest( Dimension::Type dimension )
4005 {
4006   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4007   if( relayoutController )
4008   {
4009     Dali::Actor self( this );
4010     relayoutController->RequestRelayout( self, dimension );
4011   }
4012 }
4013
4014 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4015 {
4016 }
4017
4018 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4019 {
4020 }
4021
4022 void Actor::SetPreferredSize( const Vector2& size )
4023 {
4024   EnsureRelayoutData();
4025
4026   if( size.width > 0.0f )
4027   {
4028     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4029   }
4030
4031   if( size.height > 0.0f )
4032   {
4033     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4034   }
4035
4036   mRelayoutData->preferredSize = size;
4037
4038   RelayoutRequest();
4039 }
4040
4041 Vector2 Actor::GetPreferredSize() const
4042 {
4043   if ( mRelayoutData )
4044   {
4045     return mRelayoutData->preferredSize;
4046   }
4047
4048   return GetDefaultPreferredSize();
4049 }
4050
4051 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4052 {
4053   EnsureRelayoutData();
4054
4055   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4056   {
4057     if( dimension & ( 1 << i ) )
4058     {
4059       mRelayoutData->minimumSize[ i ] = size;
4060     }
4061   }
4062
4063   RelayoutRequest();
4064 }
4065
4066 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4067 {
4068   if ( mRelayoutData )
4069   {
4070     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4071     {
4072       if( dimension & ( 1 << i ) )
4073       {
4074         return mRelayoutData->minimumSize[ i ];
4075       }
4076     }
4077   }
4078
4079   return 0.0f;  // Default
4080 }
4081
4082 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4083 {
4084   EnsureRelayoutData();
4085
4086   for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4087   {
4088     if( dimension & ( 1 << i ) )
4089     {
4090       mRelayoutData->maximumSize[ i ] = size;
4091     }
4092   }
4093
4094   RelayoutRequest();
4095 }
4096
4097 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4098 {
4099   if ( mRelayoutData )
4100   {
4101     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4102     {
4103       if( dimension & ( 1 << i ) )
4104       {
4105         return mRelayoutData->maximumSize[ i ];
4106       }
4107     }
4108   }
4109
4110   return FLT_MAX;  // Default
4111 }
4112
4113 } // namespace Internal
4114
4115 } // namespace Dali