2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/event/actors/actor-impl.h>
25 #include <cstring> // for strcmp
29 #include <dali/public-api/common/dali-common.h>
30 #include <dali/public-api/common/constants.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/public-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
46 #include <dali/internal/event/animation/constraint-impl.h>
47 #include <dali/internal/event/common/projection.h>
48 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
49 #include <dali/internal/update/common/animatable-property.h>
50 #include <dali/internal/update/nodes/node-messages.h>
51 #include <dali/internal/update/nodes/node-declarations.h>
52 #include <dali/internal/update/animation/scene-graph-constraint.h>
53 #include <dali/internal/event/events/actor-gesture-data.h>
54 #include <dali/internal/common/message.h>
55 #include <dali/integration-api/debug.h>
57 #ifdef DYNAMICS_SUPPORT
58 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
59 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
60 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
61 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
64 using Dali::Internal::SceneGraph::Node;
65 using Dali::Internal::SceneGraph::AnimatableProperty;
66 using Dali::Internal::SceneGraph::PropertyBase;
70 namespace ResizePolicy
75 DALI_ENUM_TO_STRING_TABLE_BEGIN( Type )DALI_ENUM_TO_STRING( FIXED )
76 DALI_ENUM_TO_STRING( USE_NATURAL_SIZE )
77 DALI_ENUM_TO_STRING( FILL_TO_PARENT )
78 DALI_ENUM_TO_STRING( SIZE_RELATIVE_TO_PARENT )
79 DALI_ENUM_TO_STRING( SIZE_FIXED_OFFSET_FROM_PARENT )
80 DALI_ENUM_TO_STRING( FIT_TO_CHILDREN )
81 DALI_ENUM_TO_STRING( DIMENSION_DEPENDENCY )
82 DALI_ENUM_TO_STRING( USE_ASSIGNED_SIZE )
83 DALI_ENUM_TO_STRING_TABLE_END( Type )
85 } // unnamed namespace
88 namespace SizeScalePolicy
92 // Enumeration to / from string conversion tables
93 DALI_ENUM_TO_STRING_TABLE_BEGIN( Type )DALI_ENUM_TO_STRING( USE_SIZE_SET )
94 DALI_ENUM_TO_STRING( FIT_WITH_ASPECT_RATIO )
95 DALI_ENUM_TO_STRING( FILL_WITH_ASPECT_RATIO )
96 DALI_ENUM_TO_STRING_TABLE_END( Type )
97 } // unnamed namespace
103 unsigned int Actor::mActorCounter = 0;
104 ActorContainer Actor::mNullChildren;
107 * Struct to collect relayout variables
109 struct Actor::RelayoutData
112 : sizeModeFactor( Vector3::ONE ), preferredSize( Vector2::ZERO ), sizeSetPolicy( SizeScalePolicy::USE_SIZE_SET ), relayoutEnabled( false ), insideRelayout( false )
114 // Set size negotiation defaults
115 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
117 resizePolicies[ i ] = ResizePolicy::FIXED;
118 negotiatedDimensions[ i ] = 0.0f;
119 dimensionNegotiated[ i ] = false;
120 dimensionDirty[ i ] = false;
121 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
122 dimensionPadding[ i ] = Vector2( 0.0f, 0.0f );
123 minimumSize[ i ] = 0.0f;
124 maximumSize[ i ] = FLT_MAX;
128 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
130 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
132 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
134 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
136 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
137 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
139 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
140 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
142 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
144 Vector2 preferredSize; ///< The preferred size of the actor
146 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
148 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
149 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
152 #ifdef DYNAMICS_SUPPORT
154 // Encapsulate actor related dynamics data
157 DynamicsData( Actor* slotOwner )
158 : slotDelegate( slotOwner )
162 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
163 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
165 DynamicsBodyPtr body;
166 JointContainer joints;
167 ReferencedJointContainer referencedJoints;
169 SlotDelegate< Actor > slotDelegate;
172 #endif // DYNAMICS_SUPPORT
174 namespace // unnamed namespace
180 * We want to discourage the use of property strings (minimize string comparisons),
181 * particularly for the default properties.
182 * Name Type writable animatable constraint-input enum for index-checking
184 DALI_PROPERTY_TABLE_BEGIN
185 DALI_PROPERTY( "parent-origin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
186 DALI_PROPERTY( "parent-origin-x", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
187 DALI_PROPERTY( "parent-origin-y", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
188 DALI_PROPERTY( "parent-origin-z", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
189 DALI_PROPERTY( "anchor-point", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
190 DALI_PROPERTY( "anchor-point-x", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
191 DALI_PROPERTY( "anchor-point-y", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
192 DALI_PROPERTY( "anchor-point-z", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
193 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
194 DALI_PROPERTY( "size-width", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
195 DALI_PROPERTY( "size-height", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
196 DALI_PROPERTY( "size-depth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
197 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
198 DALI_PROPERTY( "position-x", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
199 DALI_PROPERTY( "position-y", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
200 DALI_PROPERTY( "position-z", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
201 DALI_PROPERTY( "world-position", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
202 DALI_PROPERTY( "world-position-x", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
203 DALI_PROPERTY( "world-position-y", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
204 DALI_PROPERTY( "world-position-z", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
205 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
206 DALI_PROPERTY( "world-orientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
207 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
208 DALI_PROPERTY( "scale-x", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
209 DALI_PROPERTY( "scale-y", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
210 DALI_PROPERTY( "scale-z", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
211 DALI_PROPERTY( "world-scale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
212 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
213 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
214 DALI_PROPERTY( "color-red", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
215 DALI_PROPERTY( "color-green", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
216 DALI_PROPERTY( "color-blue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
217 DALI_PROPERTY( "color-alpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
218 DALI_PROPERTY( "world-color", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
219 DALI_PROPERTY( "world-matrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
220 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
221 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
222 DALI_PROPERTY( "leave-required", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
223 DALI_PROPERTY( "inherit-orientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
224 DALI_PROPERTY( "inherit-scale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
225 DALI_PROPERTY( "color-mode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
226 DALI_PROPERTY( "position-inheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
227 DALI_PROPERTY( "draw-mode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
228 DALI_PROPERTY( "size-mode-factor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
229 DALI_PROPERTY( "width-resize-policy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
230 DALI_PROPERTY( "height-resize-policy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
231 DALI_PROPERTY( "size-scale-policy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
232 DALI_PROPERTY( "width-for-height", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
233 DALI_PROPERTY( "height-for-width", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
234 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
235 DALI_PROPERTY( "minimum-size", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
236 DALI_PROPERTY( "maximum-size", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
237 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
241 const char* const SIGNAL_TOUCHED = "touched";
242 const char* const SIGNAL_HOVERED = "hovered";
243 const char* const SIGNAL_MOUSE_WHEEL_EVENT = "mouse-wheel-event";
244 const char* const SIGNAL_ON_STAGE = "on-stage";
245 const char* const SIGNAL_OFF_STAGE = "off-stage";
249 const char* const ACTION_SHOW = "show";
250 const char* const ACTION_HIDE = "hide";
252 BaseHandle CreateActor()
254 return Dali::Actor::New();
257 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
259 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
260 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
261 SignalConnectorType signalConnector3( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
262 SignalConnectorType signalConnector4( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
264 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
265 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
268 * @brief Extract a given dimension from a Vector2
270 * @param[in] values The values to extract from
271 * @param[in] dimension The dimension to extract
272 * @return Return the value for the dimension
274 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
278 case Dimension::WIDTH:
283 case Dimension::HEIGHT:
285 return values.height;
298 * @brief Extract a given dimension from a Vector3
300 * @param[in] values The values to extract from
301 * @param[in] dimension The dimension to extract
302 * @return Return the value for the dimension
304 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
306 return GetDimensionValue( values.GetVectorXY(), dimension );
309 } // unnamed namespace
311 ActorPtr Actor::New()
313 ActorPtr actor( new Actor( BASIC ) );
315 // Second-phase construction
321 const std::string& Actor::GetName() const
326 void Actor::SetName( const std::string& name )
332 // ATTENTION: string for debug purposes is not thread safe.
333 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
337 unsigned int Actor::GetId() const
342 void Actor::Attach( ActorAttachment& attachment )
344 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
348 attachment.Connect();
351 mAttachment = ActorAttachmentPtr( &attachment );
354 ActorAttachmentPtr Actor::GetAttachment()
359 bool Actor::OnStage() const
364 Dali::Layer Actor::GetLayer()
368 // Short-circuit for Layer derived actors
371 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
374 // Find the immediate Layer parent
375 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
377 if( parent->IsLayer() )
379 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
386 void Actor::Add( Actor& child )
388 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
389 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
393 mChildren = new ActorContainer;
396 Actor* const oldParent( child.mParent );
398 // child might already be ours
399 if( this != oldParent )
401 // if we already have parent, unparent us first
404 oldParent->Remove( child ); // This causes OnChildRemove callback
406 // Old parent may need to readjust to missing child
407 if( oldParent->RelayoutDependentOnChildren() )
409 oldParent->RelayoutRequest();
413 // Guard against Add() during previous OnChildRemove callback
416 // Do this first, since user callbacks from within SetParent() may need to remove child
417 mChildren->push_back( Dali::Actor( &child ) );
419 // SetParent asserts that child can be added
420 child.SetParent( this );
422 // Notification for derived classes
425 // Only put in a relayout request if there is a suitable dependency
426 if( RelayoutDependentOnChildren() )
434 void Actor::Insert( unsigned int index, Actor& child )
436 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
437 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
441 mChildren = new ActorContainer;
444 Actor* const oldParent( child.mParent );
446 // since an explicit position has been given, always insert, even if already a child
449 oldParent->Remove( child ); // This causes OnChildRemove callback
451 // Old parent may need to readjust to missing child
452 if( oldParent->RelayoutDependentOnChildren() )
454 oldParent->RelayoutRequest();
458 // Guard against Add() during previous OnChildRemove callback
461 // Do this first, since user callbacks from within SetParent() may need to remove child
462 if( index < GetChildCount() )
464 ActorIter it = mChildren->begin();
465 std::advance( it, index );
466 mChildren->insert( it, Dali::Actor( &child ) );
470 mChildren->push_back( Dali::Actor( &child ) );
472 // SetParent asserts that child can be added
473 child.SetParent( this, index );
475 // Notification for derived classes
478 // Only put in a relayout request if there is a suitable dependency
479 if( RelayoutDependentOnChildren() )
484 if( child.RelayoutDependentOnParent() )
486 child.RelayoutRequest();
491 void Actor::Remove( Actor& child )
493 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
503 // Find the child in mChildren, and unparent it
504 ActorIter end = mChildren->end();
505 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
507 Actor& actor = GetImplementation( *iter );
509 if( &actor == &child )
511 // Keep handle for OnChildRemove notification
512 removed = Dali::Actor( &actor );
514 // Do this first, since user callbacks from within SetParent() may need to add the child
515 mChildren->erase( iter );
517 DALI_ASSERT_DEBUG( actor.GetParent() == this );
518 actor.SetParent( NULL );
526 // Notification for derived classes
527 OnChildRemove( GetImplementation( removed ) );
529 // Only put in a relayout request if there is a suitable dependency
530 if( RelayoutDependentOnChildren() )
537 void Actor::Unparent()
541 // Remove this actor from the parent. The remove will put a relayout request in for
542 // the parent if required
543 mParent->Remove( *this );
544 // mParent is now NULL!
548 unsigned int Actor::GetChildCount() const
550 return ( NULL != mChildren ) ? mChildren->size() : 0;
553 Dali::Actor Actor::GetChildAt( unsigned int index ) const
555 DALI_ASSERT_ALWAYS( index < GetChildCount() );
557 return ( ( mChildren ) ? ( *mChildren )[ index ] : Dali::Actor() );
560 ActorPtr Actor::FindChildByName( const std::string& actorName )
563 if( actorName == mName )
569 ActorIter end = mChildren->end();
570 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
572 child = GetImplementation( *iter ).FindChildByName( actorName );
583 ActorPtr Actor::FindChildById( const unsigned int id )
592 ActorIter end = mChildren->end();
593 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
595 child = GetImplementation( *iter ).FindChildById( id );
606 void Actor::SetParentOrigin( const Vector3& origin )
610 // mNode is being used in a separate thread; queue a message to set the value & base value
611 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
614 // Cache for event-thread access
617 // not allocated, check if different from default
618 if( ParentOrigin::DEFAULT != origin )
620 mParentOrigin = new Vector3( origin );
625 // check if different from current costs more than just set
626 *mParentOrigin = origin;
630 void Actor::SetParentOriginX( float x )
632 const Vector3& current = GetCurrentParentOrigin();
634 SetParentOrigin( Vector3( x, current.y, current.z ) );
637 void Actor::SetParentOriginY( float y )
639 const Vector3& current = GetCurrentParentOrigin();
641 SetParentOrigin( Vector3( current.x, y, current.z ) );
644 void Actor::SetParentOriginZ( float z )
646 const Vector3& current = GetCurrentParentOrigin();
648 SetParentOrigin( Vector3( current.x, current.y, z ) );
651 const Vector3& Actor::GetCurrentParentOrigin() const
653 // Cached for event-thread access
654 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
657 void Actor::SetAnchorPoint( const Vector3& anchor )
661 // mNode is being used in a separate thread; queue a message to set the value & base value
662 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
665 // Cache for event-thread access
668 // not allocated, check if different from default
669 if( AnchorPoint::DEFAULT != anchor )
671 mAnchorPoint = new Vector3( anchor );
676 // check if different from current costs more than just set
677 *mAnchorPoint = anchor;
681 void Actor::SetAnchorPointX( float x )
683 const Vector3& current = GetCurrentAnchorPoint();
685 SetAnchorPoint( Vector3( x, current.y, current.z ) );
688 void Actor::SetAnchorPointY( float y )
690 const Vector3& current = GetCurrentAnchorPoint();
692 SetAnchorPoint( Vector3( current.x, y, current.z ) );
695 void Actor::SetAnchorPointZ( float z )
697 const Vector3& current = GetCurrentAnchorPoint();
699 SetAnchorPoint( Vector3( current.x, current.y, z ) );
702 const Vector3& Actor::GetCurrentAnchorPoint() const
704 // Cached for event-thread access
705 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
708 void Actor::SetPosition( float x, float y )
710 SetPosition( Vector3( x, y, 0.0f ) );
713 void Actor::SetPosition( float x, float y, float z )
715 SetPosition( Vector3( x, y, z ) );
718 void Actor::SetPosition( const Vector3& position )
720 mTargetPosition = position;
724 // mNode is being used in a separate thread; queue a message to set the value & base value
725 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
729 void Actor::SetX( float x )
731 mTargetPosition.x = x;
735 // mNode is being used in a separate thread; queue a message to set the value & base value
736 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
740 void Actor::SetY( float y )
742 mTargetPosition.y = y;
746 // mNode is being used in a separate thread; queue a message to set the value & base value
747 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
751 void Actor::SetZ( float z )
753 mTargetPosition.z = z;
757 // mNode is being used in a separate thread; queue a message to set the value & base value
758 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
762 void Actor::TranslateBy( const Vector3& distance )
764 mTargetPosition += distance;
768 // mNode is being used in a separate thread; queue a message to set the value & base value
769 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
773 const Vector3& Actor::GetCurrentPosition() const
777 // mNode is being used in a separate thread; copy the value from the previous update
778 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
781 return Vector3::ZERO;
784 const Vector3& Actor::GetTargetPosition() const
786 return mTargetPosition;
789 const Vector3& Actor::GetCurrentWorldPosition() const
793 // mNode is being used in a separate thread; copy the value from the previous update
794 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
797 return Vector3::ZERO;
800 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
802 // this flag is not animatable so keep the value
803 mPositionInheritanceMode = mode;
806 // mNode is being used in a separate thread; queue a message to set the value
807 SetPositionInheritanceModeMessage( GetEventThreadServices(), *mNode, mode );
811 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
813 // Cached for event-thread access
814 return mPositionInheritanceMode;
817 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
819 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
820 normalizedAxis.Normalize();
822 Quaternion orientation( angle, normalizedAxis );
824 SetOrientation( orientation );
827 void Actor::SetOrientation( const Quaternion& orientation )
831 // mNode is being used in a separate thread; queue a message to set the value & base value
832 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::Bake, orientation );
836 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
840 // mNode is being used in a separate thread; queue a message to set the value & base value
841 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
845 void Actor::RotateBy( const Quaternion& relativeRotation )
849 // mNode is being used in a separate thread; queue a message to set the value & base value
850 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
854 const Quaternion& Actor::GetCurrentOrientation() const
858 // mNode is being used in a separate thread; copy the value from the previous update
859 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
862 return Quaternion::IDENTITY;
865 const Quaternion& Actor::GetCurrentWorldOrientation() const
869 // mNode is being used in a separate thread; copy the value from the previous update
870 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
873 return Quaternion::IDENTITY;
876 void Actor::SetScale( float scale )
878 SetScale( Vector3( scale, scale, scale ) );
881 void Actor::SetScale( float x, float y, float z )
883 SetScale( Vector3( x, y, z ) );
886 void Actor::SetScale( const Vector3& scale )
890 // mNode is being used in a separate thread; queue a message to set the value & base value
891 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
895 void Actor::SetScaleX( float x )
899 // mNode is being used in a separate thread; queue a message to set the value & base value
900 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
904 void Actor::SetScaleY( float y )
908 // mNode is being used in a separate thread; queue a message to set the value & base value
909 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
913 void Actor::SetScaleZ( float z )
917 // mNode is being used in a separate thread; queue a message to set the value & base value
918 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
922 void Actor::SetInitialVolume( const Vector3& volume )
926 // mNode is being used in a separate thread; queue a message to set the value
927 SetInitialVolumeMessage( GetEventThreadServices(), *mNode, volume );
931 void Actor::SetTransmitGeometryScaling( bool transmitGeometryScaling )
935 // mNode is being used in a separate thread; queue a message to set the value
936 SetTransmitGeometryScalingMessage( GetEventThreadServices(), *mNode, transmitGeometryScaling );
940 bool Actor::GetTransmitGeometryScaling() const
944 // mNode is being used in a separate thread; copy the value from the previous update
945 return mNode->GetTransmitGeometryScaling();
951 void Actor::ScaleBy( const Vector3& relativeScale )
955 // mNode is being used in a separate thread; queue a message to set the value & base value
956 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
960 const Vector3& Actor::GetCurrentScale() const
964 // mNode is being used in a separate thread; copy the value from the previous update
965 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
971 const Vector3& Actor::GetCurrentWorldScale() const
975 // mNode is being used in a separate thread; copy the value from the previous update
976 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
982 void Actor::SetInheritScale( bool inherit )
984 // non animateable so keep local copy
985 mInheritScale = inherit;
988 // mNode is being used in a separate thread; queue a message to set the value
989 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
993 bool Actor::IsScaleInherited() const
995 return mInheritScale;
998 Matrix Actor::GetCurrentWorldMatrix() const
1002 // World matrix is no longer updated unless there is something observing the node.
1003 // Need to calculate it from node's world position, orientation and scale:
1004 BufferIndex updateBufferIndex = GetEventThreadServices().GetEventBufferIndex();
1005 Matrix worldMatrix(false);
1006 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
1007 mNode->GetWorldOrientation( updateBufferIndex ),
1008 mNode->GetWorldPosition( updateBufferIndex ) );
1012 return Matrix::IDENTITY;
1015 void Actor::SetVisible( bool visible )
1019 // mNode is being used in a separate thread; queue a message to set the value & base value
1020 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
1024 bool Actor::IsVisible() const
1028 // mNode is being used in a separate thread; copy the value from the previous update
1029 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1035 void Actor::SetOpacity( float opacity )
1039 // mNode is being used in a separate thread; queue a message to set the value & base value
1040 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1044 float Actor::GetCurrentOpacity() const
1048 // mNode is being used in a separate thread; copy the value from the previous update
1049 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1055 const Vector4& Actor::GetCurrentWorldColor() const
1059 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1062 return Color::WHITE;
1065 void Actor::SetColor( const Vector4& color )
1069 // mNode is being used in a separate thread; queue a message to set the value & base value
1070 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1074 void Actor::SetColorRed( float red )
1078 // mNode is being used in a separate thread; queue a message to set the value & base value
1079 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1083 void Actor::SetColorGreen( float green )
1087 // mNode is being used in a separate thread; queue a message to set the value & base value
1088 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1092 void Actor::SetColorBlue( float blue )
1096 // mNode is being used in a separate thread; queue a message to set the value & base value
1097 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1101 const Vector4& Actor::GetCurrentColor() const
1105 // mNode is being used in a separate thread; copy the value from the previous update
1106 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1109 return Color::WHITE;
1112 void Actor::SetInheritOrientation( bool inherit )
1114 // non animateable so keep local copy
1115 mInheritOrientation = inherit;
1118 // mNode is being used in a separate thread; queue a message to set the value
1119 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1123 bool Actor::IsOrientationInherited() const
1125 return mInheritOrientation;
1128 void Actor::SetSizeModeFactor( const Vector3& factor )
1130 EnsureRelayoutData();
1132 mRelayoutData->sizeModeFactor = factor;
1135 const Vector3& Actor::GetSizeModeFactor() const
1137 EnsureRelayoutData();
1139 return mRelayoutData->sizeModeFactor;
1142 void Actor::SetColorMode( ColorMode colorMode )
1144 // non animateable so keep local copy
1145 mColorMode = colorMode;
1148 // mNode is being used in a separate thread; queue a message to set the value
1149 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1153 ColorMode Actor::GetColorMode() const
1155 // we have cached copy
1159 void Actor::SetSize( float width, float height )
1161 SetSize( Vector2( width, height ) );
1164 void Actor::SetSize( float width, float height, float depth )
1166 SetSize( Vector3( width, height, depth ) );
1169 void Actor::SetSize( const Vector2& size )
1171 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1174 void Actor::SetSizeInternal( const Vector2& size )
1176 SetSizeInternal( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1179 float Actor::CalculateSizeZ( const Vector2& size ) const
1181 return std::min( size.width, size.height );
1184 void Actor::SetSize( const Vector3& size )
1186 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1188 SetPreferredSize( size.GetVectorXY() );
1192 SetSizeInternal( size );
1196 void Actor::SetSizeInternal( const Vector3& size )
1202 // mNode is being used in a separate thread; queue a message to set the value & base value
1203 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mTargetSize );
1205 // Notification for derived classes
1206 OnSizeSet( mTargetSize );
1208 // Raise a relayout request if the flag is not locked
1209 if( mRelayoutData && !mRelayoutData->insideRelayout )
1216 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1218 mTargetSize = targetSize;
1220 // Notify deriving classes
1221 OnSizeAnimation( animation, targetSize );
1224 void Actor::SetWidth( float width )
1228 // mNode is being used in a separate thread; queue a message to set the value & base value
1229 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1233 void Actor::SetHeight( float height )
1237 // mNode is being used in a separate thread; queue a message to set the value & base value
1238 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1242 void Actor::SetDepth( float depth )
1246 // mNode is being used in a separate thread; queue a message to set the value & base value
1247 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1251 const Vector3& Actor::GetTargetSize() const
1256 const Vector3& Actor::GetCurrentSize() const
1260 // mNode is being used in a separate thread; copy the value from the previous update
1261 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1264 return Vector3::ZERO;
1267 Vector3 Actor::GetNaturalSize() const
1269 // It is up to deriving classes to return the appropriate natural size
1270 return Vector3( 0.0f, 0.0f, 0.0f );
1273 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1275 EnsureRelayoutData();
1277 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1279 if( dimension & ( 1 << i ) )
1281 mRelayoutData->resizePolicies[ i ] = policy;
1285 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1287 if( dimension & Dimension::WIDTH )
1289 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1292 if( dimension & Dimension::HEIGHT )
1294 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1298 // If calling SetResizePolicy, assume we want relayout enabled
1299 SetRelayoutEnabled( true );
1301 OnSetResizePolicy( policy, dimension );
1303 // Trigger relayout on this control
1307 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1309 EnsureRelayoutData();
1311 // If more than one dimension is requested, just return the first one found
1312 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1314 if( ( dimension & ( 1 << i ) ) )
1316 return mRelayoutData->resizePolicies[ i ];
1320 return ResizePolicy::FIXED; // Default
1323 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1325 EnsureRelayoutData();
1327 mRelayoutData->sizeSetPolicy = policy;
1330 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1332 EnsureRelayoutData();
1334 return mRelayoutData->sizeSetPolicy;
1337 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1339 EnsureRelayoutData();
1341 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1343 if( dimension & ( 1 << i ) )
1345 mRelayoutData->dimensionDependencies[ i ] = dependency;
1350 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1352 EnsureRelayoutData();
1354 // If more than one dimension is requested, just return the first one found
1355 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1357 if( ( dimension & ( 1 << i ) ) )
1359 return mRelayoutData->dimensionDependencies[ i ];
1363 return Dimension::ALL_DIMENSIONS; // Default
1366 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1368 // If relayout data has not been allocated yet and the client is requesting
1369 // to disable it, do nothing
1370 if( mRelayoutData || relayoutEnabled )
1372 EnsureRelayoutData();
1374 mRelayoutData->relayoutEnabled = relayoutEnabled;
1378 bool Actor::IsRelayoutEnabled() const
1380 // Assume that if relayout data has not been allocated yet then
1381 // relayout is disabled
1382 return mRelayoutData && mRelayoutData->relayoutEnabled;
1385 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1387 EnsureRelayoutData();
1389 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1391 if( dimension & ( 1 << i ) )
1393 mRelayoutData->dimensionDirty[ i ] = dirty;
1398 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1400 EnsureRelayoutData();
1402 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1404 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1413 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1415 EnsureRelayoutData();
1417 return mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1420 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1422 EnsureRelayoutData();
1424 return mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1427 #ifdef DYNAMICS_SUPPORT
1429 //--------------- Dynamics ---------------
1431 void Actor::DisableDynamics()
1433 if( NULL != mDynamicsData )
1435 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1437 // ensure dynamics object are disconnected from scene
1438 DisconnectDynamics();
1440 // delete joint owned by this actor
1441 while( !mDynamicsData->joints.empty() )
1443 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1446 // delete other joints referencing this actor
1447 while( !mDynamicsData->referencedJoints.empty() )
1449 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1450 ActorPtr jointOwner( joint->GetActor( true ) );
1453 jointOwner->RemoveDynamicsJoint( joint );
1457 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1460 // delete the DynamicsBody object
1461 mDynamicsData->body.Reset();
1463 // Discard Dynamics data structure
1464 delete mDynamicsData;
1465 mDynamicsData = NULL;
1469 DynamicsBodyPtr Actor::GetDynamicsBody() const
1471 DynamicsBodyPtr body;
1473 if( NULL != mDynamicsData )
1475 body = mDynamicsData->body;
1481 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1483 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1485 if( NULL == mDynamicsData )
1487 mDynamicsData = new DynamicsData( this );
1490 if( !mDynamicsData->body )
1492 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1496 DynamicsWorldPtr world( DynamicsWorld::Get() );
1499 if( mParent == world->GetRootActor().Get() )
1501 mDynamicsData->body->Connect( GetEventThreadServices() );
1507 return mDynamicsData->body;
1510 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1512 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1513 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1516 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1518 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1519 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1521 DynamicsJointPtr joint;
1523 DynamicsWorldPtr world( DynamicsWorld::Get() );
1527 if( NULL != mDynamicsData )
1529 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1531 if( mDynamicsData->joints.end() != it )
1533 // use existing joint
1539 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1540 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1544 bodyA = EnableDynamics( new DynamicsBodyConfig );
1549 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1552 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1553 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1555 if( OnStage() && attachedActor->OnStage() )
1557 joint->Connect( GetEventThreadServices() );
1560 attachedActor->ReferenceJoint( joint );
1562 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1563 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1570 const int Actor::GetNumberOfJoints() const
1572 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1575 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1577 DynamicsJointPtr joint;
1579 if( NULL != mDynamicsData )
1581 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1583 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1585 for( int i = 0; i < index; ++i )
1597 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1599 DynamicsJointPtr joint;
1601 if( NULL != mDynamicsData )
1603 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1605 if( mDynamicsData->joints.end() != it )
1607 // use existing joint
1615 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1617 if( NULL != mDynamicsData )
1619 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1620 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1622 for(; it != endIt; ++it )
1624 if( it->second == joint.Get() )
1626 ActorPtr attachedActor( it->first );
1628 if( OnStage() && attachedActor && attachedActor->OnStage() )
1630 joint->Disconnect( GetEventThreadServices() );
1635 attachedActor->ReleaseJoint( joint );
1636 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1637 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1640 mDynamicsData->joints.erase(it);
1647 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1649 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1651 if( NULL != mDynamicsData )
1653 mDynamicsData->referencedJoints.push_back(joint);
1657 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1659 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1661 if( NULL != mDynamicsData )
1663 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1665 if( it != mDynamicsData->referencedJoints.end() )
1667 mDynamicsData->referencedJoints.erase( it );
1672 void Actor::SetDynamicsRoot(bool flag)
1674 if( mIsDynamicsRoot != flag )
1676 mIsDynamicsRoot = flag;
1678 if( OnStage() && mChildren )
1680 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1681 ActorIter end = mChildren->end();
1682 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1684 Actor& child = GetImplementation(*iter);
1686 if( child.GetDynamicsBody() )
1688 if( mIsDynamicsRoot )
1690 child.ConnectDynamics();
1694 child.DisconnectDynamics();
1702 bool Actor::IsDynamicsRoot() const
1704 return mIsDynamicsRoot;
1707 void Actor::AttachedActorOnStage( Dali::Actor actor )
1709 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1713 ActorPtr attachedActor( &GetImplementation(actor) );
1715 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1716 if( NULL != mDynamicsData )
1718 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1719 if( mDynamicsData->joints.end() != it )
1721 DynamicsJointPtr joint( it->second );
1722 joint->Connect( GetEventThreadServices() );
1728 void Actor::AttachedActorOffStage( Dali::Actor actor )
1730 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1734 ActorPtr attachedActor( &GetImplementation(actor) );
1736 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1737 if( NULL != mDynamicsData )
1739 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1740 if( mDynamicsData->joints.end() != it )
1742 DynamicsJointPtr joint( it->second );
1743 joint->Disconnect( GetEventThreadServices() );
1749 void Actor::ConnectDynamics()
1751 if( NULL != mDynamicsData && mDynamicsData->body )
1753 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1755 mDynamicsData->body->Connect( GetEventThreadServices() );
1757 // Connect all joints where attachedActor is also on stage
1758 if( !mDynamicsData->joints.empty() )
1760 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1761 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1763 for(; it != endIt; ++it )
1765 Actor* attachedActor( it->first );
1766 if( NULL != attachedActor && attachedActor->OnStage() )
1768 DynamicsJointPtr joint( it->second );
1770 joint->Connect( GetEventThreadServices() );
1778 void Actor::DisconnectDynamics()
1780 if( NULL != mDynamicsData && mDynamicsData->body )
1784 mDynamicsData->body->Disconnect( GetEventThreadServices() );
1786 // Disconnect all joints
1787 if( !mDynamicsData->joints.empty() )
1789 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1790 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1792 for(; it != endIt; ++it )
1794 DynamicsJointPtr joint( it->second );
1796 joint->Disconnect( GetEventThreadServices() );
1803 #endif // DYNAMICS_SUPPORT
1805 void Actor::SetOverlay( bool enable )
1807 // Setting STENCIL will override OVERLAY
1808 if( DrawMode::STENCIL != mDrawMode )
1810 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1814 bool Actor::IsOverlay() const
1816 return ( DrawMode::OVERLAY == mDrawMode );
1819 void Actor::SetDrawMode( DrawMode::Type drawMode )
1821 // this flag is not animatable so keep the value
1822 mDrawMode = drawMode;
1825 // mNode is being used in a separate thread; queue a message to set the value
1826 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1830 DrawMode::Type Actor::GetDrawMode() const
1835 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1837 // only valid when on-stage
1840 const RenderTaskList& taskList = Stage::GetCurrent()->GetRenderTaskList();
1842 Vector2 converted( screenX, screenY );
1844 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1845 const int taskCount = taskList.GetTaskCount();
1846 for( int i = taskCount - 1; i >= 0; --i )
1848 Dali::RenderTask task = taskList.GetTask( i );
1849 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1851 // found a task where this conversion was ok so return
1859 bool Actor::ScreenToLocal( RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1861 bool retval = false;
1862 // only valid when on-stage
1865 CameraActor* camera = renderTask.GetCameraActor();
1869 renderTask.GetViewport( viewport );
1871 // need to translate coordinates to render tasks coordinate space
1872 Vector2 converted( screenX, screenY );
1873 if( renderTask.TranslateCoordinates( converted ) )
1875 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1882 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1884 // Early-out if mNode is NULL
1890 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1892 // Calculate the ModelView matrix
1893 Matrix modelView( false/*don't init*/);
1894 // need to use the components as world matrix is only updated for actors that need it
1895 modelView.SetTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) );
1896 Matrix::Multiply( modelView, modelView, viewMatrix );
1898 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1899 Matrix invertedMvp( false/*don't init*/);
1900 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1901 bool success = invertedMvp.Invert();
1903 // Convert to GL coordinates
1904 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1909 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1916 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1922 if( XyPlaneIntersect( nearPos, farPos, local ) )
1924 Vector3 size = GetCurrentSize();
1925 localX = local.x + size.x * 0.5f;
1926 localY = local.y + size.y * 0.5f;
1937 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1940 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1942 Mathematical Formulation
1944 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1946 ( p - c ) dot ( p - c ) = r^2
1948 Given a ray with a point of origin 'o', and a direction vector 'd':
1950 ray(t) = o + td, t >= 0
1952 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1954 (o + td - c ) dot ( o + td - c ) = r^2
1956 To solve for t we first expand the above into a more recognisable quadratic equation form
1958 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1967 B = 2( o - c ) dot d
1968 C = ( o - c ) dot ( o - c ) - r^2
1970 which can be solved using a standard quadratic formula.
1972 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1974 Practical Simplification
1976 In a renderer, we often differentiate between world space and object space. In the object space
1977 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1978 into object space, the mathematical solution presented above can be simplified significantly.
1980 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1984 and we can find the t at which the (transformed) ray intersects the sphere by
1986 ( o + td ) dot ( o + td ) = r^2
1988 According to the reasoning above, we expand the above quadratic equation into the general form
1992 which now has coefficients:
1999 // Early out if mNode is NULL
2005 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
2007 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
2008 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
2009 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
2011 // Compute the radius is not needed, square radius it's enough.
2012 const Vector3& size( mNode->GetSize( bufferIndex ) );
2014 // Scale the sphere.
2015 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
2017 const float width = size.width * scale.width;
2018 const float height = size.height * scale.height;
2020 float squareSphereRadius = 0.5f * ( width * width + height * height );
2022 float a = rayDir.Dot( rayDir ); // a
2023 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
2024 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
2026 return ( b2 * b2 - a * c ) >= 0.f;
2029 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
2036 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
2038 // Transforms the ray to the local reference system.
2040 // Calculate the inverse of Model matrix
2041 Matrix invModelMatrix( false/*don't init*/);
2042 // need to use the components as world matrix is only updated for actors that need it
2043 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) );
2045 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
2046 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
2048 // Test with the actor's XY plane (Normal = 0 0 1 1).
2050 float a = -rayOriginLocal.z;
2051 float b = rayDirLocal.z;
2053 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
2055 // Ray travels distance * rayDirLocal to intersect with plane.
2058 const Vector3& size = mNode->GetSize( bufferIndex );
2060 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
2061 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
2063 // Test with the actor's geometry.
2064 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
2071 void Actor::SetLeaveRequired( bool required )
2073 mLeaveRequired = required;
2076 bool Actor::GetLeaveRequired() const
2078 return mLeaveRequired;
2081 void Actor::SetKeyboardFocusable( bool focusable )
2083 mKeyboardFocusable = focusable;
2086 bool Actor::IsKeyboardFocusable() const
2088 return mKeyboardFocusable;
2091 bool Actor::GetTouchRequired() const
2093 return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
2096 bool Actor::GetHoverRequired() const
2098 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
2101 bool Actor::GetMouseWheelEventRequired() const
2103 return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
2106 bool Actor::IsHittable() const
2108 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
2111 ActorGestureData& Actor::GetGestureData()
2113 // Likely scenario is that once gesture-data is created for this actor, the actor will require
2114 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
2115 if( NULL == mGestureData )
2117 mGestureData = new ActorGestureData;
2119 return *mGestureData;
2122 bool Actor::IsGestureRequred( Gesture::Type type ) const
2124 return mGestureData && mGestureData->IsGestureRequred( type );
2127 bool Actor::EmitTouchEventSignal( const TouchEvent& event )
2129 bool consumed = false;
2131 if( !mTouchedSignal.Empty() )
2133 Dali::Actor handle( this );
2134 consumed = mTouchedSignal.Emit( handle, event );
2139 // Notification for derived classes
2140 consumed = OnTouchEvent( event );
2146 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
2148 bool consumed = false;
2150 if( !mHoveredSignal.Empty() )
2152 Dali::Actor handle( this );
2153 consumed = mHoveredSignal.Emit( handle, event );
2158 // Notification for derived classes
2159 consumed = OnHoverEvent( event );
2165 bool Actor::EmitMouseWheelEventSignal( const MouseWheelEvent& event )
2167 bool consumed = false;
2169 if( !mMouseWheelEventSignal.Empty() )
2171 Dali::Actor handle( this );
2172 consumed = mMouseWheelEventSignal.Emit( handle, event );
2177 // Notification for derived classes
2178 consumed = OnMouseWheelEvent( event );
2184 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
2186 return mTouchedSignal;
2189 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2191 return mHoveredSignal;
2194 Dali::Actor::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
2196 return mMouseWheelEventSignal;
2199 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2201 return mOnStageSignal;
2204 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2206 return mOffStageSignal;
2209 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2211 return mOnRelayoutSignal;
2214 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2216 bool connected( true );
2217 Actor* actor = dynamic_cast< Actor* >( object );
2219 if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) ) // don't want to convert char* to string
2221 actor->TouchedSignal().Connect( tracker, functor );
2223 else if( 0 == strcmp( signalName.c_str(), SIGNAL_HOVERED ) )
2225 actor->HoveredSignal().Connect( tracker, functor );
2227 else if( 0 == strcmp( signalName.c_str(), SIGNAL_MOUSE_WHEEL_EVENT ) )
2229 actor->MouseWheelEventSignal().Connect( tracker, functor );
2231 else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) )
2233 actor->OnStageSignal().Connect( tracker, functor );
2235 else if( 0 == strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) )
2237 actor->OffStageSignal().Connect( tracker, functor );
2241 // signalName does not match any signal
2248 Actor::Actor( DerivedType derivedType )
2252 mParentOrigin( NULL ),
2253 mAnchorPoint( NULL ),
2254 mRelayoutData( NULL ),
2255 #ifdef DYNAMICS_SUPPORT
2256 mDynamicsData( NULL ),
2258 mGestureData( NULL ), mAttachment(), mTargetSize( 0.0f, 0.0f, 0.0f ), mName(), mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2259 mIsRoot( ROOT_LAYER == derivedType ), mIsRenderable( RENDERABLE == derivedType ), mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ), mIsOnStage( false ), mIsDynamicsRoot( false ), mSensitive( true ), mLeaveRequired( false ), mKeyboardFocusable( false ), mDerivedRequiresTouch( false ), mDerivedRequiresHover( false ), mDerivedRequiresMouseWheelEvent( false ), mOnStageSignalled( false ), mInheritOrientation( true ), mInheritScale( true ), mDrawMode( DrawMode::NORMAL ), mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ), mColorMode( Node::DEFAULT_COLOR_MODE )
2263 void Actor::Initialize()
2266 SceneGraph::Node* node = CreateNode();
2268 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2269 mNode = node; // Keep raw-pointer to Node
2273 GetEventThreadServices().RegisterObject( this );
2278 // Remove mParent pointers from children even if we're destroying core,
2279 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2282 ActorConstIter endIter = mChildren->end();
2283 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2285 Actor& actor = GetImplementation( *iter );
2286 actor.SetParent( NULL );
2291 // Guard to allow handle destruction after Core has been destroyed
2292 if( EventThreadServices::IsCoreRunning() )
2296 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2297 mNode = NULL; // Node is about to be destroyed
2300 GetEventThreadServices().UnregisterObject( this );
2303 #ifdef DYNAMICS_SUPPORT
2305 delete mDynamicsData;
2308 // Cleanup optional gesture data
2309 delete mGestureData;
2311 // Cleanup optional parent origin and anchor
2312 delete mParentOrigin;
2313 delete mAnchorPoint;
2315 // Delete optional relayout data
2318 delete mRelayoutData;
2322 void Actor::ConnectToStage( int index )
2324 // This container is used instead of walking the Actor hierachy.
2325 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2326 ActorContainer connectionList;
2328 // This stage is atomic i.e. not interrupted by user callbacks
2329 RecursiveConnectToStage( connectionList, index );
2331 // Notify applications about the newly connected actors.
2332 const ActorIter endIter = connectionList.end();
2333 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2335 Actor& actor = GetImplementation( *iter );
2336 actor.NotifyStageConnection();
2342 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2344 DALI_ASSERT_ALWAYS( !OnStage() );
2348 ConnectToSceneGraph( index );
2350 // Notification for internal derived classes
2351 OnStageConnectionInternal();
2353 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2354 connectionList.push_back( Dali::Actor( this ) );
2356 // Recursively connect children
2359 ActorConstIter endIter = mChildren->end();
2360 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2362 Actor& actor = GetImplementation( *iter );
2363 actor.RecursiveConnectToStage( connectionList );
2369 * This method is called when the Actor is connected to the Stage.
2370 * The parent must have added its Node to the scene-graph.
2371 * The child must connect its Node to the parent's Node.
2372 * This is resursive; the child calls ConnectToStage() for its children.
2374 void Actor::ConnectToSceneGraph( int index )
2376 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2380 // Reparent Node in next Update
2381 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode, index );
2384 // Notify attachment
2387 mAttachment->Connect();
2390 #ifdef DYNAMICS_SUPPORT
2392 if( NULL != mDynamicsData )
2398 // Request relayout on all actors that are added to the scenegraph
2401 // Notification for Object::Observers
2405 void Actor::NotifyStageConnection()
2407 // Actors can be removed (in a callback), before the on-stage stage is reported.
2408 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2409 if( OnStage() && !mOnStageSignalled )
2411 // Notification for external (CustomActor) derived classes
2412 OnStageConnectionExternal();
2414 if( !mOnStageSignal.Empty() )
2416 Dali::Actor handle( this );
2417 mOnStageSignal.Emit( handle );
2420 // Guard against Remove during callbacks
2423 mOnStageSignalled = true; // signal required next time Actor is removed
2428 void Actor::DisconnectFromStage()
2430 // This container is used instead of walking the Actor hierachy.
2431 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2432 ActorContainer disconnectionList;
2434 // This stage is atomic i.e. not interrupted by user callbacks
2435 RecursiveDisconnectFromStage( disconnectionList );
2437 // Notify applications about the newly disconnected actors.
2438 const ActorIter endIter = disconnectionList.end();
2439 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2441 Actor& actor = GetImplementation( *iter );
2442 actor.NotifyStageDisconnection();
2446 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2448 DALI_ASSERT_ALWAYS( OnStage() );
2450 // Recursively disconnect children
2453 ActorConstIter endIter = mChildren->end();
2454 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2456 Actor& actor = GetImplementation( *iter );
2457 actor.RecursiveDisconnectFromStage( disconnectionList );
2461 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2462 disconnectionList.push_back( Dali::Actor( this ) );
2464 // Notification for internal derived classes
2465 OnStageDisconnectionInternal();
2467 DisconnectFromSceneGraph();
2473 * This method is called by an actor or its parent, before a node removal message is sent.
2474 * This is recursive; the child calls DisconnectFromStage() for its children.
2476 void Actor::DisconnectFromSceneGraph()
2478 // Notification for Object::Observers
2479 OnSceneObjectRemove();
2481 // Notify attachment
2484 mAttachment->Disconnect();
2487 #ifdef DYNAMICS_SUPPORT
2489 if( NULL != mDynamicsData )
2491 DisconnectDynamics();
2496 void Actor::NotifyStageDisconnection()
2498 // Actors can be added (in a callback), before the off-stage state is reported.
2499 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2500 // only do this step if there is a stage, i.e. Core is not being shut down
2501 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2503 // Notification for external (CustomeActor) derived classes
2504 OnStageDisconnectionExternal();
2506 if( !mOffStageSignal.Empty() )
2508 Dali::Actor handle( this );
2509 mOffStageSignal.Emit( handle );
2512 // Guard against Add during callbacks
2515 mOnStageSignalled = false; // signal required next time Actor is added
2520 bool Actor::IsNodeConnected() const
2522 bool connected( false );
2527 if( mNode->IsRoot() || mNode->GetParent() )
2536 unsigned int Actor::GetDefaultPropertyCount() const
2538 return DEFAULT_PROPERTY_COUNT;
2541 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2543 indices.reserve( DEFAULT_PROPERTY_COUNT );
2545 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2547 indices.push_back( i );
2551 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2553 if( index < DEFAULT_PROPERTY_COUNT )
2555 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2561 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2563 Property::Index index = Property::INVALID_INDEX;
2565 // Look for name in default properties
2566 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2568 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2569 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2579 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2581 if( index < DEFAULT_PROPERTY_COUNT )
2583 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2589 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2591 if( index < DEFAULT_PROPERTY_COUNT )
2593 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2599 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2601 if( index < DEFAULT_PROPERTY_COUNT )
2603 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2609 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2611 if( index < DEFAULT_PROPERTY_COUNT )
2613 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2616 // index out of range...return Property::NONE
2617 return Property::NONE;
2620 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2624 case Dali::Actor::Property::PARENT_ORIGIN:
2626 SetParentOrigin( property.Get< Vector3 >() );
2630 case Dali::Actor::Property::PARENT_ORIGIN_X:
2632 SetParentOriginX( property.Get< float >() );
2636 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2638 SetParentOriginY( property.Get< float >() );
2642 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2644 SetParentOriginZ( property.Get< float >() );
2648 case Dali::Actor::Property::ANCHOR_POINT:
2650 SetAnchorPoint( property.Get< Vector3 >() );
2654 case Dali::Actor::Property::ANCHOR_POINT_X:
2656 SetAnchorPointX( property.Get< float >() );
2660 case Dali::Actor::Property::ANCHOR_POINT_Y:
2662 SetAnchorPointY( property.Get< float >() );
2666 case Dali::Actor::Property::ANCHOR_POINT_Z:
2668 SetAnchorPointZ( property.Get< float >() );
2672 case Dali::Actor::Property::SIZE:
2674 SetSize( property.Get< Vector3 >() );
2678 case Dali::Actor::Property::SIZE_WIDTH:
2680 SetWidth( property.Get< float >() );
2684 case Dali::Actor::Property::SIZE_HEIGHT:
2686 SetHeight( property.Get< float >() );
2690 case Dali::Actor::Property::SIZE_DEPTH:
2692 SetDepth( property.Get< float >() );
2696 case Dali::Actor::Property::POSITION:
2698 SetPosition( property.Get< Vector3 >() );
2702 case Dali::Actor::Property::POSITION_X:
2704 SetX( property.Get< float >() );
2708 case Dali::Actor::Property::POSITION_Y:
2710 SetY( property.Get< float >() );
2714 case Dali::Actor::Property::POSITION_Z:
2716 SetZ( property.Get< float >() );
2720 case Dali::Actor::Property::ORIENTATION:
2722 SetOrientation( property.Get< Quaternion >() );
2726 case Dali::Actor::Property::SCALE:
2728 SetScale( property.Get< Vector3 >() );
2732 case Dali::Actor::Property::SCALE_X:
2734 SetScaleX( property.Get< float >() );
2738 case Dali::Actor::Property::SCALE_Y:
2740 SetScaleY( property.Get< float >() );
2744 case Dali::Actor::Property::SCALE_Z:
2746 SetScaleZ( property.Get< float >() );
2750 case Dali::Actor::Property::VISIBLE:
2752 SetVisible( property.Get< bool >() );
2756 case Dali::Actor::Property::COLOR:
2758 SetColor( property.Get< Vector4 >() );
2762 case Dali::Actor::Property::COLOR_RED:
2764 SetColorRed( property.Get< float >() );
2768 case Dali::Actor::Property::COLOR_GREEN:
2770 SetColorGreen( property.Get< float >() );
2774 case Dali::Actor::Property::COLOR_BLUE:
2776 SetColorBlue( property.Get< float >() );
2780 case Dali::Actor::Property::COLOR_ALPHA:
2782 SetOpacity( property.Get< float >() );
2786 case Dali::Actor::Property::NAME:
2788 SetName( property.Get< std::string >() );
2792 case Dali::Actor::Property::SENSITIVE:
2794 SetSensitive( property.Get< bool >() );
2798 case Dali::Actor::Property::LEAVE_REQUIRED:
2800 SetLeaveRequired( property.Get< bool >() );
2804 case Dali::Actor::Property::INHERIT_ORIENTATION:
2806 SetInheritOrientation( property.Get< bool >() );
2810 case Dali::Actor::Property::INHERIT_SCALE:
2812 SetInheritScale( property.Get< bool >() );
2816 case Dali::Actor::Property::COLOR_MODE:
2818 SetColorMode( Scripting::GetColorMode( property.Get< std::string >() ) );
2822 case Dali::Actor::Property::POSITION_INHERITANCE:
2824 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get< std::string >() ) );
2828 case Dali::Actor::Property::DRAW_MODE:
2830 SetDrawMode( Scripting::GetDrawMode( property.Get< std::string >() ) );
2834 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2836 SetSizeModeFactor( property.Get< Vector3 >() );
2840 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2842 SetResizePolicy( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount ), Dimension::WIDTH );
2846 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2848 SetResizePolicy( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount ), Dimension::HEIGHT );
2852 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2854 SetSizeScalePolicy( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount ) );
2858 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2860 if( property.Get< bool >() )
2862 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2867 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2869 if( property.Get< bool >() )
2871 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2876 case Dali::Actor::Property::PADDING:
2878 Vector4 padding = property.Get< Vector4 >();
2879 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2880 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2884 case Dali::Actor::Property::MINIMUM_SIZE:
2886 Vector2 size = property.Get< Vector2 >();
2887 SetMinimumSize( size.x, Dimension::WIDTH );
2888 SetMinimumSize( size.y, Dimension::HEIGHT );
2892 case Dali::Actor::Property::MAXIMUM_SIZE:
2894 Vector2 size = property.Get< Vector2 >();
2895 SetMaximumSize( size.x, Dimension::WIDTH );
2896 SetMaximumSize( size.y, Dimension::HEIGHT );
2902 // this can happen in the case of a non-animatable default property so just do nothing
2908 // TODO: This method needs to be removed
2909 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2911 switch( entry.type )
2913 case Property::BOOLEAN:
2915 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2916 DALI_ASSERT_DEBUG( NULL != property );
2918 // property is being used in a separate thread; queue a message to set the property
2919 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2924 case Property::INTEGER:
2926 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2927 DALI_ASSERT_DEBUG( NULL != property );
2929 // property is being used in a separate thread; queue a message to set the property
2930 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2935 case Property::UNSIGNED_INTEGER:
2937 const AnimatableProperty< unsigned int >* property = dynamic_cast< const AnimatableProperty< unsigned int >* >( entry.GetSceneGraphProperty() );
2938 DALI_ASSERT_DEBUG( NULL != property );
2940 // property is being used in a separate thread; queue a message to set the property
2941 SceneGraph::NodePropertyMessage<unsigned int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<unsigned int>::Bake, value.Get<unsigned int>() );
2946 case Property::FLOAT:
2948 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2949 DALI_ASSERT_DEBUG( NULL != property );
2951 // property is being used in a separate thread; queue a message to set the property
2952 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2957 case Property::VECTOR2:
2959 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2960 DALI_ASSERT_DEBUG( NULL != property );
2962 // property is being used in a separate thread; queue a message to set the property
2963 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2968 case Property::VECTOR3:
2970 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2971 DALI_ASSERT_DEBUG( NULL != property );
2973 // property is being used in a separate thread; queue a message to set the property
2974 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2979 case Property::VECTOR4:
2981 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2982 DALI_ASSERT_DEBUG( NULL != property );
2984 // property is being used in a separate thread; queue a message to set the property
2985 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2990 case Property::ROTATION:
2992 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2993 DALI_ASSERT_DEBUG( NULL != property );
2995 // property is being used in a separate thread; queue a message to set the property
2996 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
3001 case Property::MATRIX:
3003 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3004 DALI_ASSERT_DEBUG( NULL != property );
3006 // property is being used in a separate thread; queue a message to set the property
3007 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
3012 case Property::MATRIX3:
3014 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3015 DALI_ASSERT_DEBUG( NULL != property );
3017 // property is being used in a separate thread; queue a message to set the property
3018 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
3025 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
3031 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3033 Property::Value value;
3037 case Dali::Actor::Property::PARENT_ORIGIN:
3039 value = GetCurrentParentOrigin();
3043 case Dali::Actor::Property::PARENT_ORIGIN_X:
3045 value = GetCurrentParentOrigin().x;
3049 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3051 value = GetCurrentParentOrigin().y;
3055 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3057 value = GetCurrentParentOrigin().z;
3061 case Dali::Actor::Property::ANCHOR_POINT:
3063 value = GetCurrentAnchorPoint();
3067 case Dali::Actor::Property::ANCHOR_POINT_X:
3069 value = GetCurrentAnchorPoint().x;
3073 case Dali::Actor::Property::ANCHOR_POINT_Y:
3075 value = GetCurrentAnchorPoint().y;
3079 case Dali::Actor::Property::ANCHOR_POINT_Z:
3081 value = GetCurrentAnchorPoint().z;
3085 case Dali::Actor::Property::SIZE:
3087 value = GetCurrentSize();
3091 case Dali::Actor::Property::SIZE_WIDTH:
3093 value = GetCurrentSize().width;
3097 case Dali::Actor::Property::SIZE_HEIGHT:
3099 value = GetCurrentSize().height;
3103 case Dali::Actor::Property::SIZE_DEPTH:
3105 value = GetCurrentSize().depth;
3109 case Dali::Actor::Property::POSITION:
3111 value = GetCurrentPosition();
3115 case Dali::Actor::Property::POSITION_X:
3117 value = GetCurrentPosition().x;
3121 case Dali::Actor::Property::POSITION_Y:
3123 value = GetCurrentPosition().y;
3127 case Dali::Actor::Property::POSITION_Z:
3129 value = GetCurrentPosition().z;
3133 case Dali::Actor::Property::WORLD_POSITION:
3135 value = GetCurrentWorldPosition();
3139 case Dali::Actor::Property::WORLD_POSITION_X:
3141 value = GetCurrentWorldPosition().x;
3145 case Dali::Actor::Property::WORLD_POSITION_Y:
3147 value = GetCurrentWorldPosition().y;
3151 case Dali::Actor::Property::WORLD_POSITION_Z:
3153 value = GetCurrentWorldPosition().z;
3157 case Dali::Actor::Property::ORIENTATION:
3159 value = GetCurrentOrientation();
3163 case Dali::Actor::Property::WORLD_ORIENTATION:
3165 value = GetCurrentWorldOrientation();
3169 case Dali::Actor::Property::SCALE:
3171 value = GetCurrentScale();
3175 case Dali::Actor::Property::SCALE_X:
3177 value = GetCurrentScale().x;
3181 case Dali::Actor::Property::SCALE_Y:
3183 value = GetCurrentScale().y;
3187 case Dali::Actor::Property::SCALE_Z:
3189 value = GetCurrentScale().z;
3193 case Dali::Actor::Property::WORLD_SCALE:
3195 value = GetCurrentWorldScale();
3199 case Dali::Actor::Property::VISIBLE:
3201 value = IsVisible();
3205 case Dali::Actor::Property::COLOR:
3207 value = GetCurrentColor();
3211 case Dali::Actor::Property::COLOR_RED:
3213 value = GetCurrentColor().r;
3217 case Dali::Actor::Property::COLOR_GREEN:
3219 value = GetCurrentColor().g;
3223 case Dali::Actor::Property::COLOR_BLUE:
3225 value = GetCurrentColor().b;
3229 case Dali::Actor::Property::COLOR_ALPHA:
3231 value = GetCurrentColor().a;
3235 case Dali::Actor::Property::WORLD_COLOR:
3237 value = GetCurrentWorldColor();
3241 case Dali::Actor::Property::WORLD_MATRIX:
3243 value = GetCurrentWorldMatrix();
3247 case Dali::Actor::Property::NAME:
3253 case Dali::Actor::Property::SENSITIVE:
3255 value = IsSensitive();
3259 case Dali::Actor::Property::LEAVE_REQUIRED:
3261 value = GetLeaveRequired();
3265 case Dali::Actor::Property::INHERIT_ORIENTATION:
3267 value = IsOrientationInherited();
3271 case Dali::Actor::Property::INHERIT_SCALE:
3273 value = IsScaleInherited();
3277 case Dali::Actor::Property::COLOR_MODE:
3279 value = Scripting::GetColorMode( GetColorMode() );
3283 case Dali::Actor::Property::POSITION_INHERITANCE:
3285 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3289 case Dali::Actor::Property::DRAW_MODE:
3291 value = Scripting::GetDrawMode( GetDrawMode() );
3295 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3297 value = GetSizeModeFactor();
3301 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3303 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount );
3307 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3309 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount );
3313 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3315 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount );
3319 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3321 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3325 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3327 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3331 case Dali::Actor::Property::PADDING:
3333 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3334 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3335 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3339 case Dali::Actor::Property::MINIMUM_SIZE:
3341 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3345 case Dali::Actor::Property::MAXIMUM_SIZE:
3347 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3353 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3361 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3366 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3368 // This method should only return an object connected to the scene-graph
3369 return OnStage() ? mNode : NULL;
3372 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3374 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3376 const PropertyBase* property( NULL );
3378 // This method should only return a property of an object connected to the scene-graph
3384 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3386 AnimatablePropertyMetadata* animatable = FindAnimatableProperty( index );
3389 const TypeInfo* typeInfo( GetTypeInfo() );
3392 if( Property::INVALID_INDEX != RegisterSceneGraphProperty( typeInfo->GetPropertyName( index ), index, Property::Value( typeInfo->GetPropertyType( index ) ) ) )
3394 animatable = FindAnimatableProperty( index );
3398 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3400 property = animatable->GetSceneGraphProperty();
3402 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3404 CustomPropertyMetadata* custom = FindCustomProperty( index );
3405 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3407 property = custom->GetSceneGraphProperty();
3409 else if( NULL != mNode )
3413 case Dali::Actor::Property::SIZE:
3414 property = &mNode->mSize;
3417 case Dali::Actor::Property::SIZE_WIDTH:
3418 property = &mNode->mSize;
3421 case Dali::Actor::Property::SIZE_HEIGHT:
3422 property = &mNode->mSize;
3425 case Dali::Actor::Property::SIZE_DEPTH:
3426 property = &mNode->mSize;
3429 case Dali::Actor::Property::POSITION:
3430 property = &mNode->mPosition;
3433 case Dali::Actor::Property::POSITION_X:
3434 property = &mNode->mPosition;
3437 case Dali::Actor::Property::POSITION_Y:
3438 property = &mNode->mPosition;
3441 case Dali::Actor::Property::POSITION_Z:
3442 property = &mNode->mPosition;
3445 case Dali::Actor::Property::ORIENTATION:
3446 property = &mNode->mOrientation;
3449 case Dali::Actor::Property::SCALE:
3450 property = &mNode->mScale;
3453 case Dali::Actor::Property::SCALE_X:
3454 property = &mNode->mScale;
3457 case Dali::Actor::Property::SCALE_Y:
3458 property = &mNode->mScale;
3461 case Dali::Actor::Property::SCALE_Z:
3462 property = &mNode->mScale;
3465 case Dali::Actor::Property::VISIBLE:
3466 property = &mNode->mVisible;
3469 case Dali::Actor::Property::COLOR:
3470 property = &mNode->mColor;
3473 case Dali::Actor::Property::COLOR_RED:
3474 property = &mNode->mColor;
3477 case Dali::Actor::Property::COLOR_GREEN:
3478 property = &mNode->mColor;
3481 case Dali::Actor::Property::COLOR_BLUE:
3482 property = &mNode->mColor;
3485 case Dali::Actor::Property::COLOR_ALPHA:
3486 property = &mNode->mColor;
3497 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3499 const PropertyInputImpl* property( NULL );
3501 // This method should only return a property of an object connected to the scene-graph
3507 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3509 AnimatablePropertyMetadata* animatable = FindAnimatableProperty( index );
3512 const TypeInfo* typeInfo( GetTypeInfo() );
3515 if( Property::INVALID_INDEX != RegisterSceneGraphProperty( typeInfo->GetPropertyName( index ), index, Property::Value( typeInfo->GetPropertyType( index ) ) ) )
3517 animatable = FindAnimatableProperty( index );
3521 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3523 property = animatable->GetSceneGraphProperty();
3525 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3527 CustomPropertyMetadata* custom = FindCustomProperty( index );
3528 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3529 property = custom->GetSceneGraphProperty();
3531 else if( NULL != mNode )
3535 case Dali::Actor::Property::PARENT_ORIGIN:
3536 property = &mNode->mParentOrigin;
3539 case Dali::Actor::Property::PARENT_ORIGIN_X:
3540 property = &mNode->mParentOrigin;
3543 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3544 property = &mNode->mParentOrigin;
3547 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3548 property = &mNode->mParentOrigin;
3551 case Dali::Actor::Property::ANCHOR_POINT:
3552 property = &mNode->mAnchorPoint;
3555 case Dali::Actor::Property::ANCHOR_POINT_X:
3556 property = &mNode->mAnchorPoint;
3559 case Dali::Actor::Property::ANCHOR_POINT_Y:
3560 property = &mNode->mAnchorPoint;
3563 case Dali::Actor::Property::ANCHOR_POINT_Z:
3564 property = &mNode->mAnchorPoint;
3567 case Dali::Actor::Property::SIZE:
3568 property = &mNode->mSize;
3571 case Dali::Actor::Property::SIZE_WIDTH:
3572 property = &mNode->mSize;
3575 case Dali::Actor::Property::SIZE_HEIGHT:
3576 property = &mNode->mSize;
3579 case Dali::Actor::Property::SIZE_DEPTH:
3580 property = &mNode->mSize;
3583 case Dali::Actor::Property::POSITION:
3584 property = &mNode->mPosition;
3587 case Dali::Actor::Property::POSITION_X:
3588 property = &mNode->mPosition;
3591 case Dali::Actor::Property::POSITION_Y:
3592 property = &mNode->mPosition;
3595 case Dali::Actor::Property::POSITION_Z:
3596 property = &mNode->mPosition;
3599 case Dali::Actor::Property::WORLD_POSITION:
3600 property = &mNode->mWorldPosition;
3603 case Dali::Actor::Property::WORLD_POSITION_X:
3604 property = &mNode->mWorldPosition;
3607 case Dali::Actor::Property::WORLD_POSITION_Y:
3608 property = &mNode->mWorldPosition;
3611 case Dali::Actor::Property::WORLD_POSITION_Z:
3612 property = &mNode->mWorldPosition;
3615 case Dali::Actor::Property::ORIENTATION:
3616 property = &mNode->mOrientation;
3619 case Dali::Actor::Property::WORLD_ORIENTATION:
3620 property = &mNode->mWorldOrientation;
3623 case Dali::Actor::Property::SCALE:
3624 property = &mNode->mScale;
3627 case Dali::Actor::Property::SCALE_X:
3628 property = &mNode->mScale;
3631 case Dali::Actor::Property::SCALE_Y:
3632 property = &mNode->mScale;
3635 case Dali::Actor::Property::SCALE_Z:
3636 property = &mNode->mScale;
3639 case Dali::Actor::Property::WORLD_SCALE:
3640 property = &mNode->mWorldScale;
3643 case Dali::Actor::Property::VISIBLE:
3644 property = &mNode->mVisible;
3647 case Dali::Actor::Property::COLOR:
3648 property = &mNode->mColor;
3651 case Dali::Actor::Property::COLOR_RED:
3652 property = &mNode->mColor;
3655 case Dali::Actor::Property::COLOR_GREEN:
3656 property = &mNode->mColor;
3659 case Dali::Actor::Property::COLOR_BLUE:
3660 property = &mNode->mColor;
3663 case Dali::Actor::Property::COLOR_ALPHA:
3664 property = &mNode->mColor;
3667 case Dali::Actor::Property::WORLD_COLOR:
3668 property = &mNode->mWorldColor;
3671 case Dali::Actor::Property::WORLD_MATRIX:
3672 property = &mNode->mWorldMatrix;
3683 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3685 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3689 case Dali::Actor::Property::PARENT_ORIGIN_X:
3690 case Dali::Actor::Property::ANCHOR_POINT_X:
3691 case Dali::Actor::Property::SIZE_WIDTH:
3692 case Dali::Actor::Property::POSITION_X:
3693 case Dali::Actor::Property::WORLD_POSITION_X:
3694 case Dali::Actor::Property::SCALE_X:
3695 case Dali::Actor::Property::COLOR_RED:
3701 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3702 case Dali::Actor::Property::ANCHOR_POINT_Y:
3703 case Dali::Actor::Property::SIZE_HEIGHT:
3704 case Dali::Actor::Property::POSITION_Y:
3705 case Dali::Actor::Property::WORLD_POSITION_Y:
3706 case Dali::Actor::Property::SCALE_Y:
3707 case Dali::Actor::Property::COLOR_GREEN:
3713 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3714 case Dali::Actor::Property::ANCHOR_POINT_Z:
3715 case Dali::Actor::Property::SIZE_DEPTH:
3716 case Dali::Actor::Property::POSITION_Z:
3717 case Dali::Actor::Property::WORLD_POSITION_Z:
3718 case Dali::Actor::Property::SCALE_Z:
3719 case Dali::Actor::Property::COLOR_BLUE:
3725 case Dali::Actor::Property::COLOR_ALPHA:
3738 return componentIndex;
3741 void Actor::SetParent( Actor* parent, int index )
3745 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3749 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3752 // Instruct each actor to create a corresponding node in the scene graph
3753 ConnectToStage( index );
3756 else // parent being set to NULL
3758 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3762 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3765 DALI_ASSERT_ALWAYS( mNode != NULL );
3769 // Disconnect the Node & its children from the scene-graph.
3770 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3773 // Instruct each actor to discard pointers to the scene-graph
3774 DisconnectFromStage();
3779 SceneGraph::Node* Actor::CreateNode() const
3784 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector< Property::Value >& attributes )
3787 Actor* actor = dynamic_cast< Actor* >( object );
3791 if( 0 == strcmp( actionName.c_str(), ACTION_SHOW ) ) // dont want to convert char* to string
3793 actor->SetVisible( true );
3796 else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE ) )
3798 actor->SetVisible( false );
3806 void Actor::EnsureRelayoutData() const
3808 // Assign relayout data.
3809 if( !mRelayoutData )
3811 mRelayoutData = new RelayoutData();
3815 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3817 // Check if actor is dependent on parent
3818 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3820 if( ( dimension & ( 1 << i ) ) )
3822 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3823 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3833 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3835 // Check if actor is dependent on children
3836 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3838 if( ( dimension & ( 1 << i ) ) )
3840 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3841 switch( resizePolicy )
3843 case ResizePolicy::FIT_TO_CHILDREN:
3844 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3860 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3862 return Actor::RelayoutDependentOnChildren( dimension );
3865 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3867 // Check each possible dimension and see if it is dependent on the input one
3868 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3870 if( dimension & ( 1 << i ) )
3872 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3879 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3881 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3883 if( dimension & ( 1 << i ) )
3885 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3890 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3892 // If more than one dimension is requested, just return the first one found
3893 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3895 if( ( dimension & ( 1 << i ) ) )
3897 return mRelayoutData->negotiatedDimensions[ i ];
3901 return 0.0f; // Default
3904 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3906 EnsureRelayoutData();
3908 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3910 if( dimension & ( 1 << i ) )
3912 mRelayoutData->dimensionPadding[ i ] = padding;
3917 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3919 EnsureRelayoutData();
3921 // If more than one dimension is requested, just return the first one found
3922 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3924 if( ( dimension & ( 1 << i ) ) )
3926 return mRelayoutData->dimensionPadding[ i ];
3930 return Vector2( 0.0f, 0.0f ); // Default
3933 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3935 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3937 if( dimension & ( 1 << i ) )
3939 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3944 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3946 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3948 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3957 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3959 // Could be overridden in derived classes.
3960 return CalculateChildSizeBase( child, dimension );
3963 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3965 // Fill to parent, taking size mode factor into account
3966 switch( child.GetResizePolicy( dimension ) )
3968 case ResizePolicy::FILL_TO_PARENT:
3970 return GetLatestSize( dimension );
3973 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3975 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3978 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3980 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3985 return GetLatestSize( dimension );
3990 float Actor::GetHeightForWidth( float width )
3992 // Could be overridden in derived classes.
3993 float height = 0.0f;
3995 const Vector3 naturalSize = GetNaturalSize();
3996 if( naturalSize.width > 0.0f )
3998 height = naturalSize.height * width / naturalSize.width;
4004 float Actor::GetWidthForHeight( float height )
4006 // Could be overridden in derived classes.
4009 const Vector3 naturalSize = GetNaturalSize();
4010 if( naturalSize.height > 0.0f )
4012 width = naturalSize.width * height / naturalSize.height;
4018 float Actor::GetLatestSize( Dimension::Type dimension ) const
4020 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4023 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4025 Vector2 padding = GetPadding( dimension );
4027 return GetLatestSize( dimension ) + padding.x + padding.y;
4030 float Actor::NegotiateFromParent( Dimension::Type dimension )
4032 Actor* parent = GetParent();
4035 Vector2 padding( GetPadding( dimension ) );
4036 Vector2 parentPadding( parent->GetPadding( dimension ) );
4037 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4043 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4045 float maxDimensionPoint = 0.0f;
4047 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4049 Dali::Actor child = GetChildAt( i );
4050 Actor& childImpl = GetImplementation( child );
4052 if( !childImpl.RelayoutDependentOnParent( dimension ) )
4054 // Calculate the min and max points that the children range across
4055 float childPosition = GetDimensionValue( childImpl.GetTargetPosition(), dimension );
4056 float dimensionSize = childImpl.GetRelayoutSize( dimension );
4057 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4061 return maxDimensionPoint;
4064 float Actor::GetSize( Dimension::Type dimension ) const
4066 return GetDimensionValue( GetTargetSize(), dimension );
4069 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4071 return GetDimensionValue( GetNaturalSize(), dimension );
4074 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4076 switch( GetResizePolicy( dimension ) )
4078 case ResizePolicy::USE_NATURAL_SIZE:
4080 return GetNaturalSize( dimension );
4083 case ResizePolicy::FIXED:
4085 return GetDimensionValue( GetPreferredSize(), dimension );
4088 case ResizePolicy::USE_ASSIGNED_SIZE:
4090 return GetDimensionValue( maximumSize, dimension );
4093 case ResizePolicy::FILL_TO_PARENT:
4094 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4095 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4097 return NegotiateFromParent( dimension );
4100 case ResizePolicy::FIT_TO_CHILDREN:
4102 return NegotiateFromChildren( dimension );
4105 case ResizePolicy::DIMENSION_DEPENDENCY:
4107 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4110 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4112 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4115 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4117 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4129 return 0.0f; // Default
4132 float Actor::ClampDimension( float size, Dimension::Type dimension )
4134 const float minSize = GetMinimumSize( dimension );
4135 const float maxSize = GetMaximumSize( dimension );
4137 return std::max( minSize, std::min( size, maxSize ) );
4140 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4142 // Check if it needs to be negotiated
4143 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4145 // Check that we havn't gotten into an infinite loop
4146 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4147 bool recursionFound = false;
4148 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4150 if( *it == searchActor )
4152 recursionFound = true;
4157 if( !recursionFound )
4159 // Record the path that we have taken
4160 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4162 // Dimension dependency check
4163 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4165 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4167 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4169 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4173 // Parent dependency check
4174 Actor* parent = GetParent();
4175 if( parent && RelayoutDependentOnParent( dimension ) )
4177 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4180 // Children dependency check
4181 if( RelayoutDependentOnChildren( dimension ) )
4183 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4185 Dali::Actor child = GetChildAt( i );
4186 Actor& childImpl = GetImplementation( child );
4188 // Only relayout child first if it is not dependent on this actor
4189 if( !childImpl.RelayoutDependentOnParent( dimension ) )
4191 childImpl.NegotiateDimension( dimension, allocatedSize, recursionStack );
4196 // For deriving classes
4197 OnCalculateRelayoutSize( dimension );
4199 // All dependencies checked, calculate the size and set negotiated flag
4200 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4202 SetNegotiatedDimension( newSize, dimension );
4203 SetLayoutNegotiated( true, dimension );
4205 // For deriving classes
4206 OnLayoutNegotiated( newSize, dimension );
4208 // This actor has been successfully processed, pop it off the recursion stack
4209 recursionStack.pop_back();
4213 // TODO: Break infinite loop
4214 SetLayoutNegotiated( true, dimension );
4219 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4221 // Negotiate all dimensions that require it
4222 ActorDimensionStack recursionStack;
4224 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4226 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4229 NegotiateDimension( dimension, allocatedSize, recursionStack );
4233 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4235 switch( mRelayoutData->sizeSetPolicy )
4237 case SizeScalePolicy::USE_SIZE_SET:
4242 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4244 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4245 const Vector3 naturalSize = GetNaturalSize();
4246 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4248 const float sizeRatio = size.width / size.height;
4249 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4251 if( naturalSizeRatio < sizeRatio )
4253 return Vector2( naturalSizeRatio * size.height, size.height );
4255 else if( naturalSizeRatio > sizeRatio )
4257 return Vector2( size.width, size.width / naturalSizeRatio );
4268 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4270 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4271 const Vector3 naturalSize = GetNaturalSize();
4272 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4274 const float sizeRatio = size.width / size.height;
4275 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4277 if( naturalSizeRatio < sizeRatio )
4279 return Vector2( size.width, size.width / naturalSizeRatio );
4281 else if( naturalSizeRatio > sizeRatio )
4283 return Vector2( naturalSizeRatio * size.height, size.height );
4301 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4303 // Do the set actor size
4304 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4306 // Adjust for size set policy
4307 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4309 // Lock the flag to stop recursive relayouts on set size
4310 mRelayoutData->insideRelayout = true;
4311 SetSize( negotiatedSize );
4312 mRelayoutData->insideRelayout = false;
4314 // Clear flags for all dimensions
4315 SetLayoutDirty( false );
4317 // Give deriving classes a chance to respond
4318 OnRelayout( negotiatedSize, container );
4320 if( !mOnRelayoutSignal.Empty() )
4322 Dali::Actor handle( this );
4323 mOnRelayoutSignal.Emit( handle );
4327 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4329 // Do the negotiation
4330 NegotiateDimensions( allocatedSize );
4332 // Set the actor size
4333 SetNegotiatedSize( container );
4335 // Negotiate down to children
4336 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4338 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4340 Dali::Actor child = GetChildAt( i );
4342 // Only relayout if required
4343 if( GetImplementation( child ).RelayoutRequired() )
4345 container.Add( child, newBounds );
4350 void Actor::RelayoutRequest( Dimension::Type dimension )
4352 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4353 if( relayoutController )
4355 Dali::Actor self( this );
4356 relayoutController->RequestRelayout( self, dimension );
4360 void Actor::PropagateRelayoutFlags()
4362 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4363 if( relayoutController )
4365 Dali::Actor self( this );
4366 relayoutController->PropagateFlags( self );
4370 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4374 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4378 void Actor::SetPreferredSize( const Vector2& size )
4380 EnsureRelayoutData();
4382 if( size.width > 0.0f )
4384 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4387 if( size.height > 0.0f )
4389 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4392 mRelayoutData->preferredSize = size;
4397 Vector2 Actor::GetPreferredSize() const
4399 EnsureRelayoutData();
4401 return mRelayoutData->preferredSize;
4404 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4406 EnsureRelayoutData();
4408 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4410 if( dimension & ( 1 << i ) )
4412 mRelayoutData->minimumSize[ i ] = size;
4419 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4421 EnsureRelayoutData();
4423 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4425 if( dimension & ( 1 << i ) )
4427 return mRelayoutData->minimumSize[ i ];
4431 return 0.0f; // Default
4434 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4436 EnsureRelayoutData();
4438 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4440 if( dimension & ( 1 << i ) )
4442 mRelayoutData->maximumSize[ i ] = size;
4449 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4451 EnsureRelayoutData();
4453 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4455 if( dimension & ( 1 << i ) )
4457 return mRelayoutData->maximumSize[ i ];
4461 return 0.0f; // Default
4464 } // namespace Internal