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