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