2 * Copyright (c) 2016 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>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.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>
36 #include <dali/devel-api/scripting/scripting.h>
38 #include <dali/internal/common/internal-constants.h>
39 #include <dali/internal/event/common/event-thread-services.h>
40 #include <dali/internal/event/render-tasks/render-task-impl.h>
41 #include <dali/internal/event/actors/camera-actor-impl.h>
42 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
43 #include <dali/internal/event/common/property-helper.h>
44 #include <dali/internal/event/common/stage-impl.h>
45 #include <dali/internal/event/common/type-info-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 using Dali::Internal::SceneGraph::Node;
58 using Dali::Internal::SceneGraph::AnimatableProperty;
59 using Dali::Internal::SceneGraph::PropertyBase;
67 unsigned int Actor::mActorCounter = 0;
71 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
72 inline const Vector3& GetDefaultSizeModeFactor()
77 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
78 inline const Vector2& GetDefaultPreferredSize()
83 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
84 inline const Vector2& GetDefaultDimensionPadding()
89 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
91 } // unnamed namespace
94 * Struct to collect relayout variables
96 struct Actor::RelayoutData
99 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
101 // Set size negotiation defaults
102 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
104 resizePolicies[ i ] = ResizePolicy::DEFAULT;
105 negotiatedDimensions[ i ] = 0.0f;
106 dimensionNegotiated[ i ] = false;
107 dimensionDirty[ i ] = false;
108 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
109 dimensionPadding[ i ] = GetDefaultDimensionPadding();
110 minimumSize[ i ] = 0.0f;
111 maximumSize[ i ] = FLT_MAX;
115 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
117 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
119 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
121 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
123 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
124 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
126 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
127 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
129 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
131 Vector2 preferredSize; ///< The preferred size of the actor
133 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
135 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
136 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
139 namespace // unnamed namespace
145 * We want to discourage the use of property strings (minimize string comparisons),
146 * particularly for the default properties.
147 * Name Type writable animatable constraint-input enum for index-checking
149 DALI_PROPERTY_TABLE_BEGIN
150 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
151 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
152 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
153 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
154 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
155 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
156 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
157 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
158 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
159 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
160 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
161 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
162 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
163 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
164 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
165 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
166 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
167 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
168 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
169 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
170 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
171 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
172 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
173 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
174 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
175 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
176 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
177 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
178 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
179 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
180 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
181 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
182 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
183 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
184 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
185 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
186 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
187 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
188 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
189 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
190 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
191 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
192 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
193 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
194 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
195 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
196 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
197 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
198 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
199 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
200 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
201 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
202 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
203 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
207 const char* const SIGNAL_TOUCHED = "touched";
208 const char* const SIGNAL_HOVERED = "hovered";
209 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
210 const char* const SIGNAL_ON_STAGE = "onStage";
211 const char* const SIGNAL_OFF_STAGE = "offStage";
212 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
213 const char* const SIGNAL_TOUCH = "touch";
217 const char* const ACTION_SHOW = "show";
218 const char* const ACTION_HIDE = "hide";
220 BaseHandle CreateActor()
222 return Dali::Actor::New();
225 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
227 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
228 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
229 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
232 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
233 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
235 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
236 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
241 const Vector3& value;
244 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
245 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
246 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
252 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
253 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
254 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
256 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
257 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
258 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
259 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
260 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
261 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
263 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
264 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
265 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
266 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
267 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
268 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
270 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
274 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
276 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
285 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
287 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
288 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
289 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
291 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
293 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
295 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
297 size_t sizeIgnored = 0;
298 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
300 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
307 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
309 // Values are the same so just use the same table as anchor-point
310 return GetAnchorPointConstant( value, parentOrigin );
314 * @brief Extract a given dimension from a Vector2
316 * @param[in] values The values to extract from
317 * @param[in] dimension The dimension to extract
318 * @return Return the value for the dimension
320 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
324 case Dimension::WIDTH:
328 case Dimension::HEIGHT:
330 return values.height;
341 * @brief Extract a given dimension from a Vector3
343 * @param[in] values The values to extract from
344 * @param[in] dimension The dimension to extract
345 * @return Return the value for the dimension
347 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
349 return GetDimensionValue( values.GetVectorXY(), dimension );
353 } // unnamed namespace
355 ActorPtr Actor::New()
357 ActorPtr actor( new Actor( BASIC ) );
359 // Second-phase construction
365 const std::string& Actor::GetName() const
370 void Actor::SetName( const std::string& name )
376 // ATTENTION: string for debug purposes is not thread safe.
377 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
381 unsigned int Actor::GetId() const
386 bool Actor::OnStage() const
391 Dali::Layer Actor::GetLayer()
395 // Short-circuit for Layer derived actors
398 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
401 // Find the immediate Layer parent
402 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
404 if( parent->IsLayer() )
406 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
413 void Actor::Add( Actor& child )
415 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
416 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
420 mChildren = new ActorContainer;
423 Actor* const oldParent( child.mParent );
425 // child might already be ours
426 if( this != oldParent )
428 // if we already have parent, unparent us first
431 oldParent->Remove( child ); // This causes OnChildRemove callback
433 // Old parent may need to readjust to missing child
434 if( oldParent->RelayoutDependentOnChildren() )
436 oldParent->RelayoutRequest();
440 // Guard against Add() during previous OnChildRemove callback
443 // Do this first, since user callbacks from within SetParent() may need to remove child
444 mChildren->push_back( ActorPtr( &child ) );
446 // SetParent asserts that child can be added
447 child.SetParent( this );
449 // Notification for derived classes
452 // Only put in a relayout request if there is a suitable dependency
453 if( RelayoutDependentOnChildren() )
461 void Actor::Remove( Actor& child )
463 if( (this == &child) || (!mChildren) )
465 // no children or removing itself
471 // Find the child in mChildren, and unparent it
472 ActorIter end = mChildren->end();
473 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
475 ActorPtr actor = (*iter);
477 if( actor.Get() == &child )
479 // Keep handle for OnChildRemove notification
482 // Do this first, since user callbacks from within SetParent() may need to add the child
483 mChildren->erase( iter );
485 DALI_ASSERT_DEBUG( actor->GetParent() == this );
486 actor->SetParent( NULL );
494 // Only put in a relayout request if there is a suitable dependency
495 if( RelayoutDependentOnChildren() )
501 // Notification for derived classes
502 OnChildRemove( child );
505 void Actor::Unparent()
509 // Remove this actor from the parent. The remove will put a relayout request in for
510 // the parent if required
511 mParent->Remove( *this );
512 // mParent is now NULL!
516 unsigned int Actor::GetChildCount() const
518 return ( NULL != mChildren ) ? mChildren->size() : 0;
521 ActorPtr Actor::GetChildAt( unsigned int index ) const
523 DALI_ASSERT_ALWAYS( index < GetChildCount() );
525 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
528 ActorPtr Actor::FindChildByName( const std::string& actorName )
531 if( actorName == mName )
537 ActorIter end = mChildren->end();
538 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
540 child = (*iter)->FindChildByName( actorName );
551 ActorPtr Actor::FindChildById( const unsigned int id )
560 ActorIter end = mChildren->end();
561 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
563 child = (*iter)->FindChildById( id );
574 void Actor::SetParentOrigin( const Vector3& origin )
578 // mNode is being used in a separate thread; queue a message to set the value & base value
579 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
582 // Cache for event-thread access
585 // not allocated, check if different from default
586 if( ParentOrigin::DEFAULT != origin )
588 mParentOrigin = new Vector3( origin );
593 // check if different from current costs more than just set
594 *mParentOrigin = origin;
598 void Actor::SetParentOriginX( float x )
600 const Vector3& current = GetCurrentParentOrigin();
602 SetParentOrigin( Vector3( x, current.y, current.z ) );
605 void Actor::SetParentOriginY( float y )
607 const Vector3& current = GetCurrentParentOrigin();
609 SetParentOrigin( Vector3( current.x, y, current.z ) );
612 void Actor::SetParentOriginZ( float z )
614 const Vector3& current = GetCurrentParentOrigin();
616 SetParentOrigin( Vector3( current.x, current.y, z ) );
619 const Vector3& Actor::GetCurrentParentOrigin() const
621 // Cached for event-thread access
622 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
625 void Actor::SetAnchorPoint( const Vector3& anchor )
629 // mNode is being used in a separate thread; queue a message to set the value & base value
630 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
633 // Cache for event-thread access
636 // not allocated, check if different from default
637 if( AnchorPoint::DEFAULT != anchor )
639 mAnchorPoint = new Vector3( anchor );
644 // check if different from current costs more than just set
645 *mAnchorPoint = anchor;
649 void Actor::SetAnchorPointX( float x )
651 const Vector3& current = GetCurrentAnchorPoint();
653 SetAnchorPoint( Vector3( x, current.y, current.z ) );
656 void Actor::SetAnchorPointY( float y )
658 const Vector3& current = GetCurrentAnchorPoint();
660 SetAnchorPoint( Vector3( current.x, y, current.z ) );
663 void Actor::SetAnchorPointZ( float z )
665 const Vector3& current = GetCurrentAnchorPoint();
667 SetAnchorPoint( Vector3( current.x, current.y, z ) );
670 const Vector3& Actor::GetCurrentAnchorPoint() const
672 // Cached for event-thread access
673 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
676 void Actor::SetPosition( float x, float y )
678 SetPosition( Vector3( x, y, 0.0f ) );
681 void Actor::SetPosition( float x, float y, float z )
683 SetPosition( Vector3( x, y, z ) );
686 void Actor::SetPosition( const Vector3& position )
688 mTargetPosition = position;
692 // mNode is being used in a separate thread; queue a message to set the value & base value
693 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
697 void Actor::SetX( float x )
699 mTargetPosition.x = x;
703 // mNode is being used in a separate thread; queue a message to set the value & base value
704 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
708 void Actor::SetY( float y )
710 mTargetPosition.y = y;
714 // mNode is being used in a separate thread; queue a message to set the value & base value
715 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
719 void Actor::SetZ( float z )
721 mTargetPosition.z = z;
725 // mNode is being used in a separate thread; queue a message to set the value & base value
726 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
730 void Actor::TranslateBy( const Vector3& distance )
732 mTargetPosition += distance;
736 // mNode is being used in a separate thread; queue a message to set the value & base value
737 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
741 const Vector3& Actor::GetCurrentPosition() const
745 // mNode is being used in a separate thread; copy the value from the previous update
746 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
749 return Vector3::ZERO;
752 const Vector3& Actor::GetTargetPosition() const
754 return mTargetPosition;
757 const Vector3& Actor::GetCurrentWorldPosition() const
761 // mNode is being used in a separate thread; copy the value from the previous update
762 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
765 return Vector3::ZERO;
768 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
770 // this flag is not animatable so keep the value
771 mPositionInheritanceMode = mode;
774 // mNode is being used in a separate thread; queue a message to set the value
775 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
779 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
781 // Cached for event-thread access
782 return mPositionInheritanceMode;
785 void Actor::SetInheritPosition( bool inherit )
787 if( mInheritPosition != inherit && NULL != mNode )
789 // non animateable so keep local copy
790 mInheritPosition = inherit;
791 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
795 bool Actor::IsPositionInherited() const
797 return mInheritPosition;
800 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
802 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
803 normalizedAxis.Normalize();
805 Quaternion orientation( angle, normalizedAxis );
807 SetOrientation( orientation );
810 void Actor::SetOrientation( const Quaternion& orientation )
814 // mNode is being used in a separate thread; queue a message to set the value & base value
815 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
819 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
823 // mNode is being used in a separate thread; queue a message to set the value & base value
824 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
828 void Actor::RotateBy( const Quaternion& relativeRotation )
832 // mNode is being used in a separate thread; queue a message to set the value & base value
833 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
837 const Quaternion& Actor::GetCurrentOrientation() const
841 // mNode is being used in a separate thread; copy the value from the previous update
842 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
845 return Quaternion::IDENTITY;
848 const Quaternion& Actor::GetCurrentWorldOrientation() const
852 // mNode is being used in a separate thread; copy the value from the previous update
853 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
856 return Quaternion::IDENTITY;
859 void Actor::SetScale( float scale )
861 SetScale( Vector3( scale, scale, scale ) );
864 void Actor::SetScale( float x, float y, float z )
866 SetScale( Vector3( x, y, z ) );
869 void Actor::SetScale( const Vector3& scale )
873 // mNode is being used in a separate thread; queue a message to set the value & base value
874 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
878 void Actor::SetScaleX( float x )
882 // mNode is being used in a separate thread; queue a message to set the value & base value
883 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
887 void Actor::SetScaleY( float y )
891 // mNode is being used in a separate thread; queue a message to set the value & base value
892 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
896 void Actor::SetScaleZ( float z )
900 // mNode is being used in a separate thread; queue a message to set the value & base value
901 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
905 void Actor::ScaleBy(const Vector3& relativeScale)
909 // mNode is being used in a separate thread; queue a message to set the value & base value
910 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
914 const Vector3& Actor::GetCurrentScale() const
918 // mNode is being used in a separate thread; copy the value from the previous update
919 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
925 const Vector3& Actor::GetCurrentWorldScale() const
929 // mNode is being used in a separate thread; copy the value from the previous update
930 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
936 void Actor::SetInheritScale( bool inherit )
939 if( mInheritScale != inherit && NULL != mNode )
941 // non animateable so keep local copy
942 mInheritScale = inherit;
943 // mNode is being used in a separate thread; queue a message to set the value
944 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
948 bool Actor::IsScaleInherited() const
950 return mInheritScale;
953 Matrix Actor::GetCurrentWorldMatrix() const
957 return mNode->GetWorldMatrix(0);
960 return Matrix::IDENTITY;
963 void Actor::SetVisible( bool visible )
967 // mNode is being used in a separate thread; queue a message to set the value & base value
968 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
972 bool Actor::IsVisible() const
976 // mNode is being used in a separate thread; copy the value from the previous update
977 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
983 void Actor::SetOpacity( float opacity )
987 // mNode is being used in a separate thread; queue a message to set the value & base value
988 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
992 float Actor::GetCurrentOpacity() const
996 // mNode is being used in a separate thread; copy the value from the previous update
997 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1003 const Vector4& Actor::GetCurrentWorldColor() const
1007 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1010 return Color::WHITE;
1013 void Actor::SetColor( const Vector4& color )
1017 // mNode is being used in a separate thread; queue a message to set the value & base value
1018 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1022 void Actor::SetColorRed( float red )
1026 // mNode is being used in a separate thread; queue a message to set the value & base value
1027 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1031 void Actor::SetColorGreen( float green )
1035 // mNode is being used in a separate thread; queue a message to set the value & base value
1036 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1040 void Actor::SetColorBlue( float blue )
1044 // mNode is being used in a separate thread; queue a message to set the value & base value
1045 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1049 const Vector4& Actor::GetCurrentColor() const
1053 // mNode is being used in a separate thread; copy the value from the previous update
1054 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1057 return Color::WHITE;
1060 void Actor::SetInheritOrientation( bool inherit )
1062 if( mInheritOrientation != inherit && NULL != mNode)
1064 // non animateable so keep local copy
1065 mInheritOrientation = inherit;
1066 // mNode is being used in a separate thread; queue a message to set the value
1067 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1071 bool Actor::IsOrientationInherited() const
1073 return mInheritOrientation;
1076 void Actor::SetSizeModeFactor( const Vector3& factor )
1078 EnsureRelayoutData();
1080 mRelayoutData->sizeModeFactor = factor;
1083 const Vector3& Actor::GetSizeModeFactor() const
1085 if ( mRelayoutData )
1087 return mRelayoutData->sizeModeFactor;
1090 return GetDefaultSizeModeFactor();
1093 void Actor::SetColorMode( ColorMode colorMode )
1095 // non animateable so keep local copy
1096 mColorMode = colorMode;
1099 // mNode is being used in a separate thread; queue a message to set the value
1100 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1104 ColorMode Actor::GetColorMode() const
1106 // we have cached copy
1110 void Actor::SetSize( float width, float height )
1112 SetSize( Vector2( width, height ) );
1115 void Actor::SetSize( float width, float height, float depth )
1117 SetSize( Vector3( width, height, depth ) );
1120 void Actor::SetSize( const Vector2& size )
1122 SetSize( Vector3( size.width, size.height, 0.f ) );
1125 void Actor::SetSizeInternal( const Vector2& size )
1127 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1130 void Actor::SetSize( const Vector3& size )
1132 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1134 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1135 SetPreferredSize( size.GetVectorXY() );
1139 SetSizeInternal( size );
1143 void Actor::SetSizeInternal( const Vector3& size )
1145 // dont allow recursive loop
1146 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1147 // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
1148 if( ( NULL != mNode )&&
1149 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1150 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1151 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1155 // mNode is being used in a separate thread; queue a message to set the value & base value
1156 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1158 // Notification for derived classes
1159 mInsideOnSizeSet = true;
1160 OnSizeSet( mTargetSize );
1161 mInsideOnSizeSet = false;
1163 // Raise a relayout request if the flag is not locked
1164 if( mRelayoutData && !mRelayoutData->insideRelayout )
1171 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1173 mTargetSize = targetSize;
1175 // Notify deriving classes
1176 OnSizeAnimation( animation, mTargetSize );
1179 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1181 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1183 mTargetSize.width = targetSize;
1185 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1187 mTargetSize.height = targetSize;
1189 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1191 mTargetSize.depth = targetSize;
1193 // Notify deriving classes
1194 OnSizeAnimation( animation, mTargetSize );
1197 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1199 mTargetPosition = targetPosition;
1202 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1204 if ( Dali::Actor::Property::POSITION_X == property )
1206 mTargetPosition.x = targetPosition;
1208 else if ( Dali::Actor::Property::POSITION_Y == property )
1210 mTargetPosition.y = targetPosition;
1212 else if ( Dali::Actor::Property::POSITION_Z == property )
1214 mTargetPosition.z = targetPosition;
1218 void Actor::SetWidth( float width )
1220 mTargetSize.width = width;
1224 // mNode is being used in a separate thread; queue a message to set the value & base value
1225 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1229 void Actor::SetHeight( float height )
1231 mTargetSize.height = height;
1235 // mNode is being used in a separate thread; queue a message to set the value & base value
1236 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1240 void Actor::SetDepth( float depth )
1242 mTargetSize.depth = depth;
1246 // mNode is being used in a separate thread; queue a message to set the value & base value
1247 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<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 if ( mRelayoutData )
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 ];
1321 return ResizePolicy::DEFAULT;
1324 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1326 EnsureRelayoutData();
1328 mRelayoutData->sizeSetPolicy = policy;
1331 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1333 if ( mRelayoutData )
1335 return mRelayoutData->sizeSetPolicy;
1338 return DEFAULT_SIZE_SCALE_POLICY;
1341 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1343 EnsureRelayoutData();
1345 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1347 if( dimension & ( 1 << i ) )
1349 mRelayoutData->dimensionDependencies[ i ] = dependency;
1354 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1356 if ( mRelayoutData )
1358 // If more than one dimension is requested, just return the first one found
1359 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1361 if( ( dimension & ( 1 << i ) ) )
1363 return mRelayoutData->dimensionDependencies[ i ];
1368 return Dimension::ALL_DIMENSIONS; // Default
1371 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1373 // If relayout data has not been allocated yet and the client is requesting
1374 // to disable it, do nothing
1375 if( mRelayoutData || relayoutEnabled )
1377 EnsureRelayoutData();
1379 mRelayoutData->relayoutEnabled = relayoutEnabled;
1383 bool Actor::IsRelayoutEnabled() const
1385 // Assume that if relayout data has not been allocated yet then
1386 // relayout is disabled
1387 return mRelayoutData && mRelayoutData->relayoutEnabled;
1390 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1392 EnsureRelayoutData();
1394 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1396 if( dimension & ( 1 << i ) )
1398 mRelayoutData->dimensionDirty[ i ] = dirty;
1403 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1405 if ( mRelayoutData )
1407 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1409 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1419 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1421 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1424 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1426 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1429 unsigned int Actor::AddRenderer( Renderer& renderer )
1433 mRenderers = new RendererContainer;
1436 unsigned int index = mRenderers->size();
1437 RendererPtr rendererPtr = RendererPtr( &renderer );
1438 mRenderers->push_back( rendererPtr );
1439 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1443 rendererPtr->Connect();
1449 unsigned int Actor::GetRendererCount() const
1451 unsigned int rendererCount(0);
1454 rendererCount = mRenderers->size();
1457 return rendererCount;
1460 RendererPtr Actor::GetRendererAt( unsigned int index )
1462 RendererPtr renderer;
1463 if( index < GetRendererCount() )
1465 renderer = ( *mRenderers )[ index ];
1471 void Actor::RemoveRenderer( Renderer& renderer )
1475 RendererIter end = mRenderers->end();
1476 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1478 if( (*iter).Get() == &renderer )
1480 mRenderers->erase( iter );
1481 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1488 void Actor::RemoveRenderer( unsigned int index )
1490 if( index < GetRendererCount() )
1492 RendererPtr renderer = ( *mRenderers )[ index ];
1493 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1494 mRenderers->erase( mRenderers->begin()+index );
1498 bool Actor::IsOverlay() const
1500 return ( DrawMode::OVERLAY_2D == mDrawMode );
1503 void Actor::SetDrawMode( DrawMode::Type drawMode )
1505 // this flag is not animatable so keep the value
1506 mDrawMode = drawMode;
1509 // mNode is being used in a separate thread; queue a message to set the value
1510 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1514 DrawMode::Type Actor::GetDrawMode() const
1519 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1521 // only valid when on-stage
1522 StagePtr stage = Stage::GetCurrent();
1523 if( stage && OnStage() )
1525 const RenderTaskList& taskList = stage->GetRenderTaskList();
1527 Vector2 converted( screenX, screenY );
1529 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1530 const int taskCount = taskList.GetTaskCount();
1531 for( int i = taskCount - 1; i >= 0; --i )
1533 Dali::RenderTask task = taskList.GetTask( i );
1534 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1536 // found a task where this conversion was ok so return
1544 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1546 bool retval = false;
1547 // only valid when on-stage
1550 CameraActor* camera = renderTask.GetCameraActor();
1554 renderTask.GetViewport( viewport );
1556 // need to translate coordinates to render tasks coordinate space
1557 Vector2 converted( screenX, screenY );
1558 if( renderTask.TranslateCoordinates( converted ) )
1560 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1567 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1569 // Early-out if mNode is NULL
1575 // Get the ModelView matrix
1577 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1579 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1580 Matrix invertedMvp( false/*don't init*/);
1581 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1582 bool success = invertedMvp.Invert();
1584 // Convert to GL coordinates
1585 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1590 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1597 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1603 if( XyPlaneIntersect( nearPos, farPos, local ) )
1605 Vector3 size = GetCurrentSize();
1606 localX = local.x + size.x * 0.5f;
1607 localY = local.y + size.y * 0.5f;
1618 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1621 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1623 Mathematical Formulation
1625 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1627 ( p - c ) dot ( p - c ) = r^2
1629 Given a ray with a point of origin 'o', and a direction vector 'd':
1631 ray(t) = o + td, t >= 0
1633 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1635 (o + td - c ) dot ( o + td - c ) = r^2
1637 To solve for t we first expand the above into a more recognisable quadratic equation form
1639 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1648 B = 2( o - c ) dot d
1649 C = ( o - c ) dot ( o - c ) - r^2
1651 which can be solved using a standard quadratic formula.
1653 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1655 Practical Simplification
1657 In a renderer, we often differentiate between world space and object space. In the object space
1658 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1659 into object space, the mathematical solution presented above can be simplified significantly.
1661 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1665 and we can find the t at which the (transformed) ray intersects the sphere by
1667 ( o + td ) dot ( o + td ) = r^2
1669 According to the reasoning above, we expand the above quadratic equation into the general form
1673 which now has coefficients:
1680 // Early out if mNode is NULL
1686 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1688 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1689 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1690 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1692 // Compute the radius is not needed, square radius it's enough.
1693 const Vector3& size( mNode->GetSize( bufferIndex ) );
1695 // Scale the sphere.
1696 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1698 const float width = size.width * scale.width;
1699 const float height = size.height * scale.height;
1701 float squareSphereRadius = 0.5f * ( width * width + height * height );
1703 float a = rayDir.Dot( rayDir ); // a
1704 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1705 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1707 return ( b2 * b2 - a * c ) >= 0.f;
1710 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1717 // Transforms the ray to the local reference system.
1718 // Calculate the inverse of Model matrix
1719 Matrix invModelMatrix( false/*don't init*/);
1721 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1722 invModelMatrix = mNode->GetWorldMatrix(0);
1723 invModelMatrix.Invert();
1725 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1726 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1728 // Test with the actor's XY plane (Normal = 0 0 1 1).
1730 float a = -rayOriginLocal.z;
1731 float b = rayDirLocal.z;
1733 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1735 // Ray travels distance * rayDirLocal to intersect with plane.
1738 const Vector3& size = mNode->GetSize( bufferIndex );
1740 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1741 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1743 // Test with the actor's geometry.
1744 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1751 void Actor::SetLeaveRequired( bool required )
1753 mLeaveRequired = required;
1756 bool Actor::GetLeaveRequired() const
1758 return mLeaveRequired;
1761 void Actor::SetKeyboardFocusable( bool focusable )
1763 mKeyboardFocusable = focusable;
1766 bool Actor::IsKeyboardFocusable() const
1768 return mKeyboardFocusable;
1771 bool Actor::GetTouchRequired() const
1773 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1776 bool Actor::GetHoverRequired() const
1778 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1781 bool Actor::GetWheelEventRequired() const
1783 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1786 bool Actor::IsHittable() const
1788 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1791 ActorGestureData& Actor::GetGestureData()
1793 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1794 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1795 if( NULL == mGestureData )
1797 mGestureData = new ActorGestureData;
1799 return *mGestureData;
1802 bool Actor::IsGestureRequred( Gesture::Type type ) const
1804 return mGestureData && mGestureData->IsGestureRequred( type );
1807 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1809 bool consumed = false;
1811 if( !mTouchSignal.Empty() )
1813 Dali::Actor handle( this );
1814 consumed = mTouchSignal.Emit( handle, touch );
1817 if( !mTouchedSignal.Empty() )
1819 Dali::Actor handle( this );
1820 consumed |= mTouchedSignal.Emit( handle, event );
1825 // Notification for derived classes
1826 consumed = OnTouchEvent( event ); // TODO
1832 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1834 bool consumed = false;
1836 if( !mHoveredSignal.Empty() )
1838 Dali::Actor handle( this );
1839 consumed = mHoveredSignal.Emit( handle, event );
1844 // Notification for derived classes
1845 consumed = OnHoverEvent( event );
1851 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1853 bool consumed = false;
1855 if( !mWheelEventSignal.Empty() )
1857 Dali::Actor handle( this );
1858 consumed = mWheelEventSignal.Emit( handle, event );
1863 // Notification for derived classes
1864 consumed = OnWheelEvent( event );
1870 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1872 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1873 return mTouchedSignal;
1876 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1878 return mTouchSignal;
1881 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1883 return mHoveredSignal;
1886 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1888 return mWheelEventSignal;
1891 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1893 return mOnStageSignal;
1896 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1898 return mOffStageSignal;
1901 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1903 return mOnRelayoutSignal;
1906 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1908 bool connected( true );
1909 Actor* actor = dynamic_cast< Actor* >( object );
1911 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1913 actor->TouchedSignal().Connect( tracker, functor );
1915 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1917 actor->HoveredSignal().Connect( tracker, functor );
1919 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1921 actor->WheelEventSignal().Connect( tracker, functor );
1923 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1925 actor->OnStageSignal().Connect( tracker, functor );
1927 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1929 actor->OffStageSignal().Connect( tracker, functor );
1931 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1933 actor->OnRelayoutSignal().Connect( tracker, functor );
1935 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1937 actor->TouchSignal().Connect( tracker, functor );
1941 // signalName does not match any signal
1948 Actor::Actor( DerivedType derivedType )
1953 mParentOrigin( NULL ),
1954 mAnchorPoint( NULL ),
1955 mRelayoutData( NULL ),
1956 mGestureData( NULL ),
1957 mTargetSize( 0.0f, 0.0f, 0.0f ),
1959 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1961 mIsRoot( ROOT_LAYER == derivedType ),
1962 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1963 mIsOnStage( false ),
1965 mLeaveRequired( false ),
1966 mKeyboardFocusable( false ),
1967 mDerivedRequiresTouch( false ),
1968 mDerivedRequiresHover( false ),
1969 mDerivedRequiresWheelEvent( false ),
1970 mOnStageSignalled( false ),
1971 mInsideOnSizeSet( false ),
1972 mInheritPosition( true ),
1973 mInheritOrientation( true ),
1974 mInheritScale( true ),
1975 mDrawMode( DrawMode::NORMAL ),
1976 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1977 mColorMode( Node::DEFAULT_COLOR_MODE )
1981 void Actor::Initialize()
1984 SceneGraph::Node* node = CreateNode();
1986 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
1987 mNode = node; // Keep raw-pointer to Node
1991 GetEventThreadServices().RegisterObject( this );
1996 // Remove mParent pointers from children even if we're destroying core,
1997 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2000 ActorConstIter endIter = mChildren->end();
2001 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2003 (*iter)->SetParent( NULL );
2009 // Guard to allow handle destruction after Core has been destroyed
2010 if( EventThreadServices::IsCoreRunning() )
2014 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2015 mNode = NULL; // Node is about to be destroyed
2018 GetEventThreadServices().UnregisterObject( this );
2021 // Cleanup optional gesture data
2022 delete mGestureData;
2024 // Cleanup optional parent origin and anchor
2025 delete mParentOrigin;
2026 delete mAnchorPoint;
2028 // Delete optional relayout data
2031 delete mRelayoutData;
2035 void Actor::ConnectToStage( unsigned int parentDepth )
2037 // This container is used instead of walking the Actor hierarchy.
2038 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2039 ActorContainer connectionList;
2041 // This stage is atomic i.e. not interrupted by user callbacks.
2042 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2044 // Notify applications about the newly connected actors.
2045 const ActorIter endIter = connectionList.end();
2046 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2048 (*iter)->NotifyStageConnection();
2054 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2056 DALI_ASSERT_ALWAYS( !OnStage() );
2061 ConnectToSceneGraph();
2063 // Notification for internal derived classes
2064 OnStageConnectionInternal();
2066 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2067 connectionList.push_back( ActorPtr( this ) );
2069 // Recursively connect children
2072 ActorConstIter endIter = mChildren->end();
2073 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2075 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2081 * This method is called when the Actor is connected to the Stage.
2082 * The parent must have added its Node to the scene-graph.
2083 * The child must connect its Node to the parent's Node.
2084 * This is recursive; the child calls ConnectToStage() for its children.
2086 void Actor::ConnectToSceneGraph()
2088 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2092 // Reparent Node in next Update
2093 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2096 unsigned int rendererCount( GetRendererCount() );
2097 for( unsigned int i(0); i<rendererCount; ++i )
2099 GetRendererAt(i)->Connect();
2102 // Request relayout on all actors that are added to the scenegraph
2105 // Notification for Object::Observers
2109 void Actor::NotifyStageConnection()
2111 // Actors can be removed (in a callback), before the on-stage stage is reported.
2112 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2113 if( OnStage() && !mOnStageSignalled )
2115 // Notification for external (CustomActor) derived classes
2116 OnStageConnectionExternal( mDepth );
2118 if( !mOnStageSignal.Empty() )
2120 Dali::Actor handle( this );
2121 mOnStageSignal.Emit( handle );
2124 // Guard against Remove during callbacks
2127 mOnStageSignalled = true; // signal required next time Actor is removed
2132 void Actor::DisconnectFromStage()
2134 // This container is used instead of walking the Actor hierachy.
2135 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2136 ActorContainer disconnectionList;
2138 // This stage is atomic i.e. not interrupted by user callbacks
2139 RecursiveDisconnectFromStage( disconnectionList );
2141 // Notify applications about the newly disconnected actors.
2142 const ActorIter endIter = disconnectionList.end();
2143 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2145 (*iter)->NotifyStageDisconnection();
2149 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2151 DALI_ASSERT_ALWAYS( OnStage() );
2153 // Recursively disconnect children
2156 ActorConstIter endIter = mChildren->end();
2157 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2159 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2163 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2164 disconnectionList.push_back( ActorPtr( this ) );
2166 // Notification for internal derived classes
2167 OnStageDisconnectionInternal();
2169 DisconnectFromSceneGraph();
2175 * This method is called by an actor or its parent, before a node removal message is sent.
2176 * This is recursive; the child calls DisconnectFromStage() for its children.
2178 void Actor::DisconnectFromSceneGraph()
2180 // Notification for Object::Observers
2181 OnSceneObjectRemove();
2183 unsigned int rendererCount( GetRendererCount() );
2184 for( unsigned int i(0); i<rendererCount; ++i )
2186 GetRendererAt(i)->Disconnect();
2190 void Actor::NotifyStageDisconnection()
2192 // Actors can be added (in a callback), before the off-stage state is reported.
2193 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2194 // only do this step if there is a stage, i.e. Core is not being shut down
2195 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2197 // Notification for external (CustomeActor) derived classes
2198 OnStageDisconnectionExternal();
2200 if( !mOffStageSignal.Empty() )
2202 Dali::Actor handle( this );
2203 mOffStageSignal.Emit( handle );
2206 // Guard against Add during callbacks
2209 mOnStageSignalled = false; // signal required next time Actor is added
2214 bool Actor::IsNodeConnected() const
2216 bool connected( false );
2218 if( OnStage() && ( NULL != mNode ) )
2220 if( IsRoot() || mNode->GetParent() )
2229 unsigned int Actor::GetDefaultPropertyCount() const
2231 return DEFAULT_PROPERTY_COUNT;
2234 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2236 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2238 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2240 indices.PushBack( i );
2244 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2246 if( index < DEFAULT_PROPERTY_COUNT )
2248 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2254 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2256 Property::Index index = Property::INVALID_INDEX;
2258 // Look for name in default properties
2259 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2261 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2262 if( 0 == name.compare( property->name ) )
2272 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2274 if( index < DEFAULT_PROPERTY_COUNT )
2276 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2282 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2284 if( index < DEFAULT_PROPERTY_COUNT )
2286 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2292 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2294 if( index < DEFAULT_PROPERTY_COUNT )
2296 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2302 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2304 if( index < DEFAULT_PROPERTY_COUNT )
2306 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2309 // index out of range...return Property::NONE
2310 return Property::NONE;
2313 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2317 case Dali::Actor::Property::PARENT_ORIGIN:
2319 Property::Type type = property.GetType();
2320 if( type == Property::VECTOR3 )
2322 SetParentOrigin( property.Get< Vector3 >() );
2324 else if ( type == Property::STRING )
2326 std::string parentOriginString;
2327 property.Get( parentOriginString );
2328 Vector3 parentOrigin;
2329 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2331 SetParentOrigin( parentOrigin );
2337 case Dali::Actor::Property::PARENT_ORIGIN_X:
2339 SetParentOriginX( property.Get< float >() );
2343 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2345 SetParentOriginY( property.Get< float >() );
2349 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2351 SetParentOriginZ( property.Get< float >() );
2355 case Dali::Actor::Property::ANCHOR_POINT:
2357 Property::Type type = property.GetType();
2358 if( type == Property::VECTOR3 )
2360 SetAnchorPoint( property.Get< Vector3 >() );
2362 else if ( type == Property::STRING )
2364 std::string anchorPointString;
2365 property.Get( anchorPointString );
2367 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2369 SetAnchorPoint( anchor );
2375 case Dali::Actor::Property::ANCHOR_POINT_X:
2377 SetAnchorPointX( property.Get< float >() );
2381 case Dali::Actor::Property::ANCHOR_POINT_Y:
2383 SetAnchorPointY( property.Get< float >() );
2387 case Dali::Actor::Property::ANCHOR_POINT_Z:
2389 SetAnchorPointZ( property.Get< float >() );
2393 case Dali::Actor::Property::SIZE:
2395 SetSize( property.Get< Vector3 >() );
2399 case Dali::Actor::Property::SIZE_WIDTH:
2401 SetWidth( property.Get< float >() );
2405 case Dali::Actor::Property::SIZE_HEIGHT:
2407 SetHeight( property.Get< float >() );
2411 case Dali::Actor::Property::SIZE_DEPTH:
2413 SetDepth( property.Get< float >() );
2417 case Dali::Actor::Property::POSITION:
2419 SetPosition( property.Get< Vector3 >() );
2423 case Dali::Actor::Property::POSITION_X:
2425 SetX( property.Get< float >() );
2429 case Dali::Actor::Property::POSITION_Y:
2431 SetY( property.Get< float >() );
2435 case Dali::Actor::Property::POSITION_Z:
2437 SetZ( property.Get< float >() );
2441 case Dali::Actor::Property::ORIENTATION:
2443 SetOrientation( property.Get< Quaternion >() );
2447 case Dali::Actor::Property::SCALE:
2449 SetScale( property.Get< Vector3 >() );
2453 case Dali::Actor::Property::SCALE_X:
2455 SetScaleX( property.Get< float >() );
2459 case Dali::Actor::Property::SCALE_Y:
2461 SetScaleY( property.Get< float >() );
2465 case Dali::Actor::Property::SCALE_Z:
2467 SetScaleZ( property.Get< float >() );
2471 case Dali::Actor::Property::VISIBLE:
2473 SetVisible( property.Get< bool >() );
2477 case Dali::Actor::Property::COLOR:
2479 SetColor( property.Get< Vector4 >() );
2483 case Dali::Actor::Property::COLOR_RED:
2485 SetColorRed( property.Get< float >() );
2489 case Dali::Actor::Property::COLOR_GREEN:
2491 SetColorGreen( property.Get< float >() );
2495 case Dali::Actor::Property::COLOR_BLUE:
2497 SetColorBlue( property.Get< float >() );
2501 case Dali::Actor::Property::COLOR_ALPHA:
2503 SetOpacity( property.Get< float >() );
2507 case Dali::Actor::Property::NAME:
2509 SetName( property.Get< std::string >() );
2513 case Dali::Actor::Property::SENSITIVE:
2515 SetSensitive( property.Get< bool >() );
2519 case Dali::Actor::Property::LEAVE_REQUIRED:
2521 SetLeaveRequired( property.Get< bool >() );
2525 case Dali::Actor::Property::INHERIT_POSITION:
2527 SetInheritPosition( property.Get< bool >() );
2531 case Dali::Actor::Property::INHERIT_ORIENTATION:
2533 SetInheritOrientation( property.Get< bool >() );
2537 case Dali::Actor::Property::INHERIT_SCALE:
2539 SetInheritScale( property.Get< bool >() );
2543 case Dali::Actor::Property::COLOR_MODE:
2546 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2548 SetColorMode( mode );
2553 case Dali::Actor::Property::POSITION_INHERITANCE:
2555 PositionInheritanceMode mode;
2556 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2558 SetPositionInheritanceMode( mode );
2563 case Dali::Actor::Property::DRAW_MODE:
2565 DrawMode::Type mode;
2566 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2568 SetDrawMode( mode );
2573 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2575 SetSizeModeFactor( property.Get< Vector3 >() );
2579 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2581 ResizePolicy::Type type;
2582 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2584 SetResizePolicy( type, Dimension::WIDTH );
2589 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2591 ResizePolicy::Type type;
2592 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2594 SetResizePolicy( type, Dimension::HEIGHT );
2599 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2601 SizeScalePolicy::Type type;
2602 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2604 SetSizeScalePolicy( type );
2609 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2611 if( property.Get< bool >() )
2613 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2618 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2620 if( property.Get< bool >() )
2622 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2627 case Dali::Actor::Property::PADDING:
2629 Vector4 padding = property.Get< Vector4 >();
2630 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2631 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2635 case Dali::Actor::Property::MINIMUM_SIZE:
2637 Vector2 size = property.Get< Vector2 >();
2638 SetMinimumSize( size.x, Dimension::WIDTH );
2639 SetMinimumSize( size.y, Dimension::HEIGHT );
2643 case Dali::Actor::Property::MAXIMUM_SIZE:
2645 Vector2 size = property.Get< Vector2 >();
2646 SetMaximumSize( size.x, Dimension::WIDTH );
2647 SetMaximumSize( size.y, Dimension::HEIGHT );
2653 // this can happen in the case of a non-animatable default property so just do nothing
2659 // TODO: This method needs to be removed
2660 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2662 switch( entry.GetType() )
2664 case Property::BOOLEAN:
2666 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2667 DALI_ASSERT_DEBUG( NULL != property );
2669 // property is being used in a separate thread; queue a message to set the property
2670 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2675 case Property::INTEGER:
2677 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2678 DALI_ASSERT_DEBUG( NULL != property );
2680 // property is being used in a separate thread; queue a message to set the property
2681 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2686 case Property::FLOAT:
2688 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2689 DALI_ASSERT_DEBUG( NULL != property );
2691 // property is being used in a separate thread; queue a message to set the property
2692 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2697 case Property::VECTOR2:
2699 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2700 DALI_ASSERT_DEBUG( NULL != property );
2702 // property is being used in a separate thread; queue a message to set the property
2703 if(entry.componentIndex == 0)
2705 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2707 else if(entry.componentIndex == 1)
2709 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2713 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2719 case Property::VECTOR3:
2721 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2722 DALI_ASSERT_DEBUG( NULL != property );
2724 // property is being used in a separate thread; queue a message to set the property
2725 if(entry.componentIndex == 0)
2727 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2729 else if(entry.componentIndex == 1)
2731 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2733 else if(entry.componentIndex == 2)
2735 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2739 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2745 case Property::VECTOR4:
2747 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2748 DALI_ASSERT_DEBUG( NULL != property );
2750 // property is being used in a separate thread; queue a message to set the property
2751 if(entry.componentIndex == 0)
2753 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2755 else if(entry.componentIndex == 1)
2757 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2759 else if(entry.componentIndex == 2)
2761 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2763 else if(entry.componentIndex == 3)
2765 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2769 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2775 case Property::ROTATION:
2777 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2778 DALI_ASSERT_DEBUG( NULL != property );
2780 // property is being used in a separate thread; queue a message to set the property
2781 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2786 case Property::MATRIX:
2788 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2789 DALI_ASSERT_DEBUG( NULL != property );
2791 // property is being used in a separate thread; queue a message to set the property
2792 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2797 case Property::MATRIX3:
2799 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2800 DALI_ASSERT_DEBUG( NULL != property );
2802 // property is being used in a separate thread; queue a message to set the property
2803 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2810 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2816 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2818 Property::Value value;
2822 case Dali::Actor::Property::PARENT_ORIGIN:
2824 value = GetCurrentParentOrigin();
2828 case Dali::Actor::Property::PARENT_ORIGIN_X:
2830 value = GetCurrentParentOrigin().x;
2834 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2836 value = GetCurrentParentOrigin().y;
2840 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2842 value = GetCurrentParentOrigin().z;
2846 case Dali::Actor::Property::ANCHOR_POINT:
2848 value = GetCurrentAnchorPoint();
2852 case Dali::Actor::Property::ANCHOR_POINT_X:
2854 value = GetCurrentAnchorPoint().x;
2858 case Dali::Actor::Property::ANCHOR_POINT_Y:
2860 value = GetCurrentAnchorPoint().y;
2864 case Dali::Actor::Property::ANCHOR_POINT_Z:
2866 value = GetCurrentAnchorPoint().z;
2870 case Dali::Actor::Property::SIZE:
2872 value = GetTargetSize();
2876 case Dali::Actor::Property::SIZE_WIDTH:
2878 value = GetTargetSize().width;
2882 case Dali::Actor::Property::SIZE_HEIGHT:
2884 value = GetTargetSize().height;
2888 case Dali::Actor::Property::SIZE_DEPTH:
2890 value = GetTargetSize().depth;
2894 case Dali::Actor::Property::POSITION:
2896 value = GetTargetPosition();
2900 case Dali::Actor::Property::POSITION_X:
2902 value = GetTargetPosition().x;
2906 case Dali::Actor::Property::POSITION_Y:
2908 value = GetTargetPosition().y;
2912 case Dali::Actor::Property::POSITION_Z:
2914 value = GetTargetPosition().z;
2918 case Dali::Actor::Property::WORLD_POSITION:
2920 value = GetCurrentWorldPosition();
2924 case Dali::Actor::Property::WORLD_POSITION_X:
2926 value = GetCurrentWorldPosition().x;
2930 case Dali::Actor::Property::WORLD_POSITION_Y:
2932 value = GetCurrentWorldPosition().y;
2936 case Dali::Actor::Property::WORLD_POSITION_Z:
2938 value = GetCurrentWorldPosition().z;
2942 case Dali::Actor::Property::ORIENTATION:
2944 value = GetCurrentOrientation();
2948 case Dali::Actor::Property::WORLD_ORIENTATION:
2950 value = GetCurrentWorldOrientation();
2954 case Dali::Actor::Property::SCALE:
2956 value = GetCurrentScale();
2960 case Dali::Actor::Property::SCALE_X:
2962 value = GetCurrentScale().x;
2966 case Dali::Actor::Property::SCALE_Y:
2968 value = GetCurrentScale().y;
2972 case Dali::Actor::Property::SCALE_Z:
2974 value = GetCurrentScale().z;
2978 case Dali::Actor::Property::WORLD_SCALE:
2980 value = GetCurrentWorldScale();
2984 case Dali::Actor::Property::VISIBLE:
2986 value = IsVisible();
2990 case Dali::Actor::Property::COLOR:
2992 value = GetCurrentColor();
2996 case Dali::Actor::Property::COLOR_RED:
2998 value = GetCurrentColor().r;
3002 case Dali::Actor::Property::COLOR_GREEN:
3004 value = GetCurrentColor().g;
3008 case Dali::Actor::Property::COLOR_BLUE:
3010 value = GetCurrentColor().b;
3014 case Dali::Actor::Property::COLOR_ALPHA:
3016 value = GetCurrentColor().a;
3020 case Dali::Actor::Property::WORLD_COLOR:
3022 value = GetCurrentWorldColor();
3026 case Dali::Actor::Property::WORLD_MATRIX:
3028 value = GetCurrentWorldMatrix();
3032 case Dali::Actor::Property::NAME:
3038 case Dali::Actor::Property::SENSITIVE:
3040 value = IsSensitive();
3044 case Dali::Actor::Property::LEAVE_REQUIRED:
3046 value = GetLeaveRequired();
3050 case Dali::Actor::Property::INHERIT_POSITION:
3052 value = IsPositionInherited();
3056 case Dali::Actor::Property::INHERIT_ORIENTATION:
3058 value = IsOrientationInherited();
3062 case Dali::Actor::Property::INHERIT_SCALE:
3064 value = IsScaleInherited();
3068 case Dali::Actor::Property::COLOR_MODE:
3070 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3074 case Dali::Actor::Property::POSITION_INHERITANCE:
3076 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3080 case Dali::Actor::Property::DRAW_MODE:
3082 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3086 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3088 value = GetSizeModeFactor();
3092 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3094 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3098 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3100 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3104 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3106 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3110 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3112 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3116 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3118 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3122 case Dali::Actor::Property::PADDING:
3124 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3125 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3126 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3130 case Dali::Actor::Property::MINIMUM_SIZE:
3132 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3136 case Dali::Actor::Property::MAXIMUM_SIZE:
3138 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3144 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3152 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3157 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3159 // This method should only return an object connected to the scene-graph
3160 return OnStage() ? mNode : NULL;
3163 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3165 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3167 const PropertyBase* property( NULL );
3169 // This method should only return a property of an object connected to the scene-graph
3175 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3177 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3178 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3180 property = animatable->GetSceneGraphProperty();
3182 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3184 CustomPropertyMetadata* custom = FindCustomProperty( index );
3185 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3187 property = custom->GetSceneGraphProperty();
3189 else if( NULL != mNode )
3193 case Dali::Actor::Property::SIZE:
3194 property = &mNode->mSize;
3197 case Dali::Actor::Property::SIZE_WIDTH:
3198 property = &mNode->mSize;
3201 case Dali::Actor::Property::SIZE_HEIGHT:
3202 property = &mNode->mSize;
3205 case Dali::Actor::Property::SIZE_DEPTH:
3206 property = &mNode->mSize;
3209 case Dali::Actor::Property::POSITION:
3210 property = &mNode->mPosition;
3213 case Dali::Actor::Property::POSITION_X:
3214 property = &mNode->mPosition;
3217 case Dali::Actor::Property::POSITION_Y:
3218 property = &mNode->mPosition;
3221 case Dali::Actor::Property::POSITION_Z:
3222 property = &mNode->mPosition;
3225 case Dali::Actor::Property::ORIENTATION:
3226 property = &mNode->mOrientation;
3229 case Dali::Actor::Property::SCALE:
3230 property = &mNode->mScale;
3233 case Dali::Actor::Property::SCALE_X:
3234 property = &mNode->mScale;
3237 case Dali::Actor::Property::SCALE_Y:
3238 property = &mNode->mScale;
3241 case Dali::Actor::Property::SCALE_Z:
3242 property = &mNode->mScale;
3245 case Dali::Actor::Property::VISIBLE:
3246 property = &mNode->mVisible;
3249 case Dali::Actor::Property::COLOR:
3250 property = &mNode->mColor;
3253 case Dali::Actor::Property::COLOR_RED:
3254 property = &mNode->mColor;
3257 case Dali::Actor::Property::COLOR_GREEN:
3258 property = &mNode->mColor;
3261 case Dali::Actor::Property::COLOR_BLUE:
3262 property = &mNode->mColor;
3265 case Dali::Actor::Property::COLOR_ALPHA:
3266 property = &mNode->mColor;
3277 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3279 const PropertyInputImpl* property( NULL );
3281 // This method should only return a property of an object connected to the scene-graph
3287 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3289 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3290 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3292 property = animatable->GetSceneGraphProperty();
3294 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3296 CustomPropertyMetadata* custom = FindCustomProperty( index );
3297 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3298 property = custom->GetSceneGraphProperty();
3300 else if( NULL != mNode )
3304 case Dali::Actor::Property::PARENT_ORIGIN:
3305 property = &mNode->mParentOrigin;
3308 case Dali::Actor::Property::PARENT_ORIGIN_X:
3309 property = &mNode->mParentOrigin;
3312 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3313 property = &mNode->mParentOrigin;
3316 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3317 property = &mNode->mParentOrigin;
3320 case Dali::Actor::Property::ANCHOR_POINT:
3321 property = &mNode->mAnchorPoint;
3324 case Dali::Actor::Property::ANCHOR_POINT_X:
3325 property = &mNode->mAnchorPoint;
3328 case Dali::Actor::Property::ANCHOR_POINT_Y:
3329 property = &mNode->mAnchorPoint;
3332 case Dali::Actor::Property::ANCHOR_POINT_Z:
3333 property = &mNode->mAnchorPoint;
3336 case Dali::Actor::Property::SIZE:
3337 property = &mNode->mSize;
3340 case Dali::Actor::Property::SIZE_WIDTH:
3341 property = &mNode->mSize;
3344 case Dali::Actor::Property::SIZE_HEIGHT:
3345 property = &mNode->mSize;
3348 case Dali::Actor::Property::SIZE_DEPTH:
3349 property = &mNode->mSize;
3352 case Dali::Actor::Property::POSITION:
3353 property = &mNode->mPosition;
3356 case Dali::Actor::Property::POSITION_X:
3357 property = &mNode->mPosition;
3360 case Dali::Actor::Property::POSITION_Y:
3361 property = &mNode->mPosition;
3364 case Dali::Actor::Property::POSITION_Z:
3365 property = &mNode->mPosition;
3368 case Dali::Actor::Property::WORLD_POSITION:
3369 property = &mNode->mWorldPosition;
3372 case Dali::Actor::Property::WORLD_POSITION_X:
3373 property = &mNode->mWorldPosition;
3376 case Dali::Actor::Property::WORLD_POSITION_Y:
3377 property = &mNode->mWorldPosition;
3380 case Dali::Actor::Property::WORLD_POSITION_Z:
3381 property = &mNode->mWorldPosition;
3384 case Dali::Actor::Property::ORIENTATION:
3385 property = &mNode->mOrientation;
3388 case Dali::Actor::Property::WORLD_ORIENTATION:
3389 property = &mNode->mWorldOrientation;
3392 case Dali::Actor::Property::SCALE:
3393 property = &mNode->mScale;
3396 case Dali::Actor::Property::SCALE_X:
3397 property = &mNode->mScale;
3400 case Dali::Actor::Property::SCALE_Y:
3401 property = &mNode->mScale;
3404 case Dali::Actor::Property::SCALE_Z:
3405 property = &mNode->mScale;
3408 case Dali::Actor::Property::WORLD_SCALE:
3409 property = &mNode->mWorldScale;
3412 case Dali::Actor::Property::VISIBLE:
3413 property = &mNode->mVisible;
3416 case Dali::Actor::Property::COLOR:
3417 property = &mNode->mColor;
3420 case Dali::Actor::Property::COLOR_RED:
3421 property = &mNode->mColor;
3424 case Dali::Actor::Property::COLOR_GREEN:
3425 property = &mNode->mColor;
3428 case Dali::Actor::Property::COLOR_BLUE:
3429 property = &mNode->mColor;
3432 case Dali::Actor::Property::COLOR_ALPHA:
3433 property = &mNode->mColor;
3436 case Dali::Actor::Property::WORLD_COLOR:
3437 property = &mNode->mWorldColor;
3440 case Dali::Actor::Property::WORLD_MATRIX:
3441 property = &mNode->mWorldMatrix;
3452 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3454 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3456 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3458 // check whether the animatable property is registered already, if not then register one.
3459 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3460 if( animatableProperty )
3462 componentIndex = animatableProperty->componentIndex;
3469 case Dali::Actor::Property::PARENT_ORIGIN_X:
3470 case Dali::Actor::Property::ANCHOR_POINT_X:
3471 case Dali::Actor::Property::SIZE_WIDTH:
3472 case Dali::Actor::Property::POSITION_X:
3473 case Dali::Actor::Property::WORLD_POSITION_X:
3474 case Dali::Actor::Property::SCALE_X:
3475 case Dali::Actor::Property::COLOR_RED:
3481 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3482 case Dali::Actor::Property::ANCHOR_POINT_Y:
3483 case Dali::Actor::Property::SIZE_HEIGHT:
3484 case Dali::Actor::Property::POSITION_Y:
3485 case Dali::Actor::Property::WORLD_POSITION_Y:
3486 case Dali::Actor::Property::SCALE_Y:
3487 case Dali::Actor::Property::COLOR_GREEN:
3493 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3494 case Dali::Actor::Property::ANCHOR_POINT_Z:
3495 case Dali::Actor::Property::SIZE_DEPTH:
3496 case Dali::Actor::Property::POSITION_Z:
3497 case Dali::Actor::Property::WORLD_POSITION_Z:
3498 case Dali::Actor::Property::SCALE_Z:
3499 case Dali::Actor::Property::COLOR_BLUE:
3505 case Dali::Actor::Property::COLOR_ALPHA:
3519 return componentIndex;
3522 void Actor::SetParent( Actor* parent )
3526 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3530 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3533 // Instruct each actor to create a corresponding node in the scene graph
3534 ConnectToStage( parent->GetHierarchyDepth() );
3537 // Resolve the name and index for the child properties if any
3538 ResolveChildProperties();
3540 else // parent being set to NULL
3542 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3546 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3549 DALI_ASSERT_ALWAYS( mNode != NULL );
3553 // Disconnect the Node & its children from the scene-graph.
3554 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3557 // Instruct each actor to discard pointers to the scene-graph
3558 DisconnectFromStage();
3563 SceneGraph::Node* Actor::CreateNode() const
3568 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3571 Actor* actor = dynamic_cast< Actor* >( object );
3575 if( 0 == actionName.compare( ACTION_SHOW ) )
3577 actor->SetVisible( true );
3580 else if( 0 == actionName.compare( ACTION_HIDE ) )
3582 actor->SetVisible( false );
3590 void Actor::EnsureRelayoutData()
3592 // Assign relayout data.
3593 if( !mRelayoutData )
3595 mRelayoutData = new RelayoutData();
3599 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3601 // Check if actor is dependent on parent
3602 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3604 if( ( dimension & ( 1 << i ) ) )
3606 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3607 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3617 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3619 // Check if actor is dependent on children
3620 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3622 if( ( dimension & ( 1 << i ) ) )
3624 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3625 switch( resizePolicy )
3627 case ResizePolicy::FIT_TO_CHILDREN:
3628 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3644 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3646 return Actor::RelayoutDependentOnChildren( dimension );
3649 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3651 // Check each possible dimension and see if it is dependent on the input one
3652 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3654 if( dimension & ( 1 << i ) )
3656 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3663 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3665 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3667 if( dimension & ( 1 << i ) )
3669 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3674 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3676 // If more than one dimension is requested, just return the first one found
3677 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3679 if( ( dimension & ( 1 << i ) ) )
3681 return mRelayoutData->negotiatedDimensions[ i ];
3685 return 0.0f; // Default
3688 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3690 EnsureRelayoutData();
3692 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3694 if( dimension & ( 1 << i ) )
3696 mRelayoutData->dimensionPadding[ i ] = padding;
3701 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3703 if ( mRelayoutData )
3705 // If more than one dimension is requested, just return the first one found
3706 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3708 if( ( dimension & ( 1 << i ) ) )
3710 return mRelayoutData->dimensionPadding[ i ];
3715 return GetDefaultDimensionPadding();
3718 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3720 EnsureRelayoutData();
3722 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3724 if( dimension & ( 1 << i ) )
3726 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3731 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3733 if ( mRelayoutData )
3735 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3737 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3747 float Actor::GetHeightForWidthBase( float width )
3749 float height = 0.0f;
3751 const Vector3 naturalSize = GetNaturalSize();
3752 if( naturalSize.width > 0.0f )
3754 height = naturalSize.height * width / naturalSize.width;
3756 else // we treat 0 as 1:1 aspect ratio
3764 float Actor::GetWidthForHeightBase( float height )
3768 const Vector3 naturalSize = GetNaturalSize();
3769 if( naturalSize.height > 0.0f )
3771 width = naturalSize.width * height / naturalSize.height;
3773 else // we treat 0 as 1:1 aspect ratio
3781 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3783 // Fill to parent, taking size mode factor into account
3784 switch( child.GetResizePolicy( dimension ) )
3786 case ResizePolicy::FILL_TO_PARENT:
3788 return GetLatestSize( dimension );
3791 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3793 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3796 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3798 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3803 return GetLatestSize( dimension );
3808 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3810 // Can be overridden in derived class
3811 return CalculateChildSizeBase( child, dimension );
3814 float Actor::GetHeightForWidth( float width )
3816 // Can be overridden in derived class
3817 return GetHeightForWidthBase( width );
3820 float Actor::GetWidthForHeight( float height )
3822 // Can be overridden in derived class
3823 return GetWidthForHeightBase( height );
3826 float Actor::GetLatestSize( Dimension::Type dimension ) const
3828 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3831 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3833 Vector2 padding = GetPadding( dimension );
3835 return GetLatestSize( dimension ) + padding.x + padding.y;
3838 float Actor::NegotiateFromParent( Dimension::Type dimension )
3840 Actor* parent = GetParent();
3843 Vector2 padding( GetPadding( dimension ) );
3844 Vector2 parentPadding( parent->GetPadding( dimension ) );
3845 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3851 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3853 float maxDimensionPoint = 0.0f;
3855 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3857 ActorPtr child = GetChildAt( i );
3859 if( !child->RelayoutDependentOnParent( dimension ) )
3861 // Calculate the min and max points that the children range across
3862 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3863 float dimensionSize = child->GetRelayoutSize( dimension );
3864 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3868 return maxDimensionPoint;
3871 float Actor::GetSize( Dimension::Type dimension ) const
3873 return GetDimensionValue( GetTargetSize(), dimension );
3876 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3878 return GetDimensionValue( GetNaturalSize(), dimension );
3881 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3883 switch( GetResizePolicy( dimension ) )
3885 case ResizePolicy::USE_NATURAL_SIZE:
3887 return GetNaturalSize( dimension );
3890 case ResizePolicy::FIXED:
3892 return GetDimensionValue( GetPreferredSize(), dimension );
3895 case ResizePolicy::USE_ASSIGNED_SIZE:
3897 return GetDimensionValue( maximumSize, dimension );
3900 case ResizePolicy::FILL_TO_PARENT:
3901 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3902 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3904 return NegotiateFromParent( dimension );
3907 case ResizePolicy::FIT_TO_CHILDREN:
3909 return NegotiateFromChildren( dimension );
3912 case ResizePolicy::DIMENSION_DEPENDENCY:
3914 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3917 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3919 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3922 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3924 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3936 return 0.0f; // Default
3939 float Actor::ClampDimension( float size, Dimension::Type dimension )
3941 const float minSize = GetMinimumSize( dimension );
3942 const float maxSize = GetMaximumSize( dimension );
3944 return std::max( minSize, std::min( size, maxSize ) );
3947 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
3949 // Check if it needs to be negotiated
3950 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
3952 // Check that we havn't gotten into an infinite loop
3953 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
3954 bool recursionFound = false;
3955 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
3957 if( *it == searchActor )
3959 recursionFound = true;
3964 if( !recursionFound )
3966 // Record the path that we have taken
3967 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
3969 // Dimension dependency check
3970 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3972 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
3974 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
3976 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
3980 // Parent dependency check
3981 Actor* parent = GetParent();
3982 if( parent && RelayoutDependentOnParent( dimension ) )
3984 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
3987 // Children dependency check
3988 if( RelayoutDependentOnChildren( dimension ) )
3990 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3992 ActorPtr child = GetChildAt( i );
3994 // Only relayout child first if it is not dependent on this actor
3995 if( !child->RelayoutDependentOnParent( dimension ) )
3997 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4002 // For deriving classes
4003 OnCalculateRelayoutSize( dimension );
4005 // All dependencies checked, calculate the size and set negotiated flag
4006 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4008 SetNegotiatedDimension( newSize, dimension );
4009 SetLayoutNegotiated( true, dimension );
4011 // For deriving classes
4012 OnLayoutNegotiated( newSize, dimension );
4014 // This actor has been successfully processed, pop it off the recursion stack
4015 recursionStack.pop_back();
4019 // TODO: Break infinite loop
4020 SetLayoutNegotiated( true, dimension );
4025 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4027 // Negotiate all dimensions that require it
4028 ActorDimensionStack recursionStack;
4030 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4032 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4035 NegotiateDimension( dimension, allocatedSize, recursionStack );
4039 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4041 switch( mRelayoutData->sizeSetPolicy )
4043 case SizeScalePolicy::USE_SIZE_SET:
4048 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4050 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4051 const Vector3 naturalSize = GetNaturalSize();
4052 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4054 const float sizeRatio = size.width / size.height;
4055 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4057 if( naturalSizeRatio < sizeRatio )
4059 return Vector2( naturalSizeRatio * size.height, size.height );
4061 else if( naturalSizeRatio > sizeRatio )
4063 return Vector2( size.width, size.width / naturalSizeRatio );
4074 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4076 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4077 const Vector3 naturalSize = GetNaturalSize();
4078 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4080 const float sizeRatio = size.width / size.height;
4081 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4083 if( naturalSizeRatio < sizeRatio )
4085 return Vector2( size.width, size.width / naturalSizeRatio );
4087 else if( naturalSizeRatio > sizeRatio )
4089 return Vector2( naturalSizeRatio * size.height, size.height );
4108 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4110 // Do the set actor size
4111 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4113 // Adjust for size set policy
4114 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4116 // Lock the flag to stop recursive relayouts on set size
4117 mRelayoutData->insideRelayout = true;
4118 SetSize( negotiatedSize );
4119 mRelayoutData->insideRelayout = false;
4121 // Clear flags for all dimensions
4122 SetLayoutDirty( false );
4124 // Give deriving classes a chance to respond
4125 OnRelayout( negotiatedSize, container );
4127 if( !mOnRelayoutSignal.Empty() )
4129 Dali::Actor handle( this );
4130 mOnRelayoutSignal.Emit( handle );
4134 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4136 // Force a size negotiation for actors that has assigned size during relayout
4137 // This is required as otherwise the flags that force a relayout will not
4138 // necessarilly be set. This will occur if the actor has already been laid out.
4139 // The dirty flags are then cleared. Then if the actor is added back into the
4140 // relayout container afterwards, the dirty flags would still be clear...
4141 // causing a relayout to be skipped. Here we force any actors added to the
4142 // container to be relayed out.
4143 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4145 SetLayoutNegotiated(false, Dimension::WIDTH);
4147 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4149 SetLayoutNegotiated(false, Dimension::HEIGHT);
4152 // Do the negotiation
4153 NegotiateDimensions( allocatedSize );
4155 // Set the actor size
4156 SetNegotiatedSize( container );
4158 // Negotiate down to children
4159 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4161 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4163 ActorPtr child = GetChildAt( i );
4165 // Forces children that have already been laid out to be relayed out
4166 // if they have assigned size during relayout.
4167 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4169 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4170 child->SetLayoutDirty(true, Dimension::WIDTH);
4172 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4174 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4175 child->SetLayoutDirty(true, Dimension::HEIGHT);
4178 // Only relayout if required
4179 if( child->RelayoutRequired() )
4181 container.Add( Dali::Actor( child.Get() ), newBounds );
4186 void Actor::RelayoutRequest( Dimension::Type dimension )
4188 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4189 if( relayoutController )
4191 Dali::Actor self( this );
4192 relayoutController->RequestRelayout( self, dimension );
4196 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4200 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4204 void Actor::SetPreferredSize( const Vector2& size )
4206 EnsureRelayoutData();
4208 if( size.width > 0.0f )
4210 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4213 if( size.height > 0.0f )
4215 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4218 mRelayoutData->preferredSize = size;
4223 Vector2 Actor::GetPreferredSize() const
4225 if ( mRelayoutData )
4227 return Vector2( mRelayoutData->preferredSize );
4230 return GetDefaultPreferredSize();
4233 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4235 EnsureRelayoutData();
4237 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4239 if( dimension & ( 1 << i ) )
4241 mRelayoutData->minimumSize[ i ] = size;
4248 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4250 if ( mRelayoutData )
4252 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4254 if( dimension & ( 1 << i ) )
4256 return mRelayoutData->minimumSize[ i ];
4261 return 0.0f; // Default
4264 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4266 EnsureRelayoutData();
4268 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4270 if( dimension & ( 1 << i ) )
4272 mRelayoutData->maximumSize[ i ] = size;
4279 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4281 if ( mRelayoutData )
4283 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4285 if( dimension & ( 1 << i ) )
4287 return mRelayoutData->maximumSize[ i ];
4292 return FLT_MAX; // Default
4295 Object* Actor::GetParentObject() const
4300 } // namespace Internal