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