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 void Actor::SetOverlay( bool enable )
1500 // Setting STENCIL will override OVERLAY_2D
1501 if( DrawMode::STENCIL != mDrawMode )
1503 SetDrawMode( enable ? DrawMode::OVERLAY_2D : DrawMode::NORMAL );
1507 bool Actor::IsOverlay() const
1509 return ( DrawMode::OVERLAY_2D == mDrawMode );
1512 void Actor::SetDrawMode( DrawMode::Type drawMode )
1514 // this flag is not animatable so keep the value
1515 mDrawMode = drawMode;
1518 // mNode is being used in a separate thread; queue a message to set the value
1519 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1523 DrawMode::Type Actor::GetDrawMode() const
1528 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1530 // only valid when on-stage
1531 StagePtr stage = Stage::GetCurrent();
1532 if( stage && OnStage() )
1534 const RenderTaskList& taskList = stage->GetRenderTaskList();
1536 Vector2 converted( screenX, screenY );
1538 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1539 const int taskCount = taskList.GetTaskCount();
1540 for( int i = taskCount - 1; i >= 0; --i )
1542 Dali::RenderTask task = taskList.GetTask( i );
1543 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1545 // found a task where this conversion was ok so return
1553 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1555 bool retval = false;
1556 // only valid when on-stage
1559 CameraActor* camera = renderTask.GetCameraActor();
1563 renderTask.GetViewport( viewport );
1565 // need to translate coordinates to render tasks coordinate space
1566 Vector2 converted( screenX, screenY );
1567 if( renderTask.TranslateCoordinates( converted ) )
1569 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1576 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1578 // Early-out if mNode is NULL
1584 // Get the ModelView matrix
1586 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1588 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1589 Matrix invertedMvp( false/*don't init*/);
1590 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1591 bool success = invertedMvp.Invert();
1593 // Convert to GL coordinates
1594 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1599 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1606 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1612 if( XyPlaneIntersect( nearPos, farPos, local ) )
1614 Vector3 size = GetCurrentSize();
1615 localX = local.x + size.x * 0.5f;
1616 localY = local.y + size.y * 0.5f;
1627 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1630 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1632 Mathematical Formulation
1634 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1636 ( p - c ) dot ( p - c ) = r^2
1638 Given a ray with a point of origin 'o', and a direction vector 'd':
1640 ray(t) = o + td, t >= 0
1642 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1644 (o + td - c ) dot ( o + td - c ) = r^2
1646 To solve for t we first expand the above into a more recognisable quadratic equation form
1648 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1657 B = 2( o - c ) dot d
1658 C = ( o - c ) dot ( o - c ) - r^2
1660 which can be solved using a standard quadratic formula.
1662 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1664 Practical Simplification
1666 In a renderer, we often differentiate between world space and object space. In the object space
1667 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1668 into object space, the mathematical solution presented above can be simplified significantly.
1670 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1674 and we can find the t at which the (transformed) ray intersects the sphere by
1676 ( o + td ) dot ( o + td ) = r^2
1678 According to the reasoning above, we expand the above quadratic equation into the general form
1682 which now has coefficients:
1689 // Early out if mNode is NULL
1695 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1697 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1698 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1699 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1701 // Compute the radius is not needed, square radius it's enough.
1702 const Vector3& size( mNode->GetSize( bufferIndex ) );
1704 // Scale the sphere.
1705 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1707 const float width = size.width * scale.width;
1708 const float height = size.height * scale.height;
1710 float squareSphereRadius = 0.5f * ( width * width + height * height );
1712 float a = rayDir.Dot( rayDir ); // a
1713 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1714 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1716 return ( b2 * b2 - a * c ) >= 0.f;
1719 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1726 // Transforms the ray to the local reference system.
1727 // Calculate the inverse of Model matrix
1728 Matrix invModelMatrix( false/*don't init*/);
1730 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1731 invModelMatrix = mNode->GetWorldMatrix(0);
1732 invModelMatrix.Invert();
1734 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1735 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1737 // Test with the actor's XY plane (Normal = 0 0 1 1).
1739 float a = -rayOriginLocal.z;
1740 float b = rayDirLocal.z;
1742 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1744 // Ray travels distance * rayDirLocal to intersect with plane.
1747 const Vector3& size = mNode->GetSize( bufferIndex );
1749 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1750 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1752 // Test with the actor's geometry.
1753 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1760 void Actor::SetLeaveRequired( bool required )
1762 mLeaveRequired = required;
1765 bool Actor::GetLeaveRequired() const
1767 return mLeaveRequired;
1770 void Actor::SetKeyboardFocusable( bool focusable )
1772 mKeyboardFocusable = focusable;
1775 bool Actor::IsKeyboardFocusable() const
1777 return mKeyboardFocusable;
1780 bool Actor::GetTouchRequired() const
1782 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1785 bool Actor::GetHoverRequired() const
1787 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1790 bool Actor::GetWheelEventRequired() const
1792 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1795 bool Actor::IsHittable() const
1797 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1800 ActorGestureData& Actor::GetGestureData()
1802 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1803 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1804 if( NULL == mGestureData )
1806 mGestureData = new ActorGestureData;
1808 return *mGestureData;
1811 bool Actor::IsGestureRequred( Gesture::Type type ) const
1813 return mGestureData && mGestureData->IsGestureRequred( type );
1816 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1818 bool consumed = false;
1820 if( !mTouchSignal.Empty() )
1822 Dali::Actor handle( this );
1823 consumed = mTouchSignal.Emit( handle, touch );
1826 if( !mTouchedSignal.Empty() )
1828 Dali::Actor handle( this );
1829 consumed |= mTouchedSignal.Emit( handle, event );
1834 // Notification for derived classes
1835 consumed = OnTouchEvent( event ); // TODO
1841 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1843 bool consumed = false;
1845 if( !mHoveredSignal.Empty() )
1847 Dali::Actor handle( this );
1848 consumed = mHoveredSignal.Emit( handle, event );
1853 // Notification for derived classes
1854 consumed = OnHoverEvent( event );
1860 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1862 bool consumed = false;
1864 if( !mWheelEventSignal.Empty() )
1866 Dali::Actor handle( this );
1867 consumed = mWheelEventSignal.Emit( handle, event );
1872 // Notification for derived classes
1873 consumed = OnWheelEvent( event );
1879 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1881 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1882 return mTouchedSignal;
1885 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1887 return mTouchSignal;
1890 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1892 return mHoveredSignal;
1895 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1897 return mWheelEventSignal;
1900 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1902 return mOnStageSignal;
1905 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1907 return mOffStageSignal;
1910 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1912 return mOnRelayoutSignal;
1915 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1917 bool connected( true );
1918 Actor* actor = dynamic_cast< Actor* >( object );
1920 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1922 actor->TouchedSignal().Connect( tracker, functor );
1924 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1926 actor->HoveredSignal().Connect( tracker, functor );
1928 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1930 actor->WheelEventSignal().Connect( tracker, functor );
1932 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1934 actor->OnStageSignal().Connect( tracker, functor );
1936 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1938 actor->OffStageSignal().Connect( tracker, functor );
1940 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1942 actor->OnRelayoutSignal().Connect( tracker, functor );
1944 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1946 actor->TouchSignal().Connect( tracker, functor );
1950 // signalName does not match any signal
1957 Actor::Actor( DerivedType derivedType )
1962 mParentOrigin( NULL ),
1963 mAnchorPoint( NULL ),
1964 mRelayoutData( NULL ),
1965 mGestureData( NULL ),
1966 mTargetSize( 0.0f, 0.0f, 0.0f ),
1968 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1970 mIsRoot( ROOT_LAYER == derivedType ),
1971 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1972 mIsOnStage( false ),
1974 mLeaveRequired( false ),
1975 mKeyboardFocusable( false ),
1976 mDerivedRequiresTouch( false ),
1977 mDerivedRequiresHover( false ),
1978 mDerivedRequiresWheelEvent( false ),
1979 mOnStageSignalled( false ),
1980 mInsideOnSizeSet( false ),
1981 mInheritPosition( true ),
1982 mInheritOrientation( true ),
1983 mInheritScale( true ),
1984 mDrawMode( DrawMode::NORMAL ),
1985 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1986 mColorMode( Node::DEFAULT_COLOR_MODE )
1990 void Actor::Initialize()
1993 SceneGraph::Node* node = CreateNode();
1995 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
1996 mNode = node; // Keep raw-pointer to Node
2000 GetEventThreadServices().RegisterObject( this );
2005 // Remove mParent pointers from children even if we're destroying core,
2006 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2009 ActorConstIter endIter = mChildren->end();
2010 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2012 (*iter)->SetParent( NULL );
2018 // Guard to allow handle destruction after Core has been destroyed
2019 if( EventThreadServices::IsCoreRunning() )
2023 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2024 mNode = NULL; // Node is about to be destroyed
2027 GetEventThreadServices().UnregisterObject( this );
2030 // Cleanup optional gesture data
2031 delete mGestureData;
2033 // Cleanup optional parent origin and anchor
2034 delete mParentOrigin;
2035 delete mAnchorPoint;
2037 // Delete optional relayout data
2040 delete mRelayoutData;
2044 void Actor::ConnectToStage( unsigned int parentDepth )
2046 // This container is used instead of walking the Actor hierarchy.
2047 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2048 ActorContainer connectionList;
2050 // This stage is atomic i.e. not interrupted by user callbacks.
2051 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2053 // Notify applications about the newly connected actors.
2054 const ActorIter endIter = connectionList.end();
2055 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2057 (*iter)->NotifyStageConnection();
2063 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2065 DALI_ASSERT_ALWAYS( !OnStage() );
2070 ConnectToSceneGraph();
2072 // Notification for internal derived classes
2073 OnStageConnectionInternal();
2075 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2076 connectionList.push_back( ActorPtr( this ) );
2078 // Recursively connect children
2081 ActorConstIter endIter = mChildren->end();
2082 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2084 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2090 * This method is called when the Actor is connected to the Stage.
2091 * The parent must have added its Node to the scene-graph.
2092 * The child must connect its Node to the parent's Node.
2093 * This is recursive; the child calls ConnectToStage() for its children.
2095 void Actor::ConnectToSceneGraph()
2097 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2101 // Reparent Node in next Update
2102 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2105 unsigned int rendererCount( GetRendererCount() );
2106 for( unsigned int i(0); i<rendererCount; ++i )
2108 GetRendererAt(i)->Connect();
2111 // Request relayout on all actors that are added to the scenegraph
2114 // Notification for Object::Observers
2118 void Actor::NotifyStageConnection()
2120 // Actors can be removed (in a callback), before the on-stage stage is reported.
2121 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2122 if( OnStage() && !mOnStageSignalled )
2124 // Notification for external (CustomActor) derived classes
2125 OnStageConnectionExternal( mDepth );
2127 if( !mOnStageSignal.Empty() )
2129 Dali::Actor handle( this );
2130 mOnStageSignal.Emit( handle );
2133 // Guard against Remove during callbacks
2136 mOnStageSignalled = true; // signal required next time Actor is removed
2141 void Actor::DisconnectFromStage()
2143 // This container is used instead of walking the Actor hierachy.
2144 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2145 ActorContainer disconnectionList;
2147 // This stage is atomic i.e. not interrupted by user callbacks
2148 RecursiveDisconnectFromStage( disconnectionList );
2150 // Notify applications about the newly disconnected actors.
2151 const ActorIter endIter = disconnectionList.end();
2152 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2154 (*iter)->NotifyStageDisconnection();
2158 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2160 DALI_ASSERT_ALWAYS( OnStage() );
2162 // Recursively disconnect children
2165 ActorConstIter endIter = mChildren->end();
2166 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2168 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2172 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2173 disconnectionList.push_back( ActorPtr( this ) );
2175 // Notification for internal derived classes
2176 OnStageDisconnectionInternal();
2178 DisconnectFromSceneGraph();
2184 * This method is called by an actor or its parent, before a node removal message is sent.
2185 * This is recursive; the child calls DisconnectFromStage() for its children.
2187 void Actor::DisconnectFromSceneGraph()
2189 // Notification for Object::Observers
2190 OnSceneObjectRemove();
2192 unsigned int rendererCount( GetRendererCount() );
2193 for( unsigned int i(0); i<rendererCount; ++i )
2195 GetRendererAt(i)->Disconnect();
2199 void Actor::NotifyStageDisconnection()
2201 // Actors can be added (in a callback), before the off-stage state is reported.
2202 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2203 // only do this step if there is a stage, i.e. Core is not being shut down
2204 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2206 // Notification for external (CustomeActor) derived classes
2207 OnStageDisconnectionExternal();
2209 if( !mOffStageSignal.Empty() )
2211 Dali::Actor handle( this );
2212 mOffStageSignal.Emit( handle );
2215 // Guard against Add during callbacks
2218 mOnStageSignalled = false; // signal required next time Actor is added
2223 bool Actor::IsNodeConnected() const
2225 bool connected( false );
2227 if( OnStage() && ( NULL != mNode ) )
2229 if( IsRoot() || mNode->GetParent() )
2238 unsigned int Actor::GetDefaultPropertyCount() const
2240 return DEFAULT_PROPERTY_COUNT;
2243 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2245 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2247 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2249 indices.PushBack( i );
2253 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2255 if( index < DEFAULT_PROPERTY_COUNT )
2257 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2263 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2265 Property::Index index = Property::INVALID_INDEX;
2267 // Look for name in default properties
2268 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2270 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2271 if( 0 == name.compare( property->name ) )
2281 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2283 if( index < DEFAULT_PROPERTY_COUNT )
2285 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2291 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2293 if( index < DEFAULT_PROPERTY_COUNT )
2295 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2301 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2303 if( index < DEFAULT_PROPERTY_COUNT )
2305 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2311 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2313 if( index < DEFAULT_PROPERTY_COUNT )
2315 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2318 // index out of range...return Property::NONE
2319 return Property::NONE;
2322 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2326 case Dali::Actor::Property::PARENT_ORIGIN:
2328 Property::Type type = property.GetType();
2329 if( type == Property::VECTOR3 )
2331 SetParentOrigin( property.Get< Vector3 >() );
2333 else if ( type == Property::STRING )
2335 std::string parentOriginString;
2336 property.Get( parentOriginString );
2337 Vector3 parentOrigin;
2338 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2340 SetParentOrigin( parentOrigin );
2346 case Dali::Actor::Property::PARENT_ORIGIN_X:
2348 SetParentOriginX( property.Get< float >() );
2352 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2354 SetParentOriginY( property.Get< float >() );
2358 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2360 SetParentOriginZ( property.Get< float >() );
2364 case Dali::Actor::Property::ANCHOR_POINT:
2366 Property::Type type = property.GetType();
2367 if( type == Property::VECTOR3 )
2369 SetAnchorPoint( property.Get< Vector3 >() );
2371 else if ( type == Property::STRING )
2373 std::string anchorPointString;
2374 property.Get( anchorPointString );
2376 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2378 SetAnchorPoint( anchor );
2384 case Dali::Actor::Property::ANCHOR_POINT_X:
2386 SetAnchorPointX( property.Get< float >() );
2390 case Dali::Actor::Property::ANCHOR_POINT_Y:
2392 SetAnchorPointY( property.Get< float >() );
2396 case Dali::Actor::Property::ANCHOR_POINT_Z:
2398 SetAnchorPointZ( property.Get< float >() );
2402 case Dali::Actor::Property::SIZE:
2404 SetSize( property.Get< Vector3 >() );
2408 case Dali::Actor::Property::SIZE_WIDTH:
2410 SetWidth( property.Get< float >() );
2414 case Dali::Actor::Property::SIZE_HEIGHT:
2416 SetHeight( property.Get< float >() );
2420 case Dali::Actor::Property::SIZE_DEPTH:
2422 SetDepth( property.Get< float >() );
2426 case Dali::Actor::Property::POSITION:
2428 SetPosition( property.Get< Vector3 >() );
2432 case Dali::Actor::Property::POSITION_X:
2434 SetX( property.Get< float >() );
2438 case Dali::Actor::Property::POSITION_Y:
2440 SetY( property.Get< float >() );
2444 case Dali::Actor::Property::POSITION_Z:
2446 SetZ( property.Get< float >() );
2450 case Dali::Actor::Property::ORIENTATION:
2452 SetOrientation( property.Get< Quaternion >() );
2456 case Dali::Actor::Property::SCALE:
2458 SetScale( property.Get< Vector3 >() );
2462 case Dali::Actor::Property::SCALE_X:
2464 SetScaleX( property.Get< float >() );
2468 case Dali::Actor::Property::SCALE_Y:
2470 SetScaleY( property.Get< float >() );
2474 case Dali::Actor::Property::SCALE_Z:
2476 SetScaleZ( property.Get< float >() );
2480 case Dali::Actor::Property::VISIBLE:
2482 SetVisible( property.Get< bool >() );
2486 case Dali::Actor::Property::COLOR:
2488 SetColor( property.Get< Vector4 >() );
2492 case Dali::Actor::Property::COLOR_RED:
2494 SetColorRed( property.Get< float >() );
2498 case Dali::Actor::Property::COLOR_GREEN:
2500 SetColorGreen( property.Get< float >() );
2504 case Dali::Actor::Property::COLOR_BLUE:
2506 SetColorBlue( property.Get< float >() );
2510 case Dali::Actor::Property::COLOR_ALPHA:
2512 SetOpacity( property.Get< float >() );
2516 case Dali::Actor::Property::NAME:
2518 SetName( property.Get< std::string >() );
2522 case Dali::Actor::Property::SENSITIVE:
2524 SetSensitive( property.Get< bool >() );
2528 case Dali::Actor::Property::LEAVE_REQUIRED:
2530 SetLeaveRequired( property.Get< bool >() );
2534 case Dali::Actor::Property::INHERIT_POSITION:
2536 SetInheritPosition( property.Get< bool >() );
2540 case Dali::Actor::Property::INHERIT_ORIENTATION:
2542 SetInheritOrientation( property.Get< bool >() );
2546 case Dali::Actor::Property::INHERIT_SCALE:
2548 SetInheritScale( property.Get< bool >() );
2552 case Dali::Actor::Property::COLOR_MODE:
2555 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2557 SetColorMode( mode );
2562 case Dali::Actor::Property::POSITION_INHERITANCE:
2564 PositionInheritanceMode mode;
2565 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2567 SetPositionInheritanceMode( mode );
2572 case Dali::Actor::Property::DRAW_MODE:
2574 DrawMode::Type mode;
2575 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2577 SetDrawMode( mode );
2582 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2584 SetSizeModeFactor( property.Get< Vector3 >() );
2588 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2590 ResizePolicy::Type type;
2591 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2593 SetResizePolicy( type, Dimension::WIDTH );
2598 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2600 ResizePolicy::Type type;
2601 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2603 SetResizePolicy( type, Dimension::HEIGHT );
2608 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2610 SizeScalePolicy::Type type;
2611 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2613 SetSizeScalePolicy( type );
2618 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2620 if( property.Get< bool >() )
2622 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2627 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2629 if( property.Get< bool >() )
2631 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2636 case Dali::Actor::Property::PADDING:
2638 Vector4 padding = property.Get< Vector4 >();
2639 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2640 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2644 case Dali::Actor::Property::MINIMUM_SIZE:
2646 Vector2 size = property.Get< Vector2 >();
2647 SetMinimumSize( size.x, Dimension::WIDTH );
2648 SetMinimumSize( size.y, Dimension::HEIGHT );
2652 case Dali::Actor::Property::MAXIMUM_SIZE:
2654 Vector2 size = property.Get< Vector2 >();
2655 SetMaximumSize( size.x, Dimension::WIDTH );
2656 SetMaximumSize( size.y, Dimension::HEIGHT );
2662 // this can happen in the case of a non-animatable default property so just do nothing
2668 // TODO: This method needs to be removed
2669 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2671 switch( entry.GetType() )
2673 case Property::BOOLEAN:
2675 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2676 DALI_ASSERT_DEBUG( NULL != property );
2678 // property is being used in a separate thread; queue a message to set the property
2679 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2684 case Property::INTEGER:
2686 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2687 DALI_ASSERT_DEBUG( NULL != property );
2689 // property is being used in a separate thread; queue a message to set the property
2690 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2695 case Property::FLOAT:
2697 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2698 DALI_ASSERT_DEBUG( NULL != property );
2700 // property is being used in a separate thread; queue a message to set the property
2701 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2706 case Property::VECTOR2:
2708 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2709 DALI_ASSERT_DEBUG( NULL != property );
2711 // property is being used in a separate thread; queue a message to set the property
2712 if(entry.componentIndex == 0)
2714 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2716 else if(entry.componentIndex == 1)
2718 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2722 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2728 case Property::VECTOR3:
2730 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2731 DALI_ASSERT_DEBUG( NULL != property );
2733 // property is being used in a separate thread; queue a message to set the property
2734 if(entry.componentIndex == 0)
2736 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2738 else if(entry.componentIndex == 1)
2740 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2742 else if(entry.componentIndex == 2)
2744 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2748 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2754 case Property::VECTOR4:
2756 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2757 DALI_ASSERT_DEBUG( NULL != property );
2759 // property is being used in a separate thread; queue a message to set the property
2760 if(entry.componentIndex == 0)
2762 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2764 else if(entry.componentIndex == 1)
2766 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2768 else if(entry.componentIndex == 2)
2770 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2772 else if(entry.componentIndex == 3)
2774 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2778 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2784 case Property::ROTATION:
2786 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2787 DALI_ASSERT_DEBUG( NULL != property );
2789 // property is being used in a separate thread; queue a message to set the property
2790 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2795 case Property::MATRIX:
2797 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2798 DALI_ASSERT_DEBUG( NULL != property );
2800 // property is being used in a separate thread; queue a message to set the property
2801 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2806 case Property::MATRIX3:
2808 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2809 DALI_ASSERT_DEBUG( NULL != property );
2811 // property is being used in a separate thread; queue a message to set the property
2812 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2819 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2825 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2827 Property::Value value;
2831 case Dali::Actor::Property::PARENT_ORIGIN:
2833 value = GetCurrentParentOrigin();
2837 case Dali::Actor::Property::PARENT_ORIGIN_X:
2839 value = GetCurrentParentOrigin().x;
2843 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2845 value = GetCurrentParentOrigin().y;
2849 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2851 value = GetCurrentParentOrigin().z;
2855 case Dali::Actor::Property::ANCHOR_POINT:
2857 value = GetCurrentAnchorPoint();
2861 case Dali::Actor::Property::ANCHOR_POINT_X:
2863 value = GetCurrentAnchorPoint().x;
2867 case Dali::Actor::Property::ANCHOR_POINT_Y:
2869 value = GetCurrentAnchorPoint().y;
2873 case Dali::Actor::Property::ANCHOR_POINT_Z:
2875 value = GetCurrentAnchorPoint().z;
2879 case Dali::Actor::Property::SIZE:
2881 value = GetTargetSize();
2885 case Dali::Actor::Property::SIZE_WIDTH:
2887 value = GetTargetSize().width;
2891 case Dali::Actor::Property::SIZE_HEIGHT:
2893 value = GetTargetSize().height;
2897 case Dali::Actor::Property::SIZE_DEPTH:
2899 value = GetTargetSize().depth;
2903 case Dali::Actor::Property::POSITION:
2905 value = GetTargetPosition();
2909 case Dali::Actor::Property::POSITION_X:
2911 value = GetTargetPosition().x;
2915 case Dali::Actor::Property::POSITION_Y:
2917 value = GetTargetPosition().y;
2921 case Dali::Actor::Property::POSITION_Z:
2923 value = GetTargetPosition().z;
2927 case Dali::Actor::Property::WORLD_POSITION:
2929 value = GetCurrentWorldPosition();
2933 case Dali::Actor::Property::WORLD_POSITION_X:
2935 value = GetCurrentWorldPosition().x;
2939 case Dali::Actor::Property::WORLD_POSITION_Y:
2941 value = GetCurrentWorldPosition().y;
2945 case Dali::Actor::Property::WORLD_POSITION_Z:
2947 value = GetCurrentWorldPosition().z;
2951 case Dali::Actor::Property::ORIENTATION:
2953 value = GetCurrentOrientation();
2957 case Dali::Actor::Property::WORLD_ORIENTATION:
2959 value = GetCurrentWorldOrientation();
2963 case Dali::Actor::Property::SCALE:
2965 value = GetCurrentScale();
2969 case Dali::Actor::Property::SCALE_X:
2971 value = GetCurrentScale().x;
2975 case Dali::Actor::Property::SCALE_Y:
2977 value = GetCurrentScale().y;
2981 case Dali::Actor::Property::SCALE_Z:
2983 value = GetCurrentScale().z;
2987 case Dali::Actor::Property::WORLD_SCALE:
2989 value = GetCurrentWorldScale();
2993 case Dali::Actor::Property::VISIBLE:
2995 value = IsVisible();
2999 case Dali::Actor::Property::COLOR:
3001 value = GetCurrentColor();
3005 case Dali::Actor::Property::COLOR_RED:
3007 value = GetCurrentColor().r;
3011 case Dali::Actor::Property::COLOR_GREEN:
3013 value = GetCurrentColor().g;
3017 case Dali::Actor::Property::COLOR_BLUE:
3019 value = GetCurrentColor().b;
3023 case Dali::Actor::Property::COLOR_ALPHA:
3025 value = GetCurrentColor().a;
3029 case Dali::Actor::Property::WORLD_COLOR:
3031 value = GetCurrentWorldColor();
3035 case Dali::Actor::Property::WORLD_MATRIX:
3037 value = GetCurrentWorldMatrix();
3041 case Dali::Actor::Property::NAME:
3047 case Dali::Actor::Property::SENSITIVE:
3049 value = IsSensitive();
3053 case Dali::Actor::Property::LEAVE_REQUIRED:
3055 value = GetLeaveRequired();
3059 case Dali::Actor::Property::INHERIT_POSITION:
3061 value = IsPositionInherited();
3065 case Dali::Actor::Property::INHERIT_ORIENTATION:
3067 value = IsOrientationInherited();
3071 case Dali::Actor::Property::INHERIT_SCALE:
3073 value = IsScaleInherited();
3077 case Dali::Actor::Property::COLOR_MODE:
3079 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3083 case Dali::Actor::Property::POSITION_INHERITANCE:
3085 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3089 case Dali::Actor::Property::DRAW_MODE:
3091 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3095 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3097 value = GetSizeModeFactor();
3101 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3103 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3107 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3109 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3113 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3115 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3119 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3121 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3125 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3127 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3131 case Dali::Actor::Property::PADDING:
3133 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3134 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3135 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3139 case Dali::Actor::Property::MINIMUM_SIZE:
3141 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3145 case Dali::Actor::Property::MAXIMUM_SIZE:
3147 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3153 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3161 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3166 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3168 // This method should only return an object connected to the scene-graph
3169 return OnStage() ? mNode : NULL;
3172 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3174 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3176 const PropertyBase* property( NULL );
3178 // This method should only return a property of an object connected to the scene-graph
3184 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3186 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3187 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3189 property = animatable->GetSceneGraphProperty();
3191 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3193 CustomPropertyMetadata* custom = FindCustomProperty( index );
3194 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3196 property = custom->GetSceneGraphProperty();
3198 else if( NULL != mNode )
3202 case Dali::Actor::Property::SIZE:
3203 property = &mNode->mSize;
3206 case Dali::Actor::Property::SIZE_WIDTH:
3207 property = &mNode->mSize;
3210 case Dali::Actor::Property::SIZE_HEIGHT:
3211 property = &mNode->mSize;
3214 case Dali::Actor::Property::SIZE_DEPTH:
3215 property = &mNode->mSize;
3218 case Dali::Actor::Property::POSITION:
3219 property = &mNode->mPosition;
3222 case Dali::Actor::Property::POSITION_X:
3223 property = &mNode->mPosition;
3226 case Dali::Actor::Property::POSITION_Y:
3227 property = &mNode->mPosition;
3230 case Dali::Actor::Property::POSITION_Z:
3231 property = &mNode->mPosition;
3234 case Dali::Actor::Property::ORIENTATION:
3235 property = &mNode->mOrientation;
3238 case Dali::Actor::Property::SCALE:
3239 property = &mNode->mScale;
3242 case Dali::Actor::Property::SCALE_X:
3243 property = &mNode->mScale;
3246 case Dali::Actor::Property::SCALE_Y:
3247 property = &mNode->mScale;
3250 case Dali::Actor::Property::SCALE_Z:
3251 property = &mNode->mScale;
3254 case Dali::Actor::Property::VISIBLE:
3255 property = &mNode->mVisible;
3258 case Dali::Actor::Property::COLOR:
3259 property = &mNode->mColor;
3262 case Dali::Actor::Property::COLOR_RED:
3263 property = &mNode->mColor;
3266 case Dali::Actor::Property::COLOR_GREEN:
3267 property = &mNode->mColor;
3270 case Dali::Actor::Property::COLOR_BLUE:
3271 property = &mNode->mColor;
3274 case Dali::Actor::Property::COLOR_ALPHA:
3275 property = &mNode->mColor;
3286 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3288 const PropertyInputImpl* property( NULL );
3290 // This method should only return a property of an object connected to the scene-graph
3296 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3298 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3299 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3301 property = animatable->GetSceneGraphProperty();
3303 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3305 CustomPropertyMetadata* custom = FindCustomProperty( index );
3306 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3307 property = custom->GetSceneGraphProperty();
3309 else if( NULL != mNode )
3313 case Dali::Actor::Property::PARENT_ORIGIN:
3314 property = &mNode->mParentOrigin;
3317 case Dali::Actor::Property::PARENT_ORIGIN_X:
3318 property = &mNode->mParentOrigin;
3321 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3322 property = &mNode->mParentOrigin;
3325 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3326 property = &mNode->mParentOrigin;
3329 case Dali::Actor::Property::ANCHOR_POINT:
3330 property = &mNode->mAnchorPoint;
3333 case Dali::Actor::Property::ANCHOR_POINT_X:
3334 property = &mNode->mAnchorPoint;
3337 case Dali::Actor::Property::ANCHOR_POINT_Y:
3338 property = &mNode->mAnchorPoint;
3341 case Dali::Actor::Property::ANCHOR_POINT_Z:
3342 property = &mNode->mAnchorPoint;
3345 case Dali::Actor::Property::SIZE:
3346 property = &mNode->mSize;
3349 case Dali::Actor::Property::SIZE_WIDTH:
3350 property = &mNode->mSize;
3353 case Dali::Actor::Property::SIZE_HEIGHT:
3354 property = &mNode->mSize;
3357 case Dali::Actor::Property::SIZE_DEPTH:
3358 property = &mNode->mSize;
3361 case Dali::Actor::Property::POSITION:
3362 property = &mNode->mPosition;
3365 case Dali::Actor::Property::POSITION_X:
3366 property = &mNode->mPosition;
3369 case Dali::Actor::Property::POSITION_Y:
3370 property = &mNode->mPosition;
3373 case Dali::Actor::Property::POSITION_Z:
3374 property = &mNode->mPosition;
3377 case Dali::Actor::Property::WORLD_POSITION:
3378 property = &mNode->mWorldPosition;
3381 case Dali::Actor::Property::WORLD_POSITION_X:
3382 property = &mNode->mWorldPosition;
3385 case Dali::Actor::Property::WORLD_POSITION_Y:
3386 property = &mNode->mWorldPosition;
3389 case Dali::Actor::Property::WORLD_POSITION_Z:
3390 property = &mNode->mWorldPosition;
3393 case Dali::Actor::Property::ORIENTATION:
3394 property = &mNode->mOrientation;
3397 case Dali::Actor::Property::WORLD_ORIENTATION:
3398 property = &mNode->mWorldOrientation;
3401 case Dali::Actor::Property::SCALE:
3402 property = &mNode->mScale;
3405 case Dali::Actor::Property::SCALE_X:
3406 property = &mNode->mScale;
3409 case Dali::Actor::Property::SCALE_Y:
3410 property = &mNode->mScale;
3413 case Dali::Actor::Property::SCALE_Z:
3414 property = &mNode->mScale;
3417 case Dali::Actor::Property::WORLD_SCALE:
3418 property = &mNode->mWorldScale;
3421 case Dali::Actor::Property::VISIBLE:
3422 property = &mNode->mVisible;
3425 case Dali::Actor::Property::COLOR:
3426 property = &mNode->mColor;
3429 case Dali::Actor::Property::COLOR_RED:
3430 property = &mNode->mColor;
3433 case Dali::Actor::Property::COLOR_GREEN:
3434 property = &mNode->mColor;
3437 case Dali::Actor::Property::COLOR_BLUE:
3438 property = &mNode->mColor;
3441 case Dali::Actor::Property::COLOR_ALPHA:
3442 property = &mNode->mColor;
3445 case Dali::Actor::Property::WORLD_COLOR:
3446 property = &mNode->mWorldColor;
3449 case Dali::Actor::Property::WORLD_MATRIX:
3450 property = &mNode->mWorldMatrix;
3461 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3463 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3465 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3467 // check whether the animatable property is registered already, if not then register one.
3468 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3469 if( animatableProperty )
3471 componentIndex = animatableProperty->componentIndex;
3478 case Dali::Actor::Property::PARENT_ORIGIN_X:
3479 case Dali::Actor::Property::ANCHOR_POINT_X:
3480 case Dali::Actor::Property::SIZE_WIDTH:
3481 case Dali::Actor::Property::POSITION_X:
3482 case Dali::Actor::Property::WORLD_POSITION_X:
3483 case Dali::Actor::Property::SCALE_X:
3484 case Dali::Actor::Property::COLOR_RED:
3490 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3491 case Dali::Actor::Property::ANCHOR_POINT_Y:
3492 case Dali::Actor::Property::SIZE_HEIGHT:
3493 case Dali::Actor::Property::POSITION_Y:
3494 case Dali::Actor::Property::WORLD_POSITION_Y:
3495 case Dali::Actor::Property::SCALE_Y:
3496 case Dali::Actor::Property::COLOR_GREEN:
3502 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3503 case Dali::Actor::Property::ANCHOR_POINT_Z:
3504 case Dali::Actor::Property::SIZE_DEPTH:
3505 case Dali::Actor::Property::POSITION_Z:
3506 case Dali::Actor::Property::WORLD_POSITION_Z:
3507 case Dali::Actor::Property::SCALE_Z:
3508 case Dali::Actor::Property::COLOR_BLUE:
3514 case Dali::Actor::Property::COLOR_ALPHA:
3528 return componentIndex;
3531 void Actor::SetParent( Actor* parent )
3535 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3539 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3542 // Instruct each actor to create a corresponding node in the scene graph
3543 ConnectToStage( parent->GetHierarchyDepth() );
3546 // Resolve the name and index for the child properties if any
3547 ResolveChildProperties();
3549 else // parent being set to NULL
3551 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3555 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3558 DALI_ASSERT_ALWAYS( mNode != NULL );
3562 // Disconnect the Node & its children from the scene-graph.
3563 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3566 // Instruct each actor to discard pointers to the scene-graph
3567 DisconnectFromStage();
3572 SceneGraph::Node* Actor::CreateNode() const
3577 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3580 Actor* actor = dynamic_cast< Actor* >( object );
3584 if( 0 == actionName.compare( ACTION_SHOW ) )
3586 actor->SetVisible( true );
3589 else if( 0 == actionName.compare( ACTION_HIDE ) )
3591 actor->SetVisible( false );
3599 void Actor::EnsureRelayoutData()
3601 // Assign relayout data.
3602 if( !mRelayoutData )
3604 mRelayoutData = new RelayoutData();
3608 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3610 // Check if actor is dependent on parent
3611 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3613 if( ( dimension & ( 1 << i ) ) )
3615 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3616 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3626 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3628 // Check if actor is dependent on children
3629 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3631 if( ( dimension & ( 1 << i ) ) )
3633 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3634 switch( resizePolicy )
3636 case ResizePolicy::FIT_TO_CHILDREN:
3637 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3653 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3655 return Actor::RelayoutDependentOnChildren( dimension );
3658 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3660 // Check each possible dimension and see if it is dependent on the input one
3661 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3663 if( dimension & ( 1 << i ) )
3665 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3672 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3674 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3676 if( dimension & ( 1 << i ) )
3678 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3683 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3685 // If more than one dimension is requested, just return the first one found
3686 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3688 if( ( dimension & ( 1 << i ) ) )
3690 return mRelayoutData->negotiatedDimensions[ i ];
3694 return 0.0f; // Default
3697 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3699 EnsureRelayoutData();
3701 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3703 if( dimension & ( 1 << i ) )
3705 mRelayoutData->dimensionPadding[ i ] = padding;
3710 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3712 if ( mRelayoutData )
3714 // If more than one dimension is requested, just return the first one found
3715 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3717 if( ( dimension & ( 1 << i ) ) )
3719 return mRelayoutData->dimensionPadding[ i ];
3724 return GetDefaultDimensionPadding();
3727 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3729 EnsureRelayoutData();
3731 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3733 if( dimension & ( 1 << i ) )
3735 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3740 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3742 if ( mRelayoutData )
3744 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3746 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3756 float Actor::GetHeightForWidthBase( float width )
3758 float height = 0.0f;
3760 const Vector3 naturalSize = GetNaturalSize();
3761 if( naturalSize.width > 0.0f )
3763 height = naturalSize.height * width / naturalSize.width;
3765 else // we treat 0 as 1:1 aspect ratio
3773 float Actor::GetWidthForHeightBase( float height )
3777 const Vector3 naturalSize = GetNaturalSize();
3778 if( naturalSize.height > 0.0f )
3780 width = naturalSize.width * height / naturalSize.height;
3782 else // we treat 0 as 1:1 aspect ratio
3790 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3792 // Fill to parent, taking size mode factor into account
3793 switch( child.GetResizePolicy( dimension ) )
3795 case ResizePolicy::FILL_TO_PARENT:
3797 return GetLatestSize( dimension );
3800 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3802 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3805 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3807 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3812 return GetLatestSize( dimension );
3817 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3819 // Can be overridden in derived class
3820 return CalculateChildSizeBase( child, dimension );
3823 float Actor::GetHeightForWidth( float width )
3825 // Can be overridden in derived class
3826 return GetHeightForWidthBase( width );
3829 float Actor::GetWidthForHeight( float height )
3831 // Can be overridden in derived class
3832 return GetWidthForHeightBase( height );
3835 float Actor::GetLatestSize( Dimension::Type dimension ) const
3837 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3840 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3842 Vector2 padding = GetPadding( dimension );
3844 return GetLatestSize( dimension ) + padding.x + padding.y;
3847 float Actor::NegotiateFromParent( Dimension::Type dimension )
3849 Actor* parent = GetParent();
3852 Vector2 padding( GetPadding( dimension ) );
3853 Vector2 parentPadding( parent->GetPadding( dimension ) );
3854 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3860 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3862 float maxDimensionPoint = 0.0f;
3864 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3866 ActorPtr child = GetChildAt( i );
3868 if( !child->RelayoutDependentOnParent( dimension ) )
3870 // Calculate the min and max points that the children range across
3871 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3872 float dimensionSize = child->GetRelayoutSize( dimension );
3873 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3877 return maxDimensionPoint;
3880 float Actor::GetSize( Dimension::Type dimension ) const
3882 return GetDimensionValue( GetTargetSize(), dimension );
3885 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3887 return GetDimensionValue( GetNaturalSize(), dimension );
3890 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3892 switch( GetResizePolicy( dimension ) )
3894 case ResizePolicy::USE_NATURAL_SIZE:
3896 return GetNaturalSize( dimension );
3899 case ResizePolicy::FIXED:
3901 return GetDimensionValue( GetPreferredSize(), dimension );
3904 case ResizePolicy::USE_ASSIGNED_SIZE:
3906 return GetDimensionValue( maximumSize, dimension );
3909 case ResizePolicy::FILL_TO_PARENT:
3910 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3911 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3913 return NegotiateFromParent( dimension );
3916 case ResizePolicy::FIT_TO_CHILDREN:
3918 return NegotiateFromChildren( dimension );
3921 case ResizePolicy::DIMENSION_DEPENDENCY:
3923 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3926 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3928 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3931 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3933 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3945 return 0.0f; // Default
3948 float Actor::ClampDimension( float size, Dimension::Type dimension )
3950 const float minSize = GetMinimumSize( dimension );
3951 const float maxSize = GetMaximumSize( dimension );
3953 return std::max( minSize, std::min( size, maxSize ) );
3956 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
3958 // Check if it needs to be negotiated
3959 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
3961 // Check that we havn't gotten into an infinite loop
3962 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
3963 bool recursionFound = false;
3964 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
3966 if( *it == searchActor )
3968 recursionFound = true;
3973 if( !recursionFound )
3975 // Record the path that we have taken
3976 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
3978 // Dimension dependency check
3979 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3981 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
3983 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
3985 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
3989 // Parent dependency check
3990 Actor* parent = GetParent();
3991 if( parent && RelayoutDependentOnParent( dimension ) )
3993 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
3996 // Children dependency check
3997 if( RelayoutDependentOnChildren( dimension ) )
3999 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4001 ActorPtr child = GetChildAt( i );
4003 // Only relayout child first if it is not dependent on this actor
4004 if( !child->RelayoutDependentOnParent( dimension ) )
4006 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4011 // For deriving classes
4012 OnCalculateRelayoutSize( dimension );
4014 // All dependencies checked, calculate the size and set negotiated flag
4015 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4017 SetNegotiatedDimension( newSize, dimension );
4018 SetLayoutNegotiated( true, dimension );
4020 // For deriving classes
4021 OnLayoutNegotiated( newSize, dimension );
4023 // This actor has been successfully processed, pop it off the recursion stack
4024 recursionStack.pop_back();
4028 // TODO: Break infinite loop
4029 SetLayoutNegotiated( true, dimension );
4034 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4036 // Negotiate all dimensions that require it
4037 ActorDimensionStack recursionStack;
4039 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4041 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4044 NegotiateDimension( dimension, allocatedSize, recursionStack );
4048 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4050 switch( mRelayoutData->sizeSetPolicy )
4052 case SizeScalePolicy::USE_SIZE_SET:
4057 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4059 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4060 const Vector3 naturalSize = GetNaturalSize();
4061 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4063 const float sizeRatio = size.width / size.height;
4064 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4066 if( naturalSizeRatio < sizeRatio )
4068 return Vector2( naturalSizeRatio * size.height, size.height );
4070 else if( naturalSizeRatio > sizeRatio )
4072 return Vector2( size.width, size.width / naturalSizeRatio );
4083 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4085 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4086 const Vector3 naturalSize = GetNaturalSize();
4087 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4089 const float sizeRatio = size.width / size.height;
4090 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4092 if( naturalSizeRatio < sizeRatio )
4094 return Vector2( size.width, size.width / naturalSizeRatio );
4096 else if( naturalSizeRatio > sizeRatio )
4098 return Vector2( naturalSizeRatio * size.height, size.height );
4117 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4119 // Do the set actor size
4120 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4122 // Adjust for size set policy
4123 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4125 // Lock the flag to stop recursive relayouts on set size
4126 mRelayoutData->insideRelayout = true;
4127 SetSize( negotiatedSize );
4128 mRelayoutData->insideRelayout = false;
4130 // Clear flags for all dimensions
4131 SetLayoutDirty( false );
4133 // Give deriving classes a chance to respond
4134 OnRelayout( negotiatedSize, container );
4136 if( !mOnRelayoutSignal.Empty() )
4138 Dali::Actor handle( this );
4139 mOnRelayoutSignal.Emit( handle );
4143 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4145 // Force a size negotiation for actors that has assigned size during relayout
4146 // This is required as otherwise the flags that force a relayout will not
4147 // necessarilly be set. This will occur if the actor has already been laid out.
4148 // The dirty flags are then cleared. Then if the actor is added back into the
4149 // relayout container afterwards, the dirty flags would still be clear...
4150 // causing a relayout to be skipped. Here we force any actors added to the
4151 // container to be relayed out.
4152 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4154 SetLayoutNegotiated(false, Dimension::WIDTH);
4156 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4158 SetLayoutNegotiated(false, Dimension::HEIGHT);
4161 // Do the negotiation
4162 NegotiateDimensions( allocatedSize );
4164 // Set the actor size
4165 SetNegotiatedSize( container );
4167 // Negotiate down to children
4168 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4170 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4172 ActorPtr child = GetChildAt( i );
4174 // Forces children that have already been laid out to be relayed out
4175 // if they have assigned size during relayout.
4176 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4178 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4179 child->SetLayoutDirty(true, Dimension::WIDTH);
4181 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4183 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4184 child->SetLayoutDirty(true, Dimension::HEIGHT);
4187 // Only relayout if required
4188 if( child->RelayoutRequired() )
4190 container.Add( Dali::Actor( child.Get() ), newBounds );
4195 void Actor::RelayoutRequest( Dimension::Type dimension )
4197 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4198 if( relayoutController )
4200 Dali::Actor self( this );
4201 relayoutController->RequestRelayout( self, dimension );
4205 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4209 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4213 void Actor::SetPreferredSize( const Vector2& size )
4215 EnsureRelayoutData();
4217 if( size.width > 0.0f )
4219 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4222 if( size.height > 0.0f )
4224 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4227 mRelayoutData->preferredSize = size;
4232 Vector2 Actor::GetPreferredSize() const
4234 if ( mRelayoutData )
4236 return Vector2( mRelayoutData->preferredSize );
4239 return GetDefaultPreferredSize();
4242 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4244 EnsureRelayoutData();
4246 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4248 if( dimension & ( 1 << i ) )
4250 mRelayoutData->minimumSize[ i ] = size;
4257 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4259 if ( mRelayoutData )
4261 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4263 if( dimension & ( 1 << i ) )
4265 return mRelayoutData->minimumSize[ i ];
4270 return 0.0f; // Default
4273 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4275 EnsureRelayoutData();
4277 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4279 if( dimension & ( 1 << i ) )
4281 mRelayoutData->maximumSize[ i ] = size;
4288 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4290 if ( mRelayoutData )
4292 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4294 if( dimension & ( 1 << i ) )
4296 return mRelayoutData->maximumSize[ i ];
4301 return FLT_MAX; // Default
4304 Object* Actor::GetParentObject() const
4309 } // namespace Internal