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";
216 const char* const ACTION_SHOW = "show";
217 const char* const ACTION_HIDE = "hide";
219 BaseHandle CreateActor()
221 return Dali::Actor::New();
224 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
226 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
227 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
228 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
229 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
233 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
234 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
239 const Vector3& value;
242 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
243 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
244 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
245 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
246 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
252 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
254 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
255 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
256 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
257 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
258 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
259 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
261 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
262 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
263 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
264 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
265 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
266 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
268 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
269 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
270 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
272 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
274 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
276 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
283 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
285 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
287 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
288 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
289 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
291 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
293 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
295 size_t sizeIgnored = 0;
296 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
298 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
305 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
307 // Values are the same so just use the same table as anchor-point
308 return GetAnchorPointConstant( value, parentOrigin );
312 * @brief Extract a given dimension from a Vector2
314 * @param[in] values The values to extract from
315 * @param[in] dimension The dimension to extract
316 * @return Return the value for the dimension
318 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
322 case Dimension::WIDTH:
326 case Dimension::HEIGHT:
328 return values.height;
339 * @brief Extract a given dimension from a Vector3
341 * @param[in] values The values to extract from
342 * @param[in] dimension The dimension to extract
343 * @return Return the value for the dimension
345 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
347 return GetDimensionValue( values.GetVectorXY(), dimension );
351 } // unnamed namespace
353 ActorPtr Actor::New()
355 ActorPtr actor( new Actor( BASIC ) );
357 // Second-phase construction
363 const std::string& Actor::GetName() const
368 void Actor::SetName( const std::string& name )
374 // ATTENTION: string for debug purposes is not thread safe.
375 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
379 unsigned int Actor::GetId() const
384 bool Actor::OnStage() const
389 Dali::Layer Actor::GetLayer()
393 // Short-circuit for Layer derived actors
396 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
399 // Find the immediate Layer parent
400 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
402 if( parent->IsLayer() )
404 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
411 void Actor::Add( Actor& child )
413 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
414 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
418 mChildren = new ActorContainer;
421 Actor* const oldParent( child.mParent );
423 // child might already be ours
424 if( this != oldParent )
426 // if we already have parent, unparent us first
429 oldParent->Remove( child ); // This causes OnChildRemove callback
431 // Old parent may need to readjust to missing child
432 if( oldParent->RelayoutDependentOnChildren() )
434 oldParent->RelayoutRequest();
438 // Guard against Add() during previous OnChildRemove callback
441 // Do this first, since user callbacks from within SetParent() may need to remove child
442 mChildren->push_back( ActorPtr( &child ) );
444 // SetParent asserts that child can be added
445 child.SetParent( this );
447 // Notification for derived classes
450 // Only put in a relayout request if there is a suitable dependency
451 if( RelayoutDependentOnChildren() )
459 void Actor::Remove( Actor& child )
461 if( (this == &child) || (!mChildren) )
463 // no children or removing itself
469 // Find the child in mChildren, and unparent it
470 ActorIter end = mChildren->end();
471 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
473 ActorPtr actor = (*iter);
475 if( actor.Get() == &child )
477 // Keep handle for OnChildRemove notification
480 // Do this first, since user callbacks from within SetParent() may need to add the child
481 mChildren->erase( iter );
483 DALI_ASSERT_DEBUG( actor->GetParent() == this );
484 actor->SetParent( NULL );
492 // Only put in a relayout request if there is a suitable dependency
493 if( RelayoutDependentOnChildren() )
499 // Notification for derived classes
500 OnChildRemove( child );
503 void Actor::Unparent()
507 // Remove this actor from the parent. The remove will put a relayout request in for
508 // the parent if required
509 mParent->Remove( *this );
510 // mParent is now NULL!
514 unsigned int Actor::GetChildCount() const
516 return ( NULL != mChildren ) ? mChildren->size() : 0;
519 ActorPtr Actor::GetChildAt( unsigned int index ) const
521 DALI_ASSERT_ALWAYS( index < GetChildCount() );
523 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
526 ActorPtr Actor::FindChildByName( const std::string& actorName )
529 if( actorName == mName )
535 ActorIter end = mChildren->end();
536 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
538 child = (*iter)->FindChildByName( actorName );
549 ActorPtr Actor::FindChildById( const unsigned int id )
558 ActorIter end = mChildren->end();
559 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
561 child = (*iter)->FindChildById( id );
572 void Actor::SetParentOrigin( const Vector3& origin )
576 // mNode is being used in a separate thread; queue a message to set the value & base value
577 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
580 // Cache for event-thread access
583 // not allocated, check if different from default
584 if( ParentOrigin::DEFAULT != origin )
586 mParentOrigin = new Vector3( origin );
591 // check if different from current costs more than just set
592 *mParentOrigin = origin;
596 void Actor::SetParentOriginX( float x )
598 const Vector3& current = GetCurrentParentOrigin();
600 SetParentOrigin( Vector3( x, current.y, current.z ) );
603 void Actor::SetParentOriginY( float y )
605 const Vector3& current = GetCurrentParentOrigin();
607 SetParentOrigin( Vector3( current.x, y, current.z ) );
610 void Actor::SetParentOriginZ( float z )
612 const Vector3& current = GetCurrentParentOrigin();
614 SetParentOrigin( Vector3( current.x, current.y, z ) );
617 const Vector3& Actor::GetCurrentParentOrigin() const
619 // Cached for event-thread access
620 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
623 void Actor::SetAnchorPoint( const Vector3& anchor )
627 // mNode is being used in a separate thread; queue a message to set the value & base value
628 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
631 // Cache for event-thread access
634 // not allocated, check if different from default
635 if( AnchorPoint::DEFAULT != anchor )
637 mAnchorPoint = new Vector3( anchor );
642 // check if different from current costs more than just set
643 *mAnchorPoint = anchor;
647 void Actor::SetAnchorPointX( float x )
649 const Vector3& current = GetCurrentAnchorPoint();
651 SetAnchorPoint( Vector3( x, current.y, current.z ) );
654 void Actor::SetAnchorPointY( float y )
656 const Vector3& current = GetCurrentAnchorPoint();
658 SetAnchorPoint( Vector3( current.x, y, current.z ) );
661 void Actor::SetAnchorPointZ( float z )
663 const Vector3& current = GetCurrentAnchorPoint();
665 SetAnchorPoint( Vector3( current.x, current.y, z ) );
668 const Vector3& Actor::GetCurrentAnchorPoint() const
670 // Cached for event-thread access
671 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
674 void Actor::SetPosition( float x, float y )
676 SetPosition( Vector3( x, y, 0.0f ) );
679 void Actor::SetPosition( float x, float y, float z )
681 SetPosition( Vector3( x, y, z ) );
684 void Actor::SetPosition( const Vector3& position )
686 mTargetPosition = position;
690 // mNode is being used in a separate thread; queue a message to set the value & base value
691 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
695 void Actor::SetX( float x )
697 mTargetPosition.x = x;
701 // mNode is being used in a separate thread; queue a message to set the value & base value
702 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
706 void Actor::SetY( float y )
708 mTargetPosition.y = y;
712 // mNode is being used in a separate thread; queue a message to set the value & base value
713 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
717 void Actor::SetZ( float z )
719 mTargetPosition.z = z;
723 // mNode is being used in a separate thread; queue a message to set the value & base value
724 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
728 void Actor::TranslateBy( const Vector3& distance )
730 mTargetPosition += distance;
734 // mNode is being used in a separate thread; queue a message to set the value & base value
735 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
739 const Vector3& Actor::GetCurrentPosition() const
743 // mNode is being used in a separate thread; copy the value from the previous update
744 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
747 return Vector3::ZERO;
750 const Vector3& Actor::GetTargetPosition() const
752 return mTargetPosition;
755 const Vector3& Actor::GetCurrentWorldPosition() const
759 // mNode is being used in a separate thread; copy the value from the previous update
760 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
763 return Vector3::ZERO;
766 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
768 // this flag is not animatable so keep the value
769 mPositionInheritanceMode = mode;
772 // mNode is being used in a separate thread; queue a message to set the value
773 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
777 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
779 // Cached for event-thread access
780 return mPositionInheritanceMode;
783 void Actor::SetInheritPosition( bool inherit )
785 if( mInheritPosition != inherit && NULL != mNode )
787 // non animateable so keep local copy
788 mInheritPosition = inherit;
789 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
793 bool Actor::IsPositionInherited() const
795 return mInheritPosition;
798 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
800 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
801 normalizedAxis.Normalize();
803 Quaternion orientation( angle, normalizedAxis );
805 SetOrientation( orientation );
808 void Actor::SetOrientation( const Quaternion& orientation )
812 // mNode is being used in a separate thread; queue a message to set the value & base value
813 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
817 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
821 // mNode is being used in a separate thread; queue a message to set the value & base value
822 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
826 void Actor::RotateBy( const Quaternion& relativeRotation )
830 // mNode is being used in a separate thread; queue a message to set the value & base value
831 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
835 const Quaternion& Actor::GetCurrentOrientation() const
839 // mNode is being used in a separate thread; copy the value from the previous update
840 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
843 return Quaternion::IDENTITY;
846 const Quaternion& Actor::GetCurrentWorldOrientation() const
850 // mNode is being used in a separate thread; copy the value from the previous update
851 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
854 return Quaternion::IDENTITY;
857 void Actor::SetScale( float scale )
859 SetScale( Vector3( scale, scale, scale ) );
862 void Actor::SetScale( float x, float y, float z )
864 SetScale( Vector3( x, y, z ) );
867 void Actor::SetScale( const Vector3& scale )
871 // mNode is being used in a separate thread; queue a message to set the value & base value
872 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
876 void Actor::SetScaleX( float x )
880 // mNode is being used in a separate thread; queue a message to set the value & base value
881 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
885 void Actor::SetScaleY( float y )
889 // mNode is being used in a separate thread; queue a message to set the value & base value
890 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
894 void Actor::SetScaleZ( float z )
898 // mNode is being used in a separate thread; queue a message to set the value & base value
899 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
903 void Actor::ScaleBy(const Vector3& relativeScale)
907 // mNode is being used in a separate thread; queue a message to set the value & base value
908 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
912 const Vector3& Actor::GetCurrentScale() const
916 // mNode is being used in a separate thread; copy the value from the previous update
917 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
923 const Vector3& Actor::GetCurrentWorldScale() const
927 // mNode is being used in a separate thread; copy the value from the previous update
928 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
934 void Actor::SetInheritScale( bool inherit )
937 if( mInheritScale != inherit && NULL != mNode )
939 // non animateable so keep local copy
940 mInheritScale = inherit;
941 // mNode is being used in a separate thread; queue a message to set the value
942 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
946 bool Actor::IsScaleInherited() const
948 return mInheritScale;
951 Matrix Actor::GetCurrentWorldMatrix() const
955 return mNode->GetWorldMatrix(0);
958 return Matrix::IDENTITY;
961 void Actor::SetVisible( bool visible )
965 // mNode is being used in a separate thread; queue a message to set the value & base value
966 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
970 bool Actor::IsVisible() const
974 // mNode is being used in a separate thread; copy the value from the previous update
975 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
981 void Actor::SetOpacity( float opacity )
985 // mNode is being used in a separate thread; queue a message to set the value & base value
986 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
990 float Actor::GetCurrentOpacity() const
994 // mNode is being used in a separate thread; copy the value from the previous update
995 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1001 const Vector4& Actor::GetCurrentWorldColor() const
1005 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1008 return Color::WHITE;
1011 void Actor::SetColor( const Vector4& color )
1015 // mNode is being used in a separate thread; queue a message to set the value & base value
1016 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1020 void Actor::SetColorRed( float red )
1024 // mNode is being used in a separate thread; queue a message to set the value & base value
1025 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1029 void Actor::SetColorGreen( float green )
1033 // mNode is being used in a separate thread; queue a message to set the value & base value
1034 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1038 void Actor::SetColorBlue( float blue )
1042 // mNode is being used in a separate thread; queue a message to set the value & base value
1043 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1047 const Vector4& Actor::GetCurrentColor() const
1051 // mNode is being used in a separate thread; copy the value from the previous update
1052 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1055 return Color::WHITE;
1058 void Actor::SetInheritOrientation( bool inherit )
1060 if( mInheritOrientation != inherit && NULL != mNode)
1062 // non animateable so keep local copy
1063 mInheritOrientation = inherit;
1064 // mNode is being used in a separate thread; queue a message to set the value
1065 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1069 bool Actor::IsOrientationInherited() const
1071 return mInheritOrientation;
1074 void Actor::SetSizeModeFactor( const Vector3& factor )
1076 EnsureRelayoutData();
1078 mRelayoutData->sizeModeFactor = factor;
1081 const Vector3& Actor::GetSizeModeFactor() const
1083 if ( mRelayoutData )
1085 return mRelayoutData->sizeModeFactor;
1088 return GetDefaultSizeModeFactor();
1091 void Actor::SetColorMode( ColorMode colorMode )
1093 // non animateable so keep local copy
1094 mColorMode = colorMode;
1097 // mNode is being used in a separate thread; queue a message to set the value
1098 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1102 ColorMode Actor::GetColorMode() const
1104 // we have cached copy
1108 void Actor::SetSize( float width, float height )
1110 SetSize( Vector2( width, height ) );
1113 void Actor::SetSize( float width, float height, float depth )
1115 SetSize( Vector3( width, height, depth ) );
1118 void Actor::SetSize( const Vector2& size )
1120 SetSize( Vector3( size.width, size.height, 0.f ) );
1123 void Actor::SetSizeInternal( const Vector2& size )
1125 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1128 void Actor::SetSize( const Vector3& size )
1130 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1132 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1133 SetPreferredSize( size.GetVectorXY() );
1137 SetSizeInternal( size );
1141 void Actor::SetSizeInternal( const Vector3& size )
1143 // dont allow recursive loop
1144 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1145 // 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
1146 if( ( NULL != mNode )&&
1147 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1148 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1149 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1153 // mNode is being used in a separate thread; queue a message to set the value & base value
1154 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1156 // Notification for derived classes
1157 mInsideOnSizeSet = true;
1158 OnSizeSet( mTargetSize );
1159 mInsideOnSizeSet = false;
1161 // Raise a relayout request if the flag is not locked
1162 if( mRelayoutData && !mRelayoutData->insideRelayout )
1169 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1171 mTargetSize = targetSize;
1173 // Notify deriving classes
1174 OnSizeAnimation( animation, mTargetSize );
1177 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1179 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1181 mTargetSize.width = targetSize;
1183 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1185 mTargetSize.height = targetSize;
1187 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1189 mTargetSize.depth = targetSize;
1191 // Notify deriving classes
1192 OnSizeAnimation( animation, mTargetSize );
1195 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1197 mTargetPosition = targetPosition;
1200 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1202 if ( Dali::Actor::Property::POSITION_X == property )
1204 mTargetPosition.x = targetPosition;
1206 else if ( Dali::Actor::Property::POSITION_Y == property )
1208 mTargetPosition.y = targetPosition;
1210 else if ( Dali::Actor::Property::POSITION_Z == property )
1212 mTargetPosition.z = targetPosition;
1216 void Actor::SetWidth( float width )
1218 mTargetSize.width = width;
1222 // mNode is being used in a separate thread; queue a message to set the value & base value
1223 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1227 void Actor::SetHeight( float height )
1229 mTargetSize.height = height;
1233 // mNode is being used in a separate thread; queue a message to set the value & base value
1234 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1238 void Actor::SetDepth( float depth )
1240 mTargetSize.depth = depth;
1244 // mNode is being used in a separate thread; queue a message to set the value & base value
1245 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1249 const Vector3& Actor::GetTargetSize() const
1254 const Vector3& Actor::GetCurrentSize() const
1258 // mNode is being used in a separate thread; copy the value from the previous update
1259 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1262 return Vector3::ZERO;
1265 Vector3 Actor::GetNaturalSize() const
1267 // It is up to deriving classes to return the appropriate natural size
1268 return Vector3( 0.0f, 0.0f, 0.0f );
1271 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1273 EnsureRelayoutData();
1275 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1277 if( dimension & ( 1 << i ) )
1279 mRelayoutData->resizePolicies[ i ] = policy;
1283 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1285 if( dimension & Dimension::WIDTH )
1287 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1290 if( dimension & Dimension::HEIGHT )
1292 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1296 // If calling SetResizePolicy, assume we want relayout enabled
1297 SetRelayoutEnabled( true );
1299 OnSetResizePolicy( policy, dimension );
1301 // Trigger relayout on this control
1305 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1307 if ( mRelayoutData )
1309 // If more than one dimension is requested, just return the first one found
1310 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1312 if( ( dimension & ( 1 << i ) ) )
1314 return mRelayoutData->resizePolicies[ i ];
1319 return ResizePolicy::DEFAULT;
1322 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1324 EnsureRelayoutData();
1326 mRelayoutData->sizeSetPolicy = policy;
1329 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1331 if ( mRelayoutData )
1333 return mRelayoutData->sizeSetPolicy;
1336 return DEFAULT_SIZE_SCALE_POLICY;
1339 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1341 EnsureRelayoutData();
1343 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1345 if( dimension & ( 1 << i ) )
1347 mRelayoutData->dimensionDependencies[ i ] = dependency;
1352 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1354 if ( mRelayoutData )
1356 // If more than one dimension is requested, just return the first one found
1357 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1359 if( ( dimension & ( 1 << i ) ) )
1361 return mRelayoutData->dimensionDependencies[ i ];
1366 return Dimension::ALL_DIMENSIONS; // Default
1369 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1371 // If relayout data has not been allocated yet and the client is requesting
1372 // to disable it, do nothing
1373 if( mRelayoutData || relayoutEnabled )
1375 EnsureRelayoutData();
1377 mRelayoutData->relayoutEnabled = relayoutEnabled;
1381 bool Actor::IsRelayoutEnabled() const
1383 // Assume that if relayout data has not been allocated yet then
1384 // relayout is disabled
1385 return mRelayoutData && mRelayoutData->relayoutEnabled;
1388 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1390 EnsureRelayoutData();
1392 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1394 if( dimension & ( 1 << i ) )
1396 mRelayoutData->dimensionDirty[ i ] = dirty;
1401 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1403 if ( mRelayoutData )
1405 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1407 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1417 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1419 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1422 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1424 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1427 unsigned int Actor::AddRenderer( Renderer& renderer )
1431 mRenderers = new RendererContainer;
1434 unsigned int index = mRenderers->size();
1435 RendererPtr rendererPtr = RendererPtr( &renderer );
1436 mRenderers->push_back( rendererPtr );
1437 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1441 rendererPtr->Connect();
1447 unsigned int Actor::GetRendererCount() const
1449 unsigned int rendererCount(0);
1452 rendererCount = mRenderers->size();
1455 return rendererCount;
1458 RendererPtr Actor::GetRendererAt( unsigned int index )
1460 RendererPtr renderer;
1461 if( index < GetRendererCount() )
1463 renderer = ( *mRenderers )[ index ];
1469 void Actor::RemoveRenderer( Renderer& renderer )
1473 RendererIter end = mRenderers->end();
1474 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1476 if( (*iter).Get() == &renderer )
1478 mRenderers->erase( iter );
1479 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1486 void Actor::RemoveRenderer( unsigned int index )
1488 if( index < GetRendererCount() )
1490 RendererPtr renderer = ( *mRenderers )[ index ];
1491 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1492 mRenderers->erase( mRenderers->begin()+index );
1496 void Actor::SetOverlay( bool enable )
1498 // Setting STENCIL will override OVERLAY_2D
1499 if( DrawMode::STENCIL != mDrawMode )
1501 SetDrawMode( enable ? DrawMode::OVERLAY_2D : DrawMode::NORMAL );
1505 bool Actor::IsOverlay() const
1507 return ( DrawMode::OVERLAY_2D == mDrawMode );
1510 void Actor::SetDrawMode( DrawMode::Type drawMode )
1512 // this flag is not animatable so keep the value
1513 mDrawMode = drawMode;
1516 // mNode is being used in a separate thread; queue a message to set the value
1517 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1521 DrawMode::Type Actor::GetDrawMode() const
1526 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1528 // only valid when on-stage
1529 StagePtr stage = Stage::GetCurrent();
1530 if( stage && OnStage() )
1532 const RenderTaskList& taskList = stage->GetRenderTaskList();
1534 Vector2 converted( screenX, screenY );
1536 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1537 const int taskCount = taskList.GetTaskCount();
1538 for( int i = taskCount - 1; i >= 0; --i )
1540 Dali::RenderTask task = taskList.GetTask( i );
1541 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1543 // found a task where this conversion was ok so return
1551 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1553 bool retval = false;
1554 // only valid when on-stage
1557 CameraActor* camera = renderTask.GetCameraActor();
1561 renderTask.GetViewport( viewport );
1563 // need to translate coordinates to render tasks coordinate space
1564 Vector2 converted( screenX, screenY );
1565 if( renderTask.TranslateCoordinates( converted ) )
1567 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1574 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1576 // Early-out if mNode is NULL
1582 // Get the ModelView matrix
1584 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1586 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1587 Matrix invertedMvp( false/*don't init*/);
1588 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1589 bool success = invertedMvp.Invert();
1591 // Convert to GL coordinates
1592 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1597 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1604 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1610 if( XyPlaneIntersect( nearPos, farPos, local ) )
1612 Vector3 size = GetCurrentSize();
1613 localX = local.x + size.x * 0.5f;
1614 localY = local.y + size.y * 0.5f;
1625 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1628 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1630 Mathematical Formulation
1632 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1634 ( p - c ) dot ( p - c ) = r^2
1636 Given a ray with a point of origin 'o', and a direction vector 'd':
1638 ray(t) = o + td, t >= 0
1640 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1642 (o + td - c ) dot ( o + td - c ) = r^2
1644 To solve for t we first expand the above into a more recognisable quadratic equation form
1646 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1655 B = 2( o - c ) dot d
1656 C = ( o - c ) dot ( o - c ) - r^2
1658 which can be solved using a standard quadratic formula.
1660 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1662 Practical Simplification
1664 In a renderer, we often differentiate between world space and object space. In the object space
1665 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1666 into object space, the mathematical solution presented above can be simplified significantly.
1668 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1672 and we can find the t at which the (transformed) ray intersects the sphere by
1674 ( o + td ) dot ( o + td ) = r^2
1676 According to the reasoning above, we expand the above quadratic equation into the general form
1680 which now has coefficients:
1687 // Early out if mNode is NULL
1693 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1695 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1696 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1697 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1699 // Compute the radius is not needed, square radius it's enough.
1700 const Vector3& size( mNode->GetSize( bufferIndex ) );
1702 // Scale the sphere.
1703 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1705 const float width = size.width * scale.width;
1706 const float height = size.height * scale.height;
1708 float squareSphereRadius = 0.5f * ( width * width + height * height );
1710 float a = rayDir.Dot( rayDir ); // a
1711 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1712 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1714 return ( b2 * b2 - a * c ) >= 0.f;
1717 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1724 // Transforms the ray to the local reference system.
1725 // Calculate the inverse of Model matrix
1726 Matrix invModelMatrix( false/*don't init*/);
1728 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1729 invModelMatrix = mNode->GetWorldMatrix(0);
1730 invModelMatrix.Invert();
1732 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1733 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1735 // Test with the actor's XY plane (Normal = 0 0 1 1).
1737 float a = -rayOriginLocal.z;
1738 float b = rayDirLocal.z;
1740 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1742 // Ray travels distance * rayDirLocal to intersect with plane.
1745 const Vector3& size = mNode->GetSize( bufferIndex );
1747 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1748 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1750 // Test with the actor's geometry.
1751 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1758 void Actor::SetLeaveRequired( bool required )
1760 mLeaveRequired = required;
1763 bool Actor::GetLeaveRequired() const
1765 return mLeaveRequired;
1768 void Actor::SetKeyboardFocusable( bool focusable )
1770 mKeyboardFocusable = focusable;
1773 bool Actor::IsKeyboardFocusable() const
1775 return mKeyboardFocusable;
1778 bool Actor::GetTouchRequired() const
1780 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1783 bool Actor::GetHoverRequired() const
1785 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1788 bool Actor::GetWheelEventRequired() const
1790 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1793 bool Actor::IsHittable() const
1795 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1798 ActorGestureData& Actor::GetGestureData()
1800 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1801 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1802 if( NULL == mGestureData )
1804 mGestureData = new ActorGestureData;
1806 return *mGestureData;
1809 bool Actor::IsGestureRequred( Gesture::Type type ) const
1811 return mGestureData && mGestureData->IsGestureRequred( type );
1814 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1816 bool consumed = false;
1818 if( !mTouchSignal.Empty() )
1820 Dali::Actor handle( this );
1821 consumed = mTouchSignal.Emit( handle, touch );
1824 if( !mTouchedSignal.Empty() || !mTouchSignal.Empty() )
1826 Dali::Actor handle( this );
1827 consumed |= mTouchedSignal.Emit( handle, event );
1832 // Notification for derived classes
1833 consumed = OnTouchEvent( event ); // TODO
1839 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1841 bool consumed = false;
1843 if( !mHoveredSignal.Empty() )
1845 Dali::Actor handle( this );
1846 consumed = mHoveredSignal.Emit( handle, event );
1851 // Notification for derived classes
1852 consumed = OnHoverEvent( event );
1858 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1860 bool consumed = false;
1862 if( !mWheelEventSignal.Empty() )
1864 Dali::Actor handle( this );
1865 consumed = mWheelEventSignal.Emit( handle, event );
1870 // Notification for derived classes
1871 consumed = OnWheelEvent( event );
1877 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1879 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1880 return mTouchedSignal;
1883 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1885 return mTouchSignal;
1888 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1890 return mHoveredSignal;
1893 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1895 return mWheelEventSignal;
1898 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1900 return mOnStageSignal;
1903 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1905 return mOffStageSignal;
1908 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1910 return mOnRelayoutSignal;
1913 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1915 bool connected( true );
1916 Actor* actor = dynamic_cast< Actor* >( object );
1918 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1920 actor->TouchedSignal().Connect( tracker, functor );
1922 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1924 actor->HoveredSignal().Connect( tracker, functor );
1926 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1928 actor->WheelEventSignal().Connect( tracker, functor );
1930 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1932 actor->OnStageSignal().Connect( tracker, functor );
1934 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1936 actor->OffStageSignal().Connect( tracker, functor );
1938 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1940 actor->OnRelayoutSignal().Connect( tracker, functor );
1944 // signalName does not match any signal
1951 Actor::Actor( DerivedType derivedType )
1956 mParentOrigin( NULL ),
1957 mAnchorPoint( NULL ),
1958 mRelayoutData( NULL ),
1959 mGestureData( NULL ),
1960 mTargetSize( 0.0f, 0.0f, 0.0f ),
1962 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1964 mIsRoot( ROOT_LAYER == derivedType ),
1965 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1966 mIsOnStage( false ),
1968 mLeaveRequired( false ),
1969 mKeyboardFocusable( false ),
1970 mDerivedRequiresTouch( false ),
1971 mDerivedRequiresHover( false ),
1972 mDerivedRequiresWheelEvent( false ),
1973 mOnStageSignalled( false ),
1974 mInsideOnSizeSet( false ),
1975 mInheritPosition( true ),
1976 mInheritOrientation( true ),
1977 mInheritScale( true ),
1978 mDrawMode( DrawMode::NORMAL ),
1979 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1980 mColorMode( Node::DEFAULT_COLOR_MODE )
1984 void Actor::Initialize()
1987 SceneGraph::Node* node = CreateNode();
1989 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
1990 mNode = node; // Keep raw-pointer to Node
1994 GetEventThreadServices().RegisterObject( this );
1999 // Remove mParent pointers from children even if we're destroying core,
2000 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2003 ActorConstIter endIter = mChildren->end();
2004 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2006 (*iter)->SetParent( NULL );
2012 // Guard to allow handle destruction after Core has been destroyed
2013 if( EventThreadServices::IsCoreRunning() )
2017 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2018 mNode = NULL; // Node is about to be destroyed
2021 GetEventThreadServices().UnregisterObject( this );
2024 // Cleanup optional gesture data
2025 delete mGestureData;
2027 // Cleanup optional parent origin and anchor
2028 delete mParentOrigin;
2029 delete mAnchorPoint;
2031 // Delete optional relayout data
2034 delete mRelayoutData;
2038 void Actor::ConnectToStage( unsigned int parentDepth )
2040 // This container is used instead of walking the Actor hierarchy.
2041 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2042 ActorContainer connectionList;
2044 // This stage is atomic i.e. not interrupted by user callbacks.
2045 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2047 // Notify applications about the newly connected actors.
2048 const ActorIter endIter = connectionList.end();
2049 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2051 (*iter)->NotifyStageConnection();
2057 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2059 DALI_ASSERT_ALWAYS( !OnStage() );
2064 ConnectToSceneGraph();
2066 // Notification for internal derived classes
2067 OnStageConnectionInternal();
2069 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2070 connectionList.push_back( ActorPtr( this ) );
2072 // Recursively connect children
2075 ActorConstIter endIter = mChildren->end();
2076 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2078 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2084 * This method is called when the Actor is connected to the Stage.
2085 * The parent must have added its Node to the scene-graph.
2086 * The child must connect its Node to the parent's Node.
2087 * This is recursive; the child calls ConnectToStage() for its children.
2089 void Actor::ConnectToSceneGraph()
2091 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2095 // Reparent Node in next Update
2096 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2099 unsigned int rendererCount( GetRendererCount() );
2100 for( unsigned int i(0); i<rendererCount; ++i )
2102 GetRendererAt(i)->Connect();
2105 // Request relayout on all actors that are added to the scenegraph
2108 // Notification for Object::Observers
2112 void Actor::NotifyStageConnection()
2114 // Actors can be removed (in a callback), before the on-stage stage is reported.
2115 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2116 if( OnStage() && !mOnStageSignalled )
2118 // Notification for external (CustomActor) derived classes
2119 OnStageConnectionExternal( mDepth );
2121 if( !mOnStageSignal.Empty() )
2123 Dali::Actor handle( this );
2124 mOnStageSignal.Emit( handle );
2127 // Guard against Remove during callbacks
2130 mOnStageSignalled = true; // signal required next time Actor is removed
2135 void Actor::DisconnectFromStage()
2137 // This container is used instead of walking the Actor hierachy.
2138 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2139 ActorContainer disconnectionList;
2141 // This stage is atomic i.e. not interrupted by user callbacks
2142 RecursiveDisconnectFromStage( disconnectionList );
2144 // Notify applications about the newly disconnected actors.
2145 const ActorIter endIter = disconnectionList.end();
2146 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2148 (*iter)->NotifyStageDisconnection();
2152 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2154 DALI_ASSERT_ALWAYS( OnStage() );
2156 // Recursively disconnect children
2159 ActorConstIter endIter = mChildren->end();
2160 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2162 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2166 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2167 disconnectionList.push_back( ActorPtr( this ) );
2169 // Notification for internal derived classes
2170 OnStageDisconnectionInternal();
2172 DisconnectFromSceneGraph();
2178 * This method is called by an actor or its parent, before a node removal message is sent.
2179 * This is recursive; the child calls DisconnectFromStage() for its children.
2181 void Actor::DisconnectFromSceneGraph()
2183 // Notification for Object::Observers
2184 OnSceneObjectRemove();
2186 unsigned int rendererCount( GetRendererCount() );
2187 for( unsigned int i(0); i<rendererCount; ++i )
2189 GetRendererAt(i)->Disconnect();
2193 void Actor::NotifyStageDisconnection()
2195 // Actors can be added (in a callback), before the off-stage state is reported.
2196 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2197 // only do this step if there is a stage, i.e. Core is not being shut down
2198 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2200 // Notification for external (CustomeActor) derived classes
2201 OnStageDisconnectionExternal();
2203 if( !mOffStageSignal.Empty() )
2205 Dali::Actor handle( this );
2206 mOffStageSignal.Emit( handle );
2209 // Guard against Add during callbacks
2212 mOnStageSignalled = false; // signal required next time Actor is added
2217 bool Actor::IsNodeConnected() const
2219 bool connected( false );
2221 if( OnStage() && ( NULL != mNode ) )
2223 if( IsRoot() || mNode->GetParent() )
2232 unsigned int Actor::GetDefaultPropertyCount() const
2234 return DEFAULT_PROPERTY_COUNT;
2237 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2239 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2241 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2243 indices.PushBack( i );
2247 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2249 if( index < DEFAULT_PROPERTY_COUNT )
2251 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2257 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2259 Property::Index index = Property::INVALID_INDEX;
2261 // Look for name in default properties
2262 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2264 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2265 if( 0 == name.compare( property->name ) )
2275 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2277 if( index < DEFAULT_PROPERTY_COUNT )
2279 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2285 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2287 if( index < DEFAULT_PROPERTY_COUNT )
2289 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2295 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2297 if( index < DEFAULT_PROPERTY_COUNT )
2299 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2305 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2307 if( index < DEFAULT_PROPERTY_COUNT )
2309 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2312 // index out of range...return Property::NONE
2313 return Property::NONE;
2316 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2320 case Dali::Actor::Property::PARENT_ORIGIN:
2322 Property::Type type = property.GetType();
2323 if( type == Property::VECTOR3 )
2325 SetParentOrigin( property.Get< Vector3 >() );
2327 else if ( type == Property::STRING )
2329 std::string parentOriginString;
2330 property.Get( parentOriginString );
2331 Vector3 parentOrigin;
2332 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2334 SetParentOrigin( parentOrigin );
2340 case Dali::Actor::Property::PARENT_ORIGIN_X:
2342 SetParentOriginX( property.Get< float >() );
2346 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2348 SetParentOriginY( property.Get< float >() );
2352 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2354 SetParentOriginZ( property.Get< float >() );
2358 case Dali::Actor::Property::ANCHOR_POINT:
2360 Property::Type type = property.GetType();
2361 if( type == Property::VECTOR3 )
2363 SetAnchorPoint( property.Get< Vector3 >() );
2365 else if ( type == Property::STRING )
2367 std::string anchorPointString;
2368 property.Get( anchorPointString );
2370 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2372 SetAnchorPoint( anchor );
2378 case Dali::Actor::Property::ANCHOR_POINT_X:
2380 SetAnchorPointX( property.Get< float >() );
2384 case Dali::Actor::Property::ANCHOR_POINT_Y:
2386 SetAnchorPointY( property.Get< float >() );
2390 case Dali::Actor::Property::ANCHOR_POINT_Z:
2392 SetAnchorPointZ( property.Get< float >() );
2396 case Dali::Actor::Property::SIZE:
2398 SetSize( property.Get< Vector3 >() );
2402 case Dali::Actor::Property::SIZE_WIDTH:
2404 SetWidth( property.Get< float >() );
2408 case Dali::Actor::Property::SIZE_HEIGHT:
2410 SetHeight( property.Get< float >() );
2414 case Dali::Actor::Property::SIZE_DEPTH:
2416 SetDepth( property.Get< float >() );
2420 case Dali::Actor::Property::POSITION:
2422 SetPosition( property.Get< Vector3 >() );
2426 case Dali::Actor::Property::POSITION_X:
2428 SetX( property.Get< float >() );
2432 case Dali::Actor::Property::POSITION_Y:
2434 SetY( property.Get< float >() );
2438 case Dali::Actor::Property::POSITION_Z:
2440 SetZ( property.Get< float >() );
2444 case Dali::Actor::Property::ORIENTATION:
2446 SetOrientation( property.Get< Quaternion >() );
2450 case Dali::Actor::Property::SCALE:
2452 SetScale( property.Get< Vector3 >() );
2456 case Dali::Actor::Property::SCALE_X:
2458 SetScaleX( property.Get< float >() );
2462 case Dali::Actor::Property::SCALE_Y:
2464 SetScaleY( property.Get< float >() );
2468 case Dali::Actor::Property::SCALE_Z:
2470 SetScaleZ( property.Get< float >() );
2474 case Dali::Actor::Property::VISIBLE:
2476 SetVisible( property.Get< bool >() );
2480 case Dali::Actor::Property::COLOR:
2482 SetColor( property.Get< Vector4 >() );
2486 case Dali::Actor::Property::COLOR_RED:
2488 SetColorRed( property.Get< float >() );
2492 case Dali::Actor::Property::COLOR_GREEN:
2494 SetColorGreen( property.Get< float >() );
2498 case Dali::Actor::Property::COLOR_BLUE:
2500 SetColorBlue( property.Get< float >() );
2504 case Dali::Actor::Property::COLOR_ALPHA:
2506 SetOpacity( property.Get< float >() );
2510 case Dali::Actor::Property::NAME:
2512 SetName( property.Get< std::string >() );
2516 case Dali::Actor::Property::SENSITIVE:
2518 SetSensitive( property.Get< bool >() );
2522 case Dali::Actor::Property::LEAVE_REQUIRED:
2524 SetLeaveRequired( property.Get< bool >() );
2528 case Dali::Actor::Property::INHERIT_POSITION:
2530 SetInheritPosition( property.Get< bool >() );
2534 case Dali::Actor::Property::INHERIT_ORIENTATION:
2536 SetInheritOrientation( property.Get< bool >() );
2540 case Dali::Actor::Property::INHERIT_SCALE:
2542 SetInheritScale( property.Get< bool >() );
2546 case Dali::Actor::Property::COLOR_MODE:
2549 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2551 SetColorMode( mode );
2556 case Dali::Actor::Property::POSITION_INHERITANCE:
2558 PositionInheritanceMode mode;
2559 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2561 SetPositionInheritanceMode( mode );
2566 case Dali::Actor::Property::DRAW_MODE:
2568 DrawMode::Type mode;
2569 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2571 SetDrawMode( mode );
2576 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2578 SetSizeModeFactor( property.Get< Vector3 >() );
2582 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2584 ResizePolicy::Type type;
2585 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2587 SetResizePolicy( type, Dimension::WIDTH );
2592 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2594 ResizePolicy::Type type;
2595 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2597 SetResizePolicy( type, Dimension::HEIGHT );
2602 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2604 SizeScalePolicy::Type type;
2605 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2607 SetSizeScalePolicy( type );
2612 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2614 if( property.Get< bool >() )
2616 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2621 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2623 if( property.Get< bool >() )
2625 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2630 case Dali::Actor::Property::PADDING:
2632 Vector4 padding = property.Get< Vector4 >();
2633 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2634 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2638 case Dali::Actor::Property::MINIMUM_SIZE:
2640 Vector2 size = property.Get< Vector2 >();
2641 SetMinimumSize( size.x, Dimension::WIDTH );
2642 SetMinimumSize( size.y, Dimension::HEIGHT );
2646 case Dali::Actor::Property::MAXIMUM_SIZE:
2648 Vector2 size = property.Get< Vector2 >();
2649 SetMaximumSize( size.x, Dimension::WIDTH );
2650 SetMaximumSize( size.y, Dimension::HEIGHT );
2656 // this can happen in the case of a non-animatable default property so just do nothing
2662 // TODO: This method needs to be removed
2663 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2665 switch( entry.GetType() )
2667 case Property::BOOLEAN:
2669 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2670 DALI_ASSERT_DEBUG( NULL != property );
2672 // property is being used in a separate thread; queue a message to set the property
2673 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2678 case Property::INTEGER:
2680 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2681 DALI_ASSERT_DEBUG( NULL != property );
2683 // property is being used in a separate thread; queue a message to set the property
2684 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2689 case Property::FLOAT:
2691 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2692 DALI_ASSERT_DEBUG( NULL != property );
2694 // property is being used in a separate thread; queue a message to set the property
2695 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2700 case Property::VECTOR2:
2702 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2703 DALI_ASSERT_DEBUG( NULL != property );
2705 // property is being used in a separate thread; queue a message to set the property
2706 if(entry.componentIndex == 0)
2708 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2710 else if(entry.componentIndex == 1)
2712 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2716 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2722 case Property::VECTOR3:
2724 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2725 DALI_ASSERT_DEBUG( NULL != property );
2727 // property is being used in a separate thread; queue a message to set the property
2728 if(entry.componentIndex == 0)
2730 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2732 else if(entry.componentIndex == 1)
2734 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2736 else if(entry.componentIndex == 2)
2738 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2742 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2748 case Property::VECTOR4:
2750 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2751 DALI_ASSERT_DEBUG( NULL != property );
2753 // property is being used in a separate thread; queue a message to set the property
2754 if(entry.componentIndex == 0)
2756 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2758 else if(entry.componentIndex == 1)
2760 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2762 else if(entry.componentIndex == 2)
2764 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2766 else if(entry.componentIndex == 3)
2768 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2772 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2778 case Property::ROTATION:
2780 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2781 DALI_ASSERT_DEBUG( NULL != property );
2783 // property is being used in a separate thread; queue a message to set the property
2784 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2789 case Property::MATRIX:
2791 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2792 DALI_ASSERT_DEBUG( NULL != property );
2794 // property is being used in a separate thread; queue a message to set the property
2795 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2800 case Property::MATRIX3:
2802 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2803 DALI_ASSERT_DEBUG( NULL != property );
2805 // property is being used in a separate thread; queue a message to set the property
2806 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2813 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2819 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2821 Property::Value value;
2825 case Dali::Actor::Property::PARENT_ORIGIN:
2827 value = GetCurrentParentOrigin();
2831 case Dali::Actor::Property::PARENT_ORIGIN_X:
2833 value = GetCurrentParentOrigin().x;
2837 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2839 value = GetCurrentParentOrigin().y;
2843 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2845 value = GetCurrentParentOrigin().z;
2849 case Dali::Actor::Property::ANCHOR_POINT:
2851 value = GetCurrentAnchorPoint();
2855 case Dali::Actor::Property::ANCHOR_POINT_X:
2857 value = GetCurrentAnchorPoint().x;
2861 case Dali::Actor::Property::ANCHOR_POINT_Y:
2863 value = GetCurrentAnchorPoint().y;
2867 case Dali::Actor::Property::ANCHOR_POINT_Z:
2869 value = GetCurrentAnchorPoint().z;
2873 case Dali::Actor::Property::SIZE:
2875 value = GetTargetSize();
2879 case Dali::Actor::Property::SIZE_WIDTH:
2881 value = GetTargetSize().width;
2885 case Dali::Actor::Property::SIZE_HEIGHT:
2887 value = GetTargetSize().height;
2891 case Dali::Actor::Property::SIZE_DEPTH:
2893 value = GetTargetSize().depth;
2897 case Dali::Actor::Property::POSITION:
2899 value = GetTargetPosition();
2903 case Dali::Actor::Property::POSITION_X:
2905 value = GetTargetPosition().x;
2909 case Dali::Actor::Property::POSITION_Y:
2911 value = GetTargetPosition().y;
2915 case Dali::Actor::Property::POSITION_Z:
2917 value = GetTargetPosition().z;
2921 case Dali::Actor::Property::WORLD_POSITION:
2923 value = GetCurrentWorldPosition();
2927 case Dali::Actor::Property::WORLD_POSITION_X:
2929 value = GetCurrentWorldPosition().x;
2933 case Dali::Actor::Property::WORLD_POSITION_Y:
2935 value = GetCurrentWorldPosition().y;
2939 case Dali::Actor::Property::WORLD_POSITION_Z:
2941 value = GetCurrentWorldPosition().z;
2945 case Dali::Actor::Property::ORIENTATION:
2947 value = GetCurrentOrientation();
2951 case Dali::Actor::Property::WORLD_ORIENTATION:
2953 value = GetCurrentWorldOrientation();
2957 case Dali::Actor::Property::SCALE:
2959 value = GetCurrentScale();
2963 case Dali::Actor::Property::SCALE_X:
2965 value = GetCurrentScale().x;
2969 case Dali::Actor::Property::SCALE_Y:
2971 value = GetCurrentScale().y;
2975 case Dali::Actor::Property::SCALE_Z:
2977 value = GetCurrentScale().z;
2981 case Dali::Actor::Property::WORLD_SCALE:
2983 value = GetCurrentWorldScale();
2987 case Dali::Actor::Property::VISIBLE:
2989 value = IsVisible();
2993 case Dali::Actor::Property::COLOR:
2995 value = GetCurrentColor();
2999 case Dali::Actor::Property::COLOR_RED:
3001 value = GetCurrentColor().r;
3005 case Dali::Actor::Property::COLOR_GREEN:
3007 value = GetCurrentColor().g;
3011 case Dali::Actor::Property::COLOR_BLUE:
3013 value = GetCurrentColor().b;
3017 case Dali::Actor::Property::COLOR_ALPHA:
3019 value = GetCurrentColor().a;
3023 case Dali::Actor::Property::WORLD_COLOR:
3025 value = GetCurrentWorldColor();
3029 case Dali::Actor::Property::WORLD_MATRIX:
3031 value = GetCurrentWorldMatrix();
3035 case Dali::Actor::Property::NAME:
3041 case Dali::Actor::Property::SENSITIVE:
3043 value = IsSensitive();
3047 case Dali::Actor::Property::LEAVE_REQUIRED:
3049 value = GetLeaveRequired();
3053 case Dali::Actor::Property::INHERIT_POSITION:
3055 value = IsPositionInherited();
3059 case Dali::Actor::Property::INHERIT_ORIENTATION:
3061 value = IsOrientationInherited();
3065 case Dali::Actor::Property::INHERIT_SCALE:
3067 value = IsScaleInherited();
3071 case Dali::Actor::Property::COLOR_MODE:
3073 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3077 case Dali::Actor::Property::POSITION_INHERITANCE:
3079 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3083 case Dali::Actor::Property::DRAW_MODE:
3085 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3089 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3091 value = GetSizeModeFactor();
3095 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3097 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3101 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3103 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3107 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3109 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3113 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3115 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3119 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3121 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3125 case Dali::Actor::Property::PADDING:
3127 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3128 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3129 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3133 case Dali::Actor::Property::MINIMUM_SIZE:
3135 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3139 case Dali::Actor::Property::MAXIMUM_SIZE:
3141 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3147 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3155 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3160 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3162 // This method should only return an object connected to the scene-graph
3163 return OnStage() ? mNode : NULL;
3166 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3168 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3170 const PropertyBase* property( NULL );
3172 // This method should only return a property of an object connected to the scene-graph
3178 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3180 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3181 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3183 property = animatable->GetSceneGraphProperty();
3185 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3187 CustomPropertyMetadata* custom = FindCustomProperty( index );
3188 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3190 property = custom->GetSceneGraphProperty();
3192 else if( NULL != mNode )
3196 case Dali::Actor::Property::SIZE:
3197 property = &mNode->mSize;
3200 case Dali::Actor::Property::SIZE_WIDTH:
3201 property = &mNode->mSize;
3204 case Dali::Actor::Property::SIZE_HEIGHT:
3205 property = &mNode->mSize;
3208 case Dali::Actor::Property::SIZE_DEPTH:
3209 property = &mNode->mSize;
3212 case Dali::Actor::Property::POSITION:
3213 property = &mNode->mPosition;
3216 case Dali::Actor::Property::POSITION_X:
3217 property = &mNode->mPosition;
3220 case Dali::Actor::Property::POSITION_Y:
3221 property = &mNode->mPosition;
3224 case Dali::Actor::Property::POSITION_Z:
3225 property = &mNode->mPosition;
3228 case Dali::Actor::Property::ORIENTATION:
3229 property = &mNode->mOrientation;
3232 case Dali::Actor::Property::SCALE:
3233 property = &mNode->mScale;
3236 case Dali::Actor::Property::SCALE_X:
3237 property = &mNode->mScale;
3240 case Dali::Actor::Property::SCALE_Y:
3241 property = &mNode->mScale;
3244 case Dali::Actor::Property::SCALE_Z:
3245 property = &mNode->mScale;
3248 case Dali::Actor::Property::VISIBLE:
3249 property = &mNode->mVisible;
3252 case Dali::Actor::Property::COLOR:
3253 property = &mNode->mColor;
3256 case Dali::Actor::Property::COLOR_RED:
3257 property = &mNode->mColor;
3260 case Dali::Actor::Property::COLOR_GREEN:
3261 property = &mNode->mColor;
3264 case Dali::Actor::Property::COLOR_BLUE:
3265 property = &mNode->mColor;
3268 case Dali::Actor::Property::COLOR_ALPHA:
3269 property = &mNode->mColor;
3280 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3282 const PropertyInputImpl* property( NULL );
3284 // This method should only return a property of an object connected to the scene-graph
3290 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3292 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3293 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3295 property = animatable->GetSceneGraphProperty();
3297 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3299 CustomPropertyMetadata* custom = FindCustomProperty( index );
3300 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3301 property = custom->GetSceneGraphProperty();
3303 else if( NULL != mNode )
3307 case Dali::Actor::Property::PARENT_ORIGIN:
3308 property = &mNode->mParentOrigin;
3311 case Dali::Actor::Property::PARENT_ORIGIN_X:
3312 property = &mNode->mParentOrigin;
3315 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3316 property = &mNode->mParentOrigin;
3319 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3320 property = &mNode->mParentOrigin;
3323 case Dali::Actor::Property::ANCHOR_POINT:
3324 property = &mNode->mAnchorPoint;
3327 case Dali::Actor::Property::ANCHOR_POINT_X:
3328 property = &mNode->mAnchorPoint;
3331 case Dali::Actor::Property::ANCHOR_POINT_Y:
3332 property = &mNode->mAnchorPoint;
3335 case Dali::Actor::Property::ANCHOR_POINT_Z:
3336 property = &mNode->mAnchorPoint;
3339 case Dali::Actor::Property::SIZE:
3340 property = &mNode->mSize;
3343 case Dali::Actor::Property::SIZE_WIDTH:
3344 property = &mNode->mSize;
3347 case Dali::Actor::Property::SIZE_HEIGHT:
3348 property = &mNode->mSize;
3351 case Dali::Actor::Property::SIZE_DEPTH:
3352 property = &mNode->mSize;
3355 case Dali::Actor::Property::POSITION:
3356 property = &mNode->mPosition;
3359 case Dali::Actor::Property::POSITION_X:
3360 property = &mNode->mPosition;
3363 case Dali::Actor::Property::POSITION_Y:
3364 property = &mNode->mPosition;
3367 case Dali::Actor::Property::POSITION_Z:
3368 property = &mNode->mPosition;
3371 case Dali::Actor::Property::WORLD_POSITION:
3372 property = &mNode->mWorldPosition;
3375 case Dali::Actor::Property::WORLD_POSITION_X:
3376 property = &mNode->mWorldPosition;
3379 case Dali::Actor::Property::WORLD_POSITION_Y:
3380 property = &mNode->mWorldPosition;
3383 case Dali::Actor::Property::WORLD_POSITION_Z:
3384 property = &mNode->mWorldPosition;
3387 case Dali::Actor::Property::ORIENTATION:
3388 property = &mNode->mOrientation;
3391 case Dali::Actor::Property::WORLD_ORIENTATION:
3392 property = &mNode->mWorldOrientation;
3395 case Dali::Actor::Property::SCALE:
3396 property = &mNode->mScale;
3399 case Dali::Actor::Property::SCALE_X:
3400 property = &mNode->mScale;
3403 case Dali::Actor::Property::SCALE_Y:
3404 property = &mNode->mScale;
3407 case Dali::Actor::Property::SCALE_Z:
3408 property = &mNode->mScale;
3411 case Dali::Actor::Property::WORLD_SCALE:
3412 property = &mNode->mWorldScale;
3415 case Dali::Actor::Property::VISIBLE:
3416 property = &mNode->mVisible;
3419 case Dali::Actor::Property::COLOR:
3420 property = &mNode->mColor;
3423 case Dali::Actor::Property::COLOR_RED:
3424 property = &mNode->mColor;
3427 case Dali::Actor::Property::COLOR_GREEN:
3428 property = &mNode->mColor;
3431 case Dali::Actor::Property::COLOR_BLUE:
3432 property = &mNode->mColor;
3435 case Dali::Actor::Property::COLOR_ALPHA:
3436 property = &mNode->mColor;
3439 case Dali::Actor::Property::WORLD_COLOR:
3440 property = &mNode->mWorldColor;
3443 case Dali::Actor::Property::WORLD_MATRIX:
3444 property = &mNode->mWorldMatrix;
3455 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3457 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3459 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3461 // check whether the animatable property is registered already, if not then register one.
3462 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3463 if( animatableProperty )
3465 componentIndex = animatableProperty->componentIndex;
3472 case Dali::Actor::Property::PARENT_ORIGIN_X:
3473 case Dali::Actor::Property::ANCHOR_POINT_X:
3474 case Dali::Actor::Property::SIZE_WIDTH:
3475 case Dali::Actor::Property::POSITION_X:
3476 case Dali::Actor::Property::WORLD_POSITION_X:
3477 case Dali::Actor::Property::SCALE_X:
3478 case Dali::Actor::Property::COLOR_RED:
3484 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3485 case Dali::Actor::Property::ANCHOR_POINT_Y:
3486 case Dali::Actor::Property::SIZE_HEIGHT:
3487 case Dali::Actor::Property::POSITION_Y:
3488 case Dali::Actor::Property::WORLD_POSITION_Y:
3489 case Dali::Actor::Property::SCALE_Y:
3490 case Dali::Actor::Property::COLOR_GREEN:
3496 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3497 case Dali::Actor::Property::ANCHOR_POINT_Z:
3498 case Dali::Actor::Property::SIZE_DEPTH:
3499 case Dali::Actor::Property::POSITION_Z:
3500 case Dali::Actor::Property::WORLD_POSITION_Z:
3501 case Dali::Actor::Property::SCALE_Z:
3502 case Dali::Actor::Property::COLOR_BLUE:
3508 case Dali::Actor::Property::COLOR_ALPHA:
3522 return componentIndex;
3525 void Actor::SetParent( Actor* parent )
3529 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3533 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3536 // Instruct each actor to create a corresponding node in the scene graph
3537 ConnectToStage( parent->GetHierarchyDepth() );
3540 // Resolve the name and index for the child properties if any
3541 ResolveChildProperties();
3543 else // parent being set to NULL
3545 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3549 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3552 DALI_ASSERT_ALWAYS( mNode != NULL );
3556 // Disconnect the Node & its children from the scene-graph.
3557 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3560 // Instruct each actor to discard pointers to the scene-graph
3561 DisconnectFromStage();
3566 SceneGraph::Node* Actor::CreateNode() const
3571 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3574 Actor* actor = dynamic_cast< Actor* >( object );
3578 if( 0 == actionName.compare( ACTION_SHOW ) )
3580 actor->SetVisible( true );
3583 else if( 0 == actionName.compare( ACTION_HIDE ) )
3585 actor->SetVisible( false );
3593 void Actor::EnsureRelayoutData()
3595 // Assign relayout data.
3596 if( !mRelayoutData )
3598 mRelayoutData = new RelayoutData();
3602 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3604 // Check if actor is dependent on parent
3605 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3607 if( ( dimension & ( 1 << i ) ) )
3609 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3610 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3620 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3622 // Check if actor is dependent on children
3623 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3625 if( ( dimension & ( 1 << i ) ) )
3627 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3628 switch( resizePolicy )
3630 case ResizePolicy::FIT_TO_CHILDREN:
3631 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3647 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3649 return Actor::RelayoutDependentOnChildren( dimension );
3652 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3654 // Check each possible dimension and see if it is dependent on the input one
3655 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3657 if( dimension & ( 1 << i ) )
3659 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3666 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3668 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3670 if( dimension & ( 1 << i ) )
3672 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3677 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3679 // If more than one dimension is requested, just return the first one found
3680 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3682 if( ( dimension & ( 1 << i ) ) )
3684 return mRelayoutData->negotiatedDimensions[ i ];
3688 return 0.0f; // Default
3691 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3693 EnsureRelayoutData();
3695 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3697 if( dimension & ( 1 << i ) )
3699 mRelayoutData->dimensionPadding[ i ] = padding;
3704 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3706 if ( mRelayoutData )
3708 // If more than one dimension is requested, just return the first one found
3709 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3711 if( ( dimension & ( 1 << i ) ) )
3713 return mRelayoutData->dimensionPadding[ i ];
3718 return GetDefaultDimensionPadding();
3721 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3723 EnsureRelayoutData();
3725 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3727 if( dimension & ( 1 << i ) )
3729 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3734 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3736 if ( mRelayoutData )
3738 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3740 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3750 float Actor::GetHeightForWidthBase( float width )
3752 float height = 0.0f;
3754 const Vector3 naturalSize = GetNaturalSize();
3755 if( naturalSize.width > 0.0f )
3757 height = naturalSize.height * width / naturalSize.width;
3759 else // we treat 0 as 1:1 aspect ratio
3767 float Actor::GetWidthForHeightBase( float height )
3771 const Vector3 naturalSize = GetNaturalSize();
3772 if( naturalSize.height > 0.0f )
3774 width = naturalSize.width * height / naturalSize.height;
3776 else // we treat 0 as 1:1 aspect ratio
3784 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3786 // Fill to parent, taking size mode factor into account
3787 switch( child.GetResizePolicy( dimension ) )
3789 case ResizePolicy::FILL_TO_PARENT:
3791 return GetLatestSize( dimension );
3794 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3796 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3799 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3801 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3806 return GetLatestSize( dimension );
3811 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3813 // Can be overridden in derived class
3814 return CalculateChildSizeBase( child, dimension );
3817 float Actor::GetHeightForWidth( float width )
3819 // Can be overridden in derived class
3820 return GetHeightForWidthBase( width );
3823 float Actor::GetWidthForHeight( float height )
3825 // Can be overridden in derived class
3826 return GetWidthForHeightBase( height );
3829 float Actor::GetLatestSize( Dimension::Type dimension ) const
3831 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3834 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3836 Vector2 padding = GetPadding( dimension );
3838 return GetLatestSize( dimension ) + padding.x + padding.y;
3841 float Actor::NegotiateFromParent( Dimension::Type dimension )
3843 Actor* parent = GetParent();
3846 Vector2 padding( GetPadding( dimension ) );
3847 Vector2 parentPadding( parent->GetPadding( dimension ) );
3848 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3854 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3856 float maxDimensionPoint = 0.0f;
3858 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3860 ActorPtr child = GetChildAt( i );
3862 if( !child->RelayoutDependentOnParent( dimension ) )
3864 // Calculate the min and max points that the children range across
3865 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3866 float dimensionSize = child->GetRelayoutSize( dimension );
3867 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3871 return maxDimensionPoint;
3874 float Actor::GetSize( Dimension::Type dimension ) const
3876 return GetDimensionValue( GetTargetSize(), dimension );
3879 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3881 return GetDimensionValue( GetNaturalSize(), dimension );
3884 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3886 switch( GetResizePolicy( dimension ) )
3888 case ResizePolicy::USE_NATURAL_SIZE:
3890 return GetNaturalSize( dimension );
3893 case ResizePolicy::FIXED:
3895 return GetDimensionValue( GetPreferredSize(), dimension );
3898 case ResizePolicy::USE_ASSIGNED_SIZE:
3900 return GetDimensionValue( maximumSize, dimension );
3903 case ResizePolicy::FILL_TO_PARENT:
3904 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3905 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3907 return NegotiateFromParent( dimension );
3910 case ResizePolicy::FIT_TO_CHILDREN:
3912 return NegotiateFromChildren( dimension );
3915 case ResizePolicy::DIMENSION_DEPENDENCY:
3917 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3920 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3922 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3925 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3927 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3939 return 0.0f; // Default
3942 float Actor::ClampDimension( float size, Dimension::Type dimension )
3944 const float minSize = GetMinimumSize( dimension );
3945 const float maxSize = GetMaximumSize( dimension );
3947 return std::max( minSize, std::min( size, maxSize ) );
3950 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
3952 // Check if it needs to be negotiated
3953 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
3955 // Check that we havn't gotten into an infinite loop
3956 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
3957 bool recursionFound = false;
3958 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
3960 if( *it == searchActor )
3962 recursionFound = true;
3967 if( !recursionFound )
3969 // Record the path that we have taken
3970 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
3972 // Dimension dependency check
3973 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3975 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
3977 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
3979 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
3983 // Parent dependency check
3984 Actor* parent = GetParent();
3985 if( parent && RelayoutDependentOnParent( dimension ) )
3987 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
3990 // Children dependency check
3991 if( RelayoutDependentOnChildren( dimension ) )
3993 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3995 ActorPtr child = GetChildAt( i );
3997 // Only relayout child first if it is not dependent on this actor
3998 if( !child->RelayoutDependentOnParent( dimension ) )
4000 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4005 // For deriving classes
4006 OnCalculateRelayoutSize( dimension );
4008 // All dependencies checked, calculate the size and set negotiated flag
4009 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4011 SetNegotiatedDimension( newSize, dimension );
4012 SetLayoutNegotiated( true, dimension );
4014 // For deriving classes
4015 OnLayoutNegotiated( newSize, dimension );
4017 // This actor has been successfully processed, pop it off the recursion stack
4018 recursionStack.pop_back();
4022 // TODO: Break infinite loop
4023 SetLayoutNegotiated( true, dimension );
4028 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4030 // Negotiate all dimensions that require it
4031 ActorDimensionStack recursionStack;
4033 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4035 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4038 NegotiateDimension( dimension, allocatedSize, recursionStack );
4042 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4044 switch( mRelayoutData->sizeSetPolicy )
4046 case SizeScalePolicy::USE_SIZE_SET:
4051 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4053 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4054 const Vector3 naturalSize = GetNaturalSize();
4055 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4057 const float sizeRatio = size.width / size.height;
4058 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4060 if( naturalSizeRatio < sizeRatio )
4062 return Vector2( naturalSizeRatio * size.height, size.height );
4064 else if( naturalSizeRatio > sizeRatio )
4066 return Vector2( size.width, size.width / naturalSizeRatio );
4077 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4079 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4080 const Vector3 naturalSize = GetNaturalSize();
4081 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4083 const float sizeRatio = size.width / size.height;
4084 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4086 if( naturalSizeRatio < sizeRatio )
4088 return Vector2( size.width, size.width / naturalSizeRatio );
4090 else if( naturalSizeRatio > sizeRatio )
4092 return Vector2( naturalSizeRatio * size.height, size.height );
4111 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4113 // Do the set actor size
4114 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4116 // Adjust for size set policy
4117 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4119 // Lock the flag to stop recursive relayouts on set size
4120 mRelayoutData->insideRelayout = true;
4121 SetSize( negotiatedSize );
4122 mRelayoutData->insideRelayout = false;
4124 // Clear flags for all dimensions
4125 SetLayoutDirty( false );
4127 // Give deriving classes a chance to respond
4128 OnRelayout( negotiatedSize, container );
4130 if( !mOnRelayoutSignal.Empty() )
4132 Dali::Actor handle( this );
4133 mOnRelayoutSignal.Emit( handle );
4137 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4139 // Force a size negotiation for actors that has assigned size during relayout
4140 // This is required as otherwise the flags that force a relayout will not
4141 // necessarilly be set. This will occur if the actor has already been laid out.
4142 // The dirty flags are then cleared. Then if the actor is added back into the
4143 // relayout container afterwards, the dirty flags would still be clear...
4144 // causing a relayout to be skipped. Here we force any actors added to the
4145 // container to be relayed out.
4146 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4148 SetLayoutNegotiated(false, Dimension::WIDTH);
4150 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4152 SetLayoutNegotiated(false, Dimension::HEIGHT);
4155 // Do the negotiation
4156 NegotiateDimensions( allocatedSize );
4158 // Set the actor size
4159 SetNegotiatedSize( container );
4161 // Negotiate down to children
4162 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4164 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4166 ActorPtr child = GetChildAt( i );
4168 // Forces children that have already been laid out to be relayed out
4169 // if they have assigned size during relayout.
4170 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4172 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4173 child->SetLayoutDirty(true, Dimension::WIDTH);
4175 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4177 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4178 child->SetLayoutDirty(true, Dimension::HEIGHT);
4181 // Only relayout if required
4182 if( child->RelayoutRequired() )
4184 container.Add( Dali::Actor( child.Get() ), newBounds );
4189 void Actor::RelayoutRequest( Dimension::Type dimension )
4191 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4192 if( relayoutController )
4194 Dali::Actor self( this );
4195 relayoutController->RequestRelayout( self, dimension );
4199 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4203 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4207 void Actor::SetPreferredSize( const Vector2& size )
4209 EnsureRelayoutData();
4211 if( size.width > 0.0f )
4213 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4216 if( size.height > 0.0f )
4218 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4221 mRelayoutData->preferredSize = size;
4226 Vector2 Actor::GetPreferredSize() const
4228 if ( mRelayoutData )
4230 return Vector2( mRelayoutData->preferredSize );
4233 return GetDefaultPreferredSize();
4236 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4238 EnsureRelayoutData();
4240 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4242 if( dimension & ( 1 << i ) )
4244 mRelayoutData->minimumSize[ i ] = size;
4251 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4253 if ( mRelayoutData )
4255 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4257 if( dimension & ( 1 << i ) )
4259 return mRelayoutData->minimumSize[ i ];
4264 return 0.0f; // Default
4267 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4269 EnsureRelayoutData();
4271 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4273 if( dimension & ( 1 << i ) )
4275 mRelayoutData->maximumSize[ i ] = size;
4282 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4284 if ( mRelayoutData )
4286 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4288 if( dimension & ( 1 << i ) )
4290 return mRelayoutData->maximumSize[ i ];
4295 return FLT_MAX; // Default
4298 Object* Actor::GetParentObject() const
4303 } // namespace Internal