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