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>
27 #include <dali/public-api/common/dali-common.h>
28 #include <dali/public-api/common/constants.h>
29 #include <dali/public-api/events/touch-data.h>
30 #include <dali/public-api/math/vector2.h>
31 #include <dali/public-api/math/vector3.h>
32 #include <dali/public-api/math/radian.h>
33 #include <dali/public-api/object/type-registry.h>
34 #include <dali/devel-api/scripting/scripting.h>
35 #include <dali/internal/common/internal-constants.h>
36 #include <dali/internal/event/common/event-thread-services.h>
37 #include <dali/internal/event/render-tasks/render-task-impl.h>
38 #include <dali/internal/event/actors/camera-actor-impl.h>
39 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
40 #include <dali/internal/event/common/property-helper.h>
41 #include <dali/internal/event/common/stage-impl.h>
42 #include <dali/internal/event/common/type-info-impl.h>
43 #include <dali/internal/event/animation/constraint-impl.h>
44 #include <dali/internal/event/common/projection.h>
45 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
46 #include <dali/internal/update/common/animatable-property.h>
47 #include <dali/internal/update/nodes/node-messages.h>
48 #include <dali/internal/update/nodes/node-declarations.h>
49 #include <dali/internal/update/animation/scene-graph-constraint.h>
50 #include <dali/internal/event/events/actor-gesture-data.h>
51 #include <dali/internal/common/message.h>
52 #include <dali/integration-api/debug.h>
54 using Dali::Internal::SceneGraph::Node;
55 using Dali::Internal::SceneGraph::AnimatableProperty;
56 using Dali::Internal::SceneGraph::PropertyBase;
64 unsigned int Actor::mActorCounter = 0;
68 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
69 inline const Vector3& GetDefaultSizeModeFactor()
74 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
75 inline const Vector2& GetDefaultPreferredSize()
80 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
81 inline const Vector2& GetDefaultDimensionPadding()
86 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
88 } // unnamed namespace
91 * Struct to collect relayout variables
93 struct Actor::RelayoutData
96 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
98 // Set size negotiation defaults
99 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
101 resizePolicies[ i ] = ResizePolicy::DEFAULT;
102 negotiatedDimensions[ i ] = 0.0f;
103 dimensionNegotiated[ i ] = false;
104 dimensionDirty[ i ] = false;
105 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
106 dimensionPadding[ i ] = GetDefaultDimensionPadding();
107 minimumSize[ i ] = 0.0f;
108 maximumSize[ i ] = FLT_MAX;
112 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
114 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
116 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
118 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
120 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
121 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
123 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
124 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
126 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
128 Vector2 preferredSize; ///< The preferred size of the actor
130 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
132 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
133 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
136 namespace // unnamed namespace
142 * We want to discourage the use of property strings (minimize string comparisons),
143 * particularly for the default properties.
144 * Name Type writable animatable constraint-input enum for index-checking
146 DALI_PROPERTY_TABLE_BEGIN
147 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
148 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
149 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
150 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
151 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
152 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
153 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
154 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
155 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
156 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
157 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
158 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
159 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
160 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
161 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
162 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
163 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
164 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
165 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
166 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
167 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
168 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
169 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
170 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
171 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
172 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
173 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
174 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
175 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
176 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
177 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
178 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
179 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
180 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
181 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
182 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
183 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
184 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
185 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
186 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
187 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
188 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
189 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
190 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
191 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
192 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
193 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
194 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
195 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
196 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
197 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
198 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
199 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
200 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
201 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
205 const char* const SIGNAL_TOUCHED = "touched";
206 const char* const SIGNAL_HOVERED = "hovered";
207 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
208 const char* const SIGNAL_ON_STAGE = "onStage";
209 const char* const SIGNAL_OFF_STAGE = "offStage";
210 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
211 const char* const SIGNAL_TOUCH = "touch";
215 const char* const ACTION_SHOW = "show";
216 const char* const ACTION_HIDE = "hide";
218 BaseHandle CreateActor()
220 return Dali::Actor::New();
223 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
225 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
226 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
227 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
228 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
229 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &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 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
294 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
297 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
299 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
301 size_t sizeIgnored = 0;
302 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
304 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
311 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
313 // Values are the same so just use the same table as anchor-point
314 return GetAnchorPointConstant( value, parentOrigin );
318 * @brief Extract a given dimension from a Vector2
320 * @param[in] values The values to extract from
321 * @param[in] dimension The dimension to extract
322 * @return Return the value for the dimension
324 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
328 case Dimension::WIDTH:
332 case Dimension::HEIGHT:
334 return values.height;
345 * @brief Extract a given dimension from a Vector3
347 * @param[in] values The values to extract from
348 * @param[in] dimension The dimension to extract
349 * @return Return the value for the dimension
351 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
353 return GetDimensionValue( values.GetVectorXY(), dimension );
357 } // unnamed namespace
359 ActorPtr Actor::New()
361 ActorPtr actor( new Actor( BASIC ) );
363 // Second-phase construction
369 const std::string& Actor::GetName() const
374 void Actor::SetName( const std::string& name )
380 // ATTENTION: string for debug purposes is not thread safe.
381 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
385 unsigned int Actor::GetId() const
390 bool Actor::OnStage() const
395 Dali::Layer Actor::GetLayer()
399 // Short-circuit for Layer derived actors
402 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
405 // Find the immediate Layer parent
406 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
408 if( parent->IsLayer() )
410 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
417 void Actor::Add( Actor& child )
419 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
420 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
424 mChildren = new ActorContainer;
427 Actor* const oldParent( child.mParent );
429 // child might already be ours
430 if( this != oldParent )
432 // if we already have parent, unparent us first
435 oldParent->Remove( child ); // This causes OnChildRemove callback
437 // Old parent may need to readjust to missing child
438 if( oldParent->RelayoutDependentOnChildren() )
440 oldParent->RelayoutRequest();
444 // Guard against Add() during previous OnChildRemove callback
447 // Do this first, since user callbacks from within SetParent() may need to remove child
448 mChildren->push_back( ActorPtr( &child ) );
450 // SetParent asserts that child can be added
451 child.SetParent( this );
453 // Notification for derived classes
456 // Only put in a relayout request if there is a suitable dependency
457 if( RelayoutDependentOnChildren() )
465 void Actor::Remove( Actor& child )
467 if( (this == &child) || (!mChildren) )
469 // no children or removing itself
475 // Find the child in mChildren, and unparent it
476 ActorIter end = mChildren->end();
477 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
479 ActorPtr actor = (*iter);
481 if( actor.Get() == &child )
483 // Keep handle for OnChildRemove notification
486 // Do this first, since user callbacks from within SetParent() may need to add the child
487 mChildren->erase( iter );
489 DALI_ASSERT_DEBUG( actor->GetParent() == this );
490 actor->SetParent( NULL );
498 // Only put in a relayout request if there is a suitable dependency
499 if( RelayoutDependentOnChildren() )
505 // Notification for derived classes
506 OnChildRemove( child );
509 void Actor::Unparent()
513 // Remove this actor from the parent. The remove will put a relayout request in for
514 // the parent if required
515 mParent->Remove( *this );
516 // mParent is now NULL!
520 unsigned int Actor::GetChildCount() const
522 return ( NULL != mChildren ) ? mChildren->size() : 0;
525 ActorPtr Actor::GetChildAt( unsigned int index ) const
527 DALI_ASSERT_ALWAYS( index < GetChildCount() );
529 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
532 ActorPtr Actor::FindChildByName( const std::string& actorName )
535 if( actorName == mName )
541 ActorIter end = mChildren->end();
542 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
544 child = (*iter)->FindChildByName( actorName );
555 ActorPtr Actor::FindChildById( const unsigned int id )
564 ActorIter end = mChildren->end();
565 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
567 child = (*iter)->FindChildById( id );
578 void Actor::SetParentOrigin( const Vector3& origin )
582 // mNode is being used in a separate thread; queue a message to set the value & base value
583 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
586 // Cache for event-thread access
589 // not allocated, check if different from default
590 if( ParentOrigin::DEFAULT != origin )
592 mParentOrigin = new Vector3( origin );
597 // check if different from current costs more than just set
598 *mParentOrigin = origin;
602 void Actor::SetParentOriginX( float x )
604 const Vector3& current = GetCurrentParentOrigin();
606 SetParentOrigin( Vector3( x, current.y, current.z ) );
609 void Actor::SetParentOriginY( float y )
611 const Vector3& current = GetCurrentParentOrigin();
613 SetParentOrigin( Vector3( current.x, y, current.z ) );
616 void Actor::SetParentOriginZ( float z )
618 const Vector3& current = GetCurrentParentOrigin();
620 SetParentOrigin( Vector3( current.x, current.y, z ) );
623 const Vector3& Actor::GetCurrentParentOrigin() const
625 // Cached for event-thread access
626 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
629 void Actor::SetAnchorPoint( const Vector3& anchor )
633 // mNode is being used in a separate thread; queue a message to set the value & base value
634 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
637 // Cache for event-thread access
640 // not allocated, check if different from default
641 if( AnchorPoint::DEFAULT != anchor )
643 mAnchorPoint = new Vector3( anchor );
648 // check if different from current costs more than just set
649 *mAnchorPoint = anchor;
653 void Actor::SetAnchorPointX( float x )
655 const Vector3& current = GetCurrentAnchorPoint();
657 SetAnchorPoint( Vector3( x, current.y, current.z ) );
660 void Actor::SetAnchorPointY( float y )
662 const Vector3& current = GetCurrentAnchorPoint();
664 SetAnchorPoint( Vector3( current.x, y, current.z ) );
667 void Actor::SetAnchorPointZ( float z )
669 const Vector3& current = GetCurrentAnchorPoint();
671 SetAnchorPoint( Vector3( current.x, current.y, z ) );
674 const Vector3& Actor::GetCurrentAnchorPoint() const
676 // Cached for event-thread access
677 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
680 void Actor::SetPosition( float x, float y )
682 SetPosition( Vector3( x, y, 0.0f ) );
685 void Actor::SetPosition( float x, float y, float z )
687 SetPosition( Vector3( x, y, z ) );
690 void Actor::SetPosition( const Vector3& position )
692 mTargetPosition = position;
696 // mNode is being used in a separate thread; queue a message to set the value & base value
697 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
701 void Actor::SetX( float x )
703 mTargetPosition.x = x;
707 // mNode is being used in a separate thread; queue a message to set the value & base value
708 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
712 void Actor::SetY( float y )
714 mTargetPosition.y = y;
718 // mNode is being used in a separate thread; queue a message to set the value & base value
719 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
723 void Actor::SetZ( float z )
725 mTargetPosition.z = z;
729 // mNode is being used in a separate thread; queue a message to set the value & base value
730 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
734 void Actor::TranslateBy( const Vector3& distance )
736 mTargetPosition += distance;
740 // mNode is being used in a separate thread; queue a message to set the value & base value
741 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
745 const Vector3& Actor::GetCurrentPosition() const
749 // mNode is being used in a separate thread; copy the value from the previous update
750 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
753 return Vector3::ZERO;
756 const Vector3& Actor::GetTargetPosition() const
758 return mTargetPosition;
761 const Vector3& Actor::GetCurrentWorldPosition() const
765 // mNode is being used in a separate thread; copy the value from the previous update
766 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
769 return Vector3::ZERO;
772 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
774 // this flag is not animatable so keep the value
775 mPositionInheritanceMode = mode;
778 // mNode is being used in a separate thread; queue a message to set the value
779 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
783 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
785 // Cached for event-thread access
786 return mPositionInheritanceMode;
789 void Actor::SetInheritPosition( bool inherit )
791 if( mInheritPosition != inherit && NULL != mNode )
793 // non animateable so keep local copy
794 mInheritPosition = inherit;
795 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
799 bool Actor::IsPositionInherited() const
801 return mInheritPosition;
804 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
806 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
807 normalizedAxis.Normalize();
809 Quaternion orientation( angle, normalizedAxis );
811 SetOrientation( orientation );
814 void Actor::SetOrientation( const Quaternion& orientation )
818 // mNode is being used in a separate thread; queue a message to set the value & base value
819 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
823 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
827 // mNode is being used in a separate thread; queue a message to set the value & base value
828 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
832 void Actor::RotateBy( const Quaternion& relativeRotation )
836 // mNode is being used in a separate thread; queue a message to set the value & base value
837 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
841 const Quaternion& Actor::GetCurrentOrientation() const
845 // mNode is being used in a separate thread; copy the value from the previous update
846 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
849 return Quaternion::IDENTITY;
852 const Quaternion& Actor::GetCurrentWorldOrientation() const
856 // mNode is being used in a separate thread; copy the value from the previous update
857 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
860 return Quaternion::IDENTITY;
863 void Actor::SetScale( float scale )
865 SetScale( Vector3( scale, scale, scale ) );
868 void Actor::SetScale( float x, float y, float z )
870 SetScale( Vector3( x, y, z ) );
873 void Actor::SetScale( const Vector3& scale )
877 // mNode is being used in a separate thread; queue a message to set the value & base value
878 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
882 void Actor::SetScaleX( float x )
886 // mNode is being used in a separate thread; queue a message to set the value & base value
887 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
891 void Actor::SetScaleY( float y )
895 // mNode is being used in a separate thread; queue a message to set the value & base value
896 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
900 void Actor::SetScaleZ( float z )
904 // mNode is being used in a separate thread; queue a message to set the value & base value
905 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
909 void Actor::ScaleBy(const Vector3& relativeScale)
913 // mNode is being used in a separate thread; queue a message to set the value & base value
914 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
918 const Vector3& Actor::GetCurrentScale() const
922 // mNode is being used in a separate thread; copy the value from the previous update
923 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
929 const Vector3& Actor::GetCurrentWorldScale() const
933 // mNode is being used in a separate thread; copy the value from the previous update
934 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
940 void Actor::SetInheritScale( bool inherit )
943 if( mInheritScale != inherit && NULL != mNode )
945 // non animateable so keep local copy
946 mInheritScale = inherit;
947 // mNode is being used in a separate thread; queue a message to set the value
948 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
952 bool Actor::IsScaleInherited() const
954 return mInheritScale;
957 Matrix Actor::GetCurrentWorldMatrix() const
961 return mNode->GetWorldMatrix(0);
964 return Matrix::IDENTITY;
967 void Actor::SetVisible( bool visible )
971 // mNode is being used in a separate thread; queue a message to set the value & base value
972 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
976 bool Actor::IsVisible() const
980 // mNode is being used in a separate thread; copy the value from the previous update
981 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
987 void Actor::SetOpacity( float opacity )
991 // mNode is being used in a separate thread; queue a message to set the value & base value
992 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
996 float Actor::GetCurrentOpacity() const
1000 // mNode is being used in a separate thread; copy the value from the previous update
1001 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1007 ClippingMode::Type Actor::GetClippingMode() const
1009 return mClippingMode;
1012 const Vector4& Actor::GetCurrentWorldColor() const
1016 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1019 return Color::WHITE;
1022 void Actor::SetColor( const Vector4& color )
1026 // mNode is being used in a separate thread; queue a message to set the value & base value
1027 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1031 void Actor::SetColorRed( float red )
1035 // mNode is being used in a separate thread; queue a message to set the value & base value
1036 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1040 void Actor::SetColorGreen( float green )
1044 // mNode is being used in a separate thread; queue a message to set the value & base value
1045 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1049 void Actor::SetColorBlue( float blue )
1053 // mNode is being used in a separate thread; queue a message to set the value & base value
1054 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1058 const Vector4& Actor::GetCurrentColor() const
1062 // mNode is being used in a separate thread; copy the value from the previous update
1063 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1066 return Color::WHITE;
1069 void Actor::SetInheritOrientation( bool inherit )
1071 if( mInheritOrientation != inherit && NULL != mNode)
1073 // non animateable so keep local copy
1074 mInheritOrientation = inherit;
1075 // mNode is being used in a separate thread; queue a message to set the value
1076 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1080 bool Actor::IsOrientationInherited() const
1082 return mInheritOrientation;
1085 void Actor::SetSizeModeFactor( const Vector3& factor )
1087 EnsureRelayoutData();
1089 mRelayoutData->sizeModeFactor = factor;
1092 const Vector3& Actor::GetSizeModeFactor() const
1094 if ( mRelayoutData )
1096 return mRelayoutData->sizeModeFactor;
1099 return GetDefaultSizeModeFactor();
1102 void Actor::SetColorMode( ColorMode colorMode )
1104 // non animateable so keep local copy
1105 mColorMode = colorMode;
1108 // mNode is being used in a separate thread; queue a message to set the value
1109 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1113 ColorMode Actor::GetColorMode() const
1115 // we have cached copy
1119 void Actor::SetSize( float width, float height )
1121 SetSize( Vector2( width, height ) );
1124 void Actor::SetSize( float width, float height, float depth )
1126 SetSize( Vector3( width, height, depth ) );
1129 void Actor::SetSize( const Vector2& size )
1131 SetSize( Vector3( size.width, size.height, 0.f ) );
1134 void Actor::SetSizeInternal( const Vector2& size )
1136 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1139 void Actor::SetSize( const Vector3& size )
1141 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1143 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1144 SetPreferredSize( size.GetVectorXY() );
1148 SetSizeInternal( size );
1152 void Actor::SetSizeInternal( const Vector3& size )
1154 // dont allow recursive loop
1155 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1156 // 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
1157 if( ( NULL != mNode )&&
1158 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1159 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1160 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1164 // mNode is being used in a separate thread; queue a message to set the value & base value
1165 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1167 // Notification for derived classes
1168 mInsideOnSizeSet = true;
1169 OnSizeSet( mTargetSize );
1170 mInsideOnSizeSet = false;
1172 // Raise a relayout request if the flag is not locked
1173 if( mRelayoutData && !mRelayoutData->insideRelayout )
1180 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1182 mTargetSize = targetSize;
1184 // Notify deriving classes
1185 OnSizeAnimation( animation, mTargetSize );
1188 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1190 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1192 mTargetSize.width = targetSize;
1194 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1196 mTargetSize.height = targetSize;
1198 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1200 mTargetSize.depth = targetSize;
1202 // Notify deriving classes
1203 OnSizeAnimation( animation, mTargetSize );
1206 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1208 mTargetPosition = targetPosition;
1211 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1213 if ( Dali::Actor::Property::POSITION_X == property )
1215 mTargetPosition.x = targetPosition;
1217 else if ( Dali::Actor::Property::POSITION_Y == property )
1219 mTargetPosition.y = targetPosition;
1221 else if ( Dali::Actor::Property::POSITION_Z == property )
1223 mTargetPosition.z = targetPosition;
1227 void Actor::SetWidth( float width )
1229 mTargetSize.width = width;
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>::BakeX, width );
1238 void Actor::SetHeight( float height )
1240 mTargetSize.height = height;
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>::BakeY, height );
1249 void Actor::SetDepth( float depth )
1251 mTargetSize.depth = depth;
1255 // mNode is being used in a separate thread; queue a message to set the value & base value
1256 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1260 const Vector3& Actor::GetTargetSize() const
1265 const Vector3& Actor::GetCurrentSize() const
1269 // mNode is being used in a separate thread; copy the value from the previous update
1270 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1273 return Vector3::ZERO;
1276 Vector3 Actor::GetNaturalSize() const
1278 // It is up to deriving classes to return the appropriate natural size
1279 return Vector3( 0.0f, 0.0f, 0.0f );
1282 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1284 EnsureRelayoutData();
1286 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1288 if( dimension & ( 1 << i ) )
1290 mRelayoutData->resizePolicies[ i ] = policy;
1294 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1296 if( dimension & Dimension::WIDTH )
1298 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1301 if( dimension & Dimension::HEIGHT )
1303 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1307 // If calling SetResizePolicy, assume we want relayout enabled
1308 SetRelayoutEnabled( true );
1310 OnSetResizePolicy( policy, dimension );
1312 // Trigger relayout on this control
1316 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1318 if ( mRelayoutData )
1320 // If more than one dimension is requested, just return the first one found
1321 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1323 if( ( dimension & ( 1 << i ) ) )
1325 return mRelayoutData->resizePolicies[ i ];
1330 return ResizePolicy::DEFAULT;
1333 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1335 EnsureRelayoutData();
1337 mRelayoutData->sizeSetPolicy = policy;
1340 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1342 if ( mRelayoutData )
1344 return mRelayoutData->sizeSetPolicy;
1347 return DEFAULT_SIZE_SCALE_POLICY;
1350 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1352 EnsureRelayoutData();
1354 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1356 if( dimension & ( 1 << i ) )
1358 mRelayoutData->dimensionDependencies[ i ] = dependency;
1363 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1365 if ( mRelayoutData )
1367 // If more than one dimension is requested, just return the first one found
1368 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1370 if( ( dimension & ( 1 << i ) ) )
1372 return mRelayoutData->dimensionDependencies[ i ];
1377 return Dimension::ALL_DIMENSIONS; // Default
1380 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1382 // If relayout data has not been allocated yet and the client is requesting
1383 // to disable it, do nothing
1384 if( mRelayoutData || relayoutEnabled )
1386 EnsureRelayoutData();
1388 mRelayoutData->relayoutEnabled = relayoutEnabled;
1392 bool Actor::IsRelayoutEnabled() const
1394 // Assume that if relayout data has not been allocated yet then
1395 // relayout is disabled
1396 return mRelayoutData && mRelayoutData->relayoutEnabled;
1399 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1401 EnsureRelayoutData();
1403 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1405 if( dimension & ( 1 << i ) )
1407 mRelayoutData->dimensionDirty[ i ] = dirty;
1412 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1414 if ( mRelayoutData )
1416 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1418 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1428 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1430 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1433 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1435 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1438 unsigned int Actor::AddRenderer( Renderer& renderer )
1442 mRenderers = new RendererContainer;
1445 unsigned int index = mRenderers->size();
1446 RendererPtr rendererPtr = RendererPtr( &renderer );
1447 mRenderers->push_back( rendererPtr );
1448 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1452 rendererPtr->Connect();
1458 unsigned int Actor::GetRendererCount() const
1460 unsigned int rendererCount(0);
1463 rendererCount = mRenderers->size();
1466 return rendererCount;
1469 RendererPtr Actor::GetRendererAt( unsigned int index )
1471 RendererPtr renderer;
1472 if( index < GetRendererCount() )
1474 renderer = ( *mRenderers )[ index ];
1480 void Actor::RemoveRenderer( Renderer& renderer )
1484 RendererIter end = mRenderers->end();
1485 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1487 if( (*iter).Get() == &renderer )
1489 mRenderers->erase( iter );
1490 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1497 void Actor::RemoveRenderer( unsigned int index )
1499 if( index < GetRendererCount() )
1501 RendererPtr renderer = ( *mRenderers )[ index ];
1502 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1503 mRenderers->erase( mRenderers->begin()+index );
1507 bool Actor::IsOverlay() const
1509 return ( DrawMode::OVERLAY_2D == mDrawMode );
1512 void Actor::SetDrawMode( DrawMode::Type drawMode )
1514 // this flag is not animatable so keep the value
1515 mDrawMode = drawMode;
1516 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1518 // mNode is being used in a separate thread; queue a message to set the value
1519 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1523 DrawMode::Type Actor::GetDrawMode() const
1528 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1530 // only valid when on-stage
1531 StagePtr stage = Stage::GetCurrent();
1532 if( stage && OnStage() )
1534 const RenderTaskList& taskList = stage->GetRenderTaskList();
1536 Vector2 converted( screenX, screenY );
1538 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1539 const int taskCount = taskList.GetTaskCount();
1540 for( int i = taskCount - 1; i >= 0; --i )
1542 Dali::RenderTask task = taskList.GetTask( i );
1543 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1545 // found a task where this conversion was ok so return
1553 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1555 bool retval = false;
1556 // only valid when on-stage
1559 CameraActor* camera = renderTask.GetCameraActor();
1563 renderTask.GetViewport( viewport );
1565 // need to translate coordinates to render tasks coordinate space
1566 Vector2 converted( screenX, screenY );
1567 if( renderTask.TranslateCoordinates( converted ) )
1569 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1576 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1578 // Early-out if mNode is NULL
1584 // Get the ModelView matrix
1586 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1588 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1589 Matrix invertedMvp( false/*don't init*/);
1590 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1591 bool success = invertedMvp.Invert();
1593 // Convert to GL coordinates
1594 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1599 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1606 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1612 if( XyPlaneIntersect( nearPos, farPos, local ) )
1614 Vector3 size = GetCurrentSize();
1615 localX = local.x + size.x * 0.5f;
1616 localY = local.y + size.y * 0.5f;
1627 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1630 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1632 Mathematical Formulation
1634 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1636 ( p - c ) dot ( p - c ) = r^2
1638 Given a ray with a point of origin 'o', and a direction vector 'd':
1640 ray(t) = o + td, t >= 0
1642 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1644 (o + td - c ) dot ( o + td - c ) = r^2
1646 To solve for t we first expand the above into a more recognisable quadratic equation form
1648 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1657 B = 2( o - c ) dot d
1658 C = ( o - c ) dot ( o - c ) - r^2
1660 which can be solved using a standard quadratic formula.
1662 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1664 Practical Simplification
1666 In a renderer, we often differentiate between world space and object space. In the object space
1667 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1668 into object space, the mathematical solution presented above can be simplified significantly.
1670 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1674 and we can find the t at which the (transformed) ray intersects the sphere by
1676 ( o + td ) dot ( o + td ) = r^2
1678 According to the reasoning above, we expand the above quadratic equation into the general form
1682 which now has coefficients:
1689 // Early out if mNode is NULL
1695 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1697 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1698 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1699 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1701 // Compute the radius is not needed, square radius it's enough.
1702 const Vector3& size( mNode->GetSize( bufferIndex ) );
1704 // Scale the sphere.
1705 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1707 const float width = size.width * scale.width;
1708 const float height = size.height * scale.height;
1710 float squareSphereRadius = 0.5f * ( width * width + height * height );
1712 float a = rayDir.Dot( rayDir ); // a
1713 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1714 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1716 return ( b2 * b2 - a * c ) >= 0.f;
1719 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1723 if( OnStage() && NULL != mNode )
1725 // Transforms the ray to the local reference system.
1726 // Calculate the inverse of Model matrix
1727 Matrix invModelMatrix( false/*don't init*/);
1729 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1730 invModelMatrix = mNode->GetWorldMatrix(0);
1731 invModelMatrix.Invert();
1733 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1734 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1736 // Test with the actor's XY plane (Normal = 0 0 1 1).
1738 float a = -rayOriginLocal.z;
1739 float b = rayDirLocal.z;
1741 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1743 // Ray travels distance * rayDirLocal to intersect with plane.
1746 const Vector3& size = mNode->GetSize( bufferIndex );
1748 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1749 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1751 // Test with the actor's geometry.
1752 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1759 void Actor::SetLeaveRequired( bool required )
1761 mLeaveRequired = required;
1764 bool Actor::GetLeaveRequired() const
1766 return mLeaveRequired;
1769 void Actor::SetKeyboardFocusable( bool focusable )
1771 mKeyboardFocusable = focusable;
1774 bool Actor::IsKeyboardFocusable() const
1776 return mKeyboardFocusable;
1779 bool Actor::GetTouchRequired() const
1781 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1784 bool Actor::GetHoverRequired() const
1786 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1789 bool Actor::GetWheelEventRequired() const
1791 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1794 bool Actor::IsHittable() const
1796 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1799 ActorGestureData& Actor::GetGestureData()
1801 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1802 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1803 if( NULL == mGestureData )
1805 mGestureData = new ActorGestureData;
1807 return *mGestureData;
1810 bool Actor::IsGestureRequred( Gesture::Type type ) const
1812 return mGestureData && mGestureData->IsGestureRequred( type );
1815 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1817 bool consumed = false;
1819 if( !mTouchSignal.Empty() )
1821 Dali::Actor handle( this );
1822 consumed = mTouchSignal.Emit( handle, touch );
1825 if( !mTouchedSignal.Empty() )
1827 Dali::Actor handle( this );
1828 consumed |= mTouchedSignal.Emit( handle, event );
1833 // Notification for derived classes
1834 consumed = OnTouchEvent( event ); // TODO
1840 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1842 bool consumed = false;
1844 if( !mHoveredSignal.Empty() )
1846 Dali::Actor handle( this );
1847 consumed = mHoveredSignal.Emit( handle, event );
1852 // Notification for derived classes
1853 consumed = OnHoverEvent( event );
1859 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1861 bool consumed = false;
1863 if( !mWheelEventSignal.Empty() )
1865 Dali::Actor handle( this );
1866 consumed = mWheelEventSignal.Emit( handle, event );
1871 // Notification for derived classes
1872 consumed = OnWheelEvent( event );
1878 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1880 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1881 return mTouchedSignal;
1884 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1886 return mTouchSignal;
1889 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1891 return mHoveredSignal;
1894 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1896 return mWheelEventSignal;
1899 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1901 return mOnStageSignal;
1904 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1906 return mOffStageSignal;
1909 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1911 return mOnRelayoutSignal;
1914 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1916 bool connected( true );
1917 Actor* actor = dynamic_cast< Actor* >( object );
1919 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1921 actor->TouchedSignal().Connect( tracker, functor );
1923 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1925 actor->HoveredSignal().Connect( tracker, functor );
1927 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1929 actor->WheelEventSignal().Connect( tracker, functor );
1931 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1933 actor->OnStageSignal().Connect( tracker, functor );
1935 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1937 actor->OffStageSignal().Connect( tracker, functor );
1939 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1941 actor->OnRelayoutSignal().Connect( tracker, functor );
1943 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1945 actor->TouchSignal().Connect( tracker, functor );
1949 // signalName does not match any signal
1956 Actor::Actor( DerivedType derivedType )
1961 mParentOrigin( NULL ),
1962 mAnchorPoint( NULL ),
1963 mRelayoutData( NULL ),
1964 mGestureData( NULL ),
1965 mTargetSize( 0.0f, 0.0f, 0.0f ),
1967 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1969 mIsRoot( ROOT_LAYER == derivedType ),
1970 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1971 mIsOnStage( false ),
1973 mLeaveRequired( false ),
1974 mKeyboardFocusable( false ),
1975 mDerivedRequiresTouch( false ),
1976 mDerivedRequiresHover( false ),
1977 mDerivedRequiresWheelEvent( false ),
1978 mOnStageSignalled( false ),
1979 mInsideOnSizeSet( false ),
1980 mInheritPosition( true ),
1981 mInheritOrientation( true ),
1982 mInheritScale( true ),
1983 mDrawMode( DrawMode::NORMAL ),
1984 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1985 mColorMode( Node::DEFAULT_COLOR_MODE ),
1986 mClippingMode( ClippingMode::DISABLED )
1990 void Actor::Initialize()
1993 SceneGraph::Node* node = CreateNode();
1995 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
1996 mNode = node; // Keep raw-pointer to Node
2000 GetEventThreadServices().RegisterObject( this );
2005 // Remove mParent pointers from children even if we're destroying core,
2006 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2009 ActorConstIter endIter = mChildren->end();
2010 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2012 (*iter)->SetParent( NULL );
2018 // Guard to allow handle destruction after Core has been destroyed
2019 if( EventThreadServices::IsCoreRunning() )
2023 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2024 mNode = NULL; // Node is about to be destroyed
2027 GetEventThreadServices().UnregisterObject( this );
2030 // Cleanup optional gesture data
2031 delete mGestureData;
2033 // Cleanup optional parent origin and anchor
2034 delete mParentOrigin;
2035 delete mAnchorPoint;
2037 // Delete optional relayout data
2040 delete mRelayoutData;
2044 void Actor::ConnectToStage( unsigned int parentDepth )
2046 // This container is used instead of walking the Actor hierarchy.
2047 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2048 ActorContainer connectionList;
2050 // This stage is atomic i.e. not interrupted by user callbacks.
2051 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2053 // Notify applications about the newly connected actors.
2054 const ActorIter endIter = connectionList.end();
2055 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2057 (*iter)->NotifyStageConnection();
2063 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2065 DALI_ASSERT_ALWAYS( !OnStage() );
2070 ConnectToSceneGraph();
2072 // Notification for internal derived classes
2073 OnStageConnectionInternal();
2075 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2076 connectionList.push_back( ActorPtr( this ) );
2078 // Recursively connect children
2081 ActorConstIter endIter = mChildren->end();
2082 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2084 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2090 * This method is called when the Actor is connected to the Stage.
2091 * The parent must have added its Node to the scene-graph.
2092 * The child must connect its Node to the parent's Node.
2093 * This is recursive; the child calls ConnectToStage() for its children.
2095 void Actor::ConnectToSceneGraph()
2097 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2101 // Reparent Node in next Update
2102 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2105 unsigned int rendererCount( GetRendererCount() );
2106 for( unsigned int i(0); i<rendererCount; ++i )
2108 GetRendererAt(i)->Connect();
2111 // Request relayout on all actors that are added to the scenegraph
2114 // Notification for Object::Observers
2118 void Actor::NotifyStageConnection()
2120 // Actors can be removed (in a callback), before the on-stage stage is reported.
2121 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2122 if( OnStage() && !mOnStageSignalled )
2124 // Notification for external (CustomActor) derived classes
2125 OnStageConnectionExternal( mDepth );
2127 if( !mOnStageSignal.Empty() )
2129 Dali::Actor handle( this );
2130 mOnStageSignal.Emit( handle );
2133 // Guard against Remove during callbacks
2136 mOnStageSignalled = true; // signal required next time Actor is removed
2141 void Actor::DisconnectFromStage()
2143 // This container is used instead of walking the Actor hierachy.
2144 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2145 ActorContainer disconnectionList;
2147 // This stage is atomic i.e. not interrupted by user callbacks
2148 RecursiveDisconnectFromStage( disconnectionList );
2150 // Notify applications about the newly disconnected actors.
2151 const ActorIter endIter = disconnectionList.end();
2152 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2154 (*iter)->NotifyStageDisconnection();
2158 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2160 DALI_ASSERT_ALWAYS( OnStage() );
2162 // Recursively disconnect children
2165 ActorConstIter endIter = mChildren->end();
2166 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2168 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2172 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2173 disconnectionList.push_back( ActorPtr( this ) );
2175 // Notification for internal derived classes
2176 OnStageDisconnectionInternal();
2178 DisconnectFromSceneGraph();
2184 * This method is called by an actor or its parent, before a node removal message is sent.
2185 * This is recursive; the child calls DisconnectFromStage() for its children.
2187 void Actor::DisconnectFromSceneGraph()
2189 // Notification for Object::Observers
2190 OnSceneObjectRemove();
2192 unsigned int rendererCount( GetRendererCount() );
2193 for( unsigned int i(0); i<rendererCount; ++i )
2195 GetRendererAt(i)->Disconnect();
2199 void Actor::NotifyStageDisconnection()
2201 // Actors can be added (in a callback), before the off-stage state is reported.
2202 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2203 // only do this step if there is a stage, i.e. Core is not being shut down
2204 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2206 // Notification for external (CustomeActor) derived classes
2207 OnStageDisconnectionExternal();
2209 if( !mOffStageSignal.Empty() )
2211 Dali::Actor handle( this );
2212 mOffStageSignal.Emit( handle );
2215 // Guard against Add during callbacks
2218 mOnStageSignalled = false; // signal required next time Actor is added
2223 bool Actor::IsNodeConnected() const
2225 bool connected( false );
2227 if( OnStage() && ( NULL != mNode ) )
2229 if( IsRoot() || mNode->GetParent() )
2238 unsigned int Actor::GetDefaultPropertyCount() const
2240 return DEFAULT_PROPERTY_COUNT;
2243 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2245 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2247 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2249 indices.PushBack( i );
2253 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2255 if( index < DEFAULT_PROPERTY_COUNT )
2257 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2263 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2265 Property::Index index = Property::INVALID_INDEX;
2267 // Look for name in default properties
2268 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2270 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2271 if( 0 == name.compare( property->name ) )
2281 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2283 if( index < DEFAULT_PROPERTY_COUNT )
2285 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2291 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2293 if( index < DEFAULT_PROPERTY_COUNT )
2295 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2301 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2303 if( index < DEFAULT_PROPERTY_COUNT )
2305 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2311 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2313 if( index < DEFAULT_PROPERTY_COUNT )
2315 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2318 // index out of range...return Property::NONE
2319 return Property::NONE;
2322 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2326 case Dali::Actor::Property::PARENT_ORIGIN:
2328 Property::Type type = property.GetType();
2329 if( type == Property::VECTOR3 )
2331 SetParentOrigin( property.Get< Vector3 >() );
2333 else if ( type == Property::STRING )
2335 std::string parentOriginString;
2336 property.Get( parentOriginString );
2337 Vector3 parentOrigin;
2338 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2340 SetParentOrigin( parentOrigin );
2346 case Dali::Actor::Property::PARENT_ORIGIN_X:
2348 SetParentOriginX( property.Get< float >() );
2352 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2354 SetParentOriginY( property.Get< float >() );
2358 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2360 SetParentOriginZ( property.Get< float >() );
2364 case Dali::Actor::Property::ANCHOR_POINT:
2366 Property::Type type = property.GetType();
2367 if( type == Property::VECTOR3 )
2369 SetAnchorPoint( property.Get< Vector3 >() );
2371 else if ( type == Property::STRING )
2373 std::string anchorPointString;
2374 property.Get( anchorPointString );
2376 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2378 SetAnchorPoint( anchor );
2384 case Dali::Actor::Property::ANCHOR_POINT_X:
2386 SetAnchorPointX( property.Get< float >() );
2390 case Dali::Actor::Property::ANCHOR_POINT_Y:
2392 SetAnchorPointY( property.Get< float >() );
2396 case Dali::Actor::Property::ANCHOR_POINT_Z:
2398 SetAnchorPointZ( property.Get< float >() );
2402 case Dali::Actor::Property::SIZE:
2404 SetSize( property.Get< Vector3 >() );
2408 case Dali::Actor::Property::SIZE_WIDTH:
2410 SetWidth( property.Get< float >() );
2414 case Dali::Actor::Property::SIZE_HEIGHT:
2416 SetHeight( property.Get< float >() );
2420 case Dali::Actor::Property::SIZE_DEPTH:
2422 SetDepth( property.Get< float >() );
2426 case Dali::Actor::Property::POSITION:
2428 SetPosition( property.Get< Vector3 >() );
2432 case Dali::Actor::Property::POSITION_X:
2434 SetX( property.Get< float >() );
2438 case Dali::Actor::Property::POSITION_Y:
2440 SetY( property.Get< float >() );
2444 case Dali::Actor::Property::POSITION_Z:
2446 SetZ( property.Get< float >() );
2450 case Dali::Actor::Property::ORIENTATION:
2452 SetOrientation( property.Get< Quaternion >() );
2456 case Dali::Actor::Property::SCALE:
2458 SetScale( property.Get< Vector3 >() );
2462 case Dali::Actor::Property::SCALE_X:
2464 SetScaleX( property.Get< float >() );
2468 case Dali::Actor::Property::SCALE_Y:
2470 SetScaleY( property.Get< float >() );
2474 case Dali::Actor::Property::SCALE_Z:
2476 SetScaleZ( property.Get< float >() );
2480 case Dali::Actor::Property::VISIBLE:
2482 SetVisible( property.Get< bool >() );
2486 case Dali::Actor::Property::COLOR:
2488 SetColor( property.Get< Vector4 >() );
2492 case Dali::Actor::Property::COLOR_RED:
2494 SetColorRed( property.Get< float >() );
2498 case Dali::Actor::Property::COLOR_GREEN:
2500 SetColorGreen( property.Get< float >() );
2504 case Dali::Actor::Property::COLOR_BLUE:
2506 SetColorBlue( property.Get< float >() );
2510 case Dali::Actor::Property::COLOR_ALPHA:
2512 SetOpacity( property.Get< float >() );
2516 case Dali::Actor::Property::NAME:
2518 SetName( property.Get< std::string >() );
2522 case Dali::Actor::Property::SENSITIVE:
2524 SetSensitive( property.Get< bool >() );
2528 case Dali::Actor::Property::LEAVE_REQUIRED:
2530 SetLeaveRequired( property.Get< bool >() );
2534 case Dali::Actor::Property::INHERIT_POSITION:
2536 SetInheritPosition( property.Get< bool >() );
2540 case Dali::Actor::Property::INHERIT_ORIENTATION:
2542 SetInheritOrientation( property.Get< bool >() );
2546 case Dali::Actor::Property::INHERIT_SCALE:
2548 SetInheritScale( property.Get< bool >() );
2552 case Dali::Actor::Property::COLOR_MODE:
2555 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2557 SetColorMode( mode );
2562 case Dali::Actor::Property::POSITION_INHERITANCE:
2564 PositionInheritanceMode mode;
2565 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2567 SetPositionInheritanceMode( mode );
2572 case Dali::Actor::Property::DRAW_MODE:
2574 DrawMode::Type mode;
2575 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2577 SetDrawMode( mode );
2582 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2584 SetSizeModeFactor( property.Get< Vector3 >() );
2588 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2590 ResizePolicy::Type type;
2591 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2593 SetResizePolicy( type, Dimension::WIDTH );
2598 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2600 ResizePolicy::Type type;
2601 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2603 SetResizePolicy( type, Dimension::HEIGHT );
2608 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2610 SizeScalePolicy::Type type;
2611 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2613 SetSizeScalePolicy( type );
2618 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2620 if( property.Get< bool >() )
2622 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2627 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2629 if( property.Get< bool >() )
2631 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2636 case Dali::Actor::Property::PADDING:
2638 Vector4 padding = property.Get< Vector4 >();
2639 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2640 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2644 case Dali::Actor::Property::MINIMUM_SIZE:
2646 Vector2 size = property.Get< Vector2 >();
2647 SetMinimumSize( size.x, Dimension::WIDTH );
2648 SetMinimumSize( size.y, Dimension::HEIGHT );
2652 case Dali::Actor::Property::MAXIMUM_SIZE:
2654 Vector2 size = property.Get< Vector2 >();
2655 SetMaximumSize( size.x, Dimension::WIDTH );
2656 SetMaximumSize( size.y, Dimension::HEIGHT );
2660 case Dali::Actor::Property::CLIPPING_MODE:
2662 ClippingMode::Type convertedValue = mClippingMode;
2663 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2665 mClippingMode = convertedValue;
2668 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2676 // this can happen in the case of a non-animatable default property so just do nothing
2682 // TODO: This method needs to be removed
2683 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2685 switch( entry.GetType() )
2687 case Property::BOOLEAN:
2689 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2690 DALI_ASSERT_DEBUG( NULL != property );
2692 // property is being used in a separate thread; queue a message to set the property
2693 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2698 case Property::INTEGER:
2700 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2701 DALI_ASSERT_DEBUG( NULL != property );
2703 // property is being used in a separate thread; queue a message to set the property
2704 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2709 case Property::FLOAT:
2711 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2712 DALI_ASSERT_DEBUG( NULL != property );
2714 // property is being used in a separate thread; queue a message to set the property
2715 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2720 case Property::VECTOR2:
2722 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2723 DALI_ASSERT_DEBUG( NULL != property );
2725 // property is being used in a separate thread; queue a message to set the property
2726 if(entry.componentIndex == 0)
2728 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2730 else if(entry.componentIndex == 1)
2732 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2736 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2742 case Property::VECTOR3:
2744 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2745 DALI_ASSERT_DEBUG( NULL != property );
2747 // property is being used in a separate thread; queue a message to set the property
2748 if(entry.componentIndex == 0)
2750 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2752 else if(entry.componentIndex == 1)
2754 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2756 else if(entry.componentIndex == 2)
2758 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2762 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2768 case Property::VECTOR4:
2770 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2771 DALI_ASSERT_DEBUG( NULL != property );
2773 // property is being used in a separate thread; queue a message to set the property
2774 if(entry.componentIndex == 0)
2776 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2778 else if(entry.componentIndex == 1)
2780 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2782 else if(entry.componentIndex == 2)
2784 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2786 else if(entry.componentIndex == 3)
2788 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2792 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2798 case Property::ROTATION:
2800 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2801 DALI_ASSERT_DEBUG( NULL != property );
2803 // property is being used in a separate thread; queue a message to set the property
2804 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2809 case Property::MATRIX:
2811 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2812 DALI_ASSERT_DEBUG( NULL != property );
2814 // property is being used in a separate thread; queue a message to set the property
2815 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2820 case Property::MATRIX3:
2822 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2823 DALI_ASSERT_DEBUG( NULL != property );
2825 // property is being used in a separate thread; queue a message to set the property
2826 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2833 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2839 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2841 Property::Value value;
2845 case Dali::Actor::Property::PARENT_ORIGIN:
2847 value = GetCurrentParentOrigin();
2851 case Dali::Actor::Property::PARENT_ORIGIN_X:
2853 value = GetCurrentParentOrigin().x;
2857 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2859 value = GetCurrentParentOrigin().y;
2863 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2865 value = GetCurrentParentOrigin().z;
2869 case Dali::Actor::Property::ANCHOR_POINT:
2871 value = GetCurrentAnchorPoint();
2875 case Dali::Actor::Property::ANCHOR_POINT_X:
2877 value = GetCurrentAnchorPoint().x;
2881 case Dali::Actor::Property::ANCHOR_POINT_Y:
2883 value = GetCurrentAnchorPoint().y;
2887 case Dali::Actor::Property::ANCHOR_POINT_Z:
2889 value = GetCurrentAnchorPoint().z;
2893 case Dali::Actor::Property::SIZE:
2895 value = GetTargetSize();
2899 case Dali::Actor::Property::SIZE_WIDTH:
2901 value = GetTargetSize().width;
2905 case Dali::Actor::Property::SIZE_HEIGHT:
2907 value = GetTargetSize().height;
2911 case Dali::Actor::Property::SIZE_DEPTH:
2913 value = GetTargetSize().depth;
2917 case Dali::Actor::Property::POSITION:
2919 value = GetTargetPosition();
2923 case Dali::Actor::Property::POSITION_X:
2925 value = GetTargetPosition().x;
2929 case Dali::Actor::Property::POSITION_Y:
2931 value = GetTargetPosition().y;
2935 case Dali::Actor::Property::POSITION_Z:
2937 value = GetTargetPosition().z;
2941 case Dali::Actor::Property::WORLD_POSITION:
2943 value = GetCurrentWorldPosition();
2947 case Dali::Actor::Property::WORLD_POSITION_X:
2949 value = GetCurrentWorldPosition().x;
2953 case Dali::Actor::Property::WORLD_POSITION_Y:
2955 value = GetCurrentWorldPosition().y;
2959 case Dali::Actor::Property::WORLD_POSITION_Z:
2961 value = GetCurrentWorldPosition().z;
2965 case Dali::Actor::Property::ORIENTATION:
2967 value = GetCurrentOrientation();
2971 case Dali::Actor::Property::WORLD_ORIENTATION:
2973 value = GetCurrentWorldOrientation();
2977 case Dali::Actor::Property::SCALE:
2979 value = GetCurrentScale();
2983 case Dali::Actor::Property::SCALE_X:
2985 value = GetCurrentScale().x;
2989 case Dali::Actor::Property::SCALE_Y:
2991 value = GetCurrentScale().y;
2995 case Dali::Actor::Property::SCALE_Z:
2997 value = GetCurrentScale().z;
3001 case Dali::Actor::Property::WORLD_SCALE:
3003 value = GetCurrentWorldScale();
3007 case Dali::Actor::Property::VISIBLE:
3009 value = IsVisible();
3013 case Dali::Actor::Property::COLOR:
3015 value = GetCurrentColor();
3019 case Dali::Actor::Property::COLOR_RED:
3021 value = GetCurrentColor().r;
3025 case Dali::Actor::Property::COLOR_GREEN:
3027 value = GetCurrentColor().g;
3031 case Dali::Actor::Property::COLOR_BLUE:
3033 value = GetCurrentColor().b;
3037 case Dali::Actor::Property::COLOR_ALPHA:
3039 value = GetCurrentColor().a;
3043 case Dali::Actor::Property::WORLD_COLOR:
3045 value = GetCurrentWorldColor();
3049 case Dali::Actor::Property::WORLD_MATRIX:
3051 value = GetCurrentWorldMatrix();
3055 case Dali::Actor::Property::NAME:
3061 case Dali::Actor::Property::SENSITIVE:
3063 value = IsSensitive();
3067 case Dali::Actor::Property::LEAVE_REQUIRED:
3069 value = GetLeaveRequired();
3073 case Dali::Actor::Property::INHERIT_POSITION:
3075 value = IsPositionInherited();
3079 case Dali::Actor::Property::INHERIT_ORIENTATION:
3081 value = IsOrientationInherited();
3085 case Dali::Actor::Property::INHERIT_SCALE:
3087 value = IsScaleInherited();
3091 case Dali::Actor::Property::COLOR_MODE:
3093 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3097 case Dali::Actor::Property::POSITION_INHERITANCE:
3099 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3103 case Dali::Actor::Property::DRAW_MODE:
3105 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3109 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3111 value = GetSizeModeFactor();
3115 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3117 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3121 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3123 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3127 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3129 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3133 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3135 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3139 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3141 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3145 case Dali::Actor::Property::PADDING:
3147 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3148 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3149 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3153 case Dali::Actor::Property::MINIMUM_SIZE:
3155 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3159 case Dali::Actor::Property::MAXIMUM_SIZE:
3161 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3165 case Dali::Actor::Property::CLIPPING_MODE:
3167 value = mClippingMode;
3173 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3181 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3186 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3188 // This method should only return an object connected to the scene-graph
3189 return OnStage() ? mNode : NULL;
3192 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3194 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3196 const PropertyBase* property( NULL );
3198 // This method should only return a property of an object connected to the scene-graph
3204 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3206 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3207 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3209 property = animatable->GetSceneGraphProperty();
3211 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3212 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3214 CustomPropertyMetadata* custom = FindCustomProperty( index );
3215 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3217 property = custom->GetSceneGraphProperty();
3219 else if( NULL != mNode )
3223 case Dali::Actor::Property::SIZE:
3224 property = &mNode->mSize;
3227 case Dali::Actor::Property::SIZE_WIDTH:
3228 property = &mNode->mSize;
3231 case Dali::Actor::Property::SIZE_HEIGHT:
3232 property = &mNode->mSize;
3235 case Dali::Actor::Property::SIZE_DEPTH:
3236 property = &mNode->mSize;
3239 case Dali::Actor::Property::POSITION:
3240 property = &mNode->mPosition;
3243 case Dali::Actor::Property::POSITION_X:
3244 property = &mNode->mPosition;
3247 case Dali::Actor::Property::POSITION_Y:
3248 property = &mNode->mPosition;
3251 case Dali::Actor::Property::POSITION_Z:
3252 property = &mNode->mPosition;
3255 case Dali::Actor::Property::ORIENTATION:
3256 property = &mNode->mOrientation;
3259 case Dali::Actor::Property::SCALE:
3260 property = &mNode->mScale;
3263 case Dali::Actor::Property::SCALE_X:
3264 property = &mNode->mScale;
3267 case Dali::Actor::Property::SCALE_Y:
3268 property = &mNode->mScale;
3271 case Dali::Actor::Property::SCALE_Z:
3272 property = &mNode->mScale;
3275 case Dali::Actor::Property::VISIBLE:
3276 property = &mNode->mVisible;
3279 case Dali::Actor::Property::COLOR:
3280 property = &mNode->mColor;
3283 case Dali::Actor::Property::COLOR_RED:
3284 property = &mNode->mColor;
3287 case Dali::Actor::Property::COLOR_GREEN:
3288 property = &mNode->mColor;
3291 case Dali::Actor::Property::COLOR_BLUE:
3292 property = &mNode->mColor;
3295 case Dali::Actor::Property::COLOR_ALPHA:
3296 property = &mNode->mColor;
3307 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3309 const PropertyInputImpl* property( NULL );
3311 // This method should only return a property of an object connected to the scene-graph
3317 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3319 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3320 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3322 property = animatable->GetSceneGraphProperty();
3324 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3325 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3327 CustomPropertyMetadata* custom = FindCustomProperty( index );
3328 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3329 property = custom->GetSceneGraphProperty();
3331 else if( NULL != mNode )
3335 case Dali::Actor::Property::PARENT_ORIGIN:
3336 property = &mNode->mParentOrigin;
3339 case Dali::Actor::Property::PARENT_ORIGIN_X:
3340 property = &mNode->mParentOrigin;
3343 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3344 property = &mNode->mParentOrigin;
3347 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3348 property = &mNode->mParentOrigin;
3351 case Dali::Actor::Property::ANCHOR_POINT:
3352 property = &mNode->mAnchorPoint;
3355 case Dali::Actor::Property::ANCHOR_POINT_X:
3356 property = &mNode->mAnchorPoint;
3359 case Dali::Actor::Property::ANCHOR_POINT_Y:
3360 property = &mNode->mAnchorPoint;
3363 case Dali::Actor::Property::ANCHOR_POINT_Z:
3364 property = &mNode->mAnchorPoint;
3367 case Dali::Actor::Property::SIZE:
3368 property = &mNode->mSize;
3371 case Dali::Actor::Property::SIZE_WIDTH:
3372 property = &mNode->mSize;
3375 case Dali::Actor::Property::SIZE_HEIGHT:
3376 property = &mNode->mSize;
3379 case Dali::Actor::Property::SIZE_DEPTH:
3380 property = &mNode->mSize;
3383 case Dali::Actor::Property::POSITION:
3384 property = &mNode->mPosition;
3387 case Dali::Actor::Property::POSITION_X:
3388 property = &mNode->mPosition;
3391 case Dali::Actor::Property::POSITION_Y:
3392 property = &mNode->mPosition;
3395 case Dali::Actor::Property::POSITION_Z:
3396 property = &mNode->mPosition;
3399 case Dali::Actor::Property::WORLD_POSITION:
3400 property = &mNode->mWorldPosition;
3403 case Dali::Actor::Property::WORLD_POSITION_X:
3404 property = &mNode->mWorldPosition;
3407 case Dali::Actor::Property::WORLD_POSITION_Y:
3408 property = &mNode->mWorldPosition;
3411 case Dali::Actor::Property::WORLD_POSITION_Z:
3412 property = &mNode->mWorldPosition;
3415 case Dali::Actor::Property::ORIENTATION:
3416 property = &mNode->mOrientation;
3419 case Dali::Actor::Property::WORLD_ORIENTATION:
3420 property = &mNode->mWorldOrientation;
3423 case Dali::Actor::Property::SCALE:
3424 property = &mNode->mScale;
3427 case Dali::Actor::Property::SCALE_X:
3428 property = &mNode->mScale;
3431 case Dali::Actor::Property::SCALE_Y:
3432 property = &mNode->mScale;
3435 case Dali::Actor::Property::SCALE_Z:
3436 property = &mNode->mScale;
3439 case Dali::Actor::Property::WORLD_SCALE:
3440 property = &mNode->mWorldScale;
3443 case Dali::Actor::Property::VISIBLE:
3444 property = &mNode->mVisible;
3447 case Dali::Actor::Property::COLOR:
3448 property = &mNode->mColor;
3451 case Dali::Actor::Property::COLOR_RED:
3452 property = &mNode->mColor;
3455 case Dali::Actor::Property::COLOR_GREEN:
3456 property = &mNode->mColor;
3459 case Dali::Actor::Property::COLOR_BLUE:
3460 property = &mNode->mColor;
3463 case Dali::Actor::Property::COLOR_ALPHA:
3464 property = &mNode->mColor;
3467 case Dali::Actor::Property::WORLD_COLOR:
3468 property = &mNode->mWorldColor;
3471 case Dali::Actor::Property::WORLD_MATRIX:
3472 property = &mNode->mWorldMatrix;
3483 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3485 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3487 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3489 // check whether the animatable property is registered already, if not then register one.
3490 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3491 if( animatableProperty )
3493 componentIndex = animatableProperty->componentIndex;
3500 case Dali::Actor::Property::PARENT_ORIGIN_X:
3501 case Dali::Actor::Property::ANCHOR_POINT_X:
3502 case Dali::Actor::Property::SIZE_WIDTH:
3503 case Dali::Actor::Property::POSITION_X:
3504 case Dali::Actor::Property::WORLD_POSITION_X:
3505 case Dali::Actor::Property::SCALE_X:
3506 case Dali::Actor::Property::COLOR_RED:
3512 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3513 case Dali::Actor::Property::ANCHOR_POINT_Y:
3514 case Dali::Actor::Property::SIZE_HEIGHT:
3515 case Dali::Actor::Property::POSITION_Y:
3516 case Dali::Actor::Property::WORLD_POSITION_Y:
3517 case Dali::Actor::Property::SCALE_Y:
3518 case Dali::Actor::Property::COLOR_GREEN:
3524 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3525 case Dali::Actor::Property::ANCHOR_POINT_Z:
3526 case Dali::Actor::Property::SIZE_DEPTH:
3527 case Dali::Actor::Property::POSITION_Z:
3528 case Dali::Actor::Property::WORLD_POSITION_Z:
3529 case Dali::Actor::Property::SCALE_Z:
3530 case Dali::Actor::Property::COLOR_BLUE:
3536 case Dali::Actor::Property::COLOR_ALPHA:
3550 return componentIndex;
3553 void Actor::SetParent( Actor* parent )
3557 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3561 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3564 // Instruct each actor to create a corresponding node in the scene graph
3565 ConnectToStage( parent->GetHierarchyDepth() );
3568 // Resolve the name and index for the child properties if any
3569 ResolveChildProperties();
3571 else // parent being set to NULL
3573 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3577 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3580 DALI_ASSERT_ALWAYS( mNode != NULL );
3584 // Disconnect the Node & its children from the scene-graph.
3585 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3588 // Instruct each actor to discard pointers to the scene-graph
3589 DisconnectFromStage();
3594 SceneGraph::Node* Actor::CreateNode() const
3599 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3602 Actor* actor = dynamic_cast< Actor* >( object );
3606 if( 0 == actionName.compare( ACTION_SHOW ) )
3608 actor->SetVisible( true );
3611 else if( 0 == actionName.compare( ACTION_HIDE ) )
3613 actor->SetVisible( false );
3621 void Actor::EnsureRelayoutData()
3623 // Assign relayout data.
3624 if( !mRelayoutData )
3626 mRelayoutData = new RelayoutData();
3630 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3632 // Check if actor is dependent on parent
3633 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3635 if( ( dimension & ( 1 << i ) ) )
3637 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3638 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3648 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3650 // Check if actor is dependent on children
3651 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3653 if( ( dimension & ( 1 << i ) ) )
3655 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3656 switch( resizePolicy )
3658 case ResizePolicy::FIT_TO_CHILDREN:
3659 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3675 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3677 return Actor::RelayoutDependentOnChildren( dimension );
3680 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3682 // Check each possible dimension and see if it is dependent on the input one
3683 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3685 if( dimension & ( 1 << i ) )
3687 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3694 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3696 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3698 if( dimension & ( 1 << i ) )
3700 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3705 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3707 // If more than one dimension is requested, just return the first one found
3708 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3710 if( ( dimension & ( 1 << i ) ) )
3712 return mRelayoutData->negotiatedDimensions[ i ];
3716 return 0.0f; // Default
3719 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3721 EnsureRelayoutData();
3723 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3725 if( dimension & ( 1 << i ) )
3727 mRelayoutData->dimensionPadding[ i ] = padding;
3732 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3734 if ( mRelayoutData )
3736 // If more than one dimension is requested, just return the first one found
3737 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3739 if( ( dimension & ( 1 << i ) ) )
3741 return mRelayoutData->dimensionPadding[ i ];
3746 return GetDefaultDimensionPadding();
3749 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3751 EnsureRelayoutData();
3753 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3755 if( dimension & ( 1 << i ) )
3757 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3762 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3764 if ( mRelayoutData )
3766 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3768 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3778 float Actor::GetHeightForWidthBase( float width )
3780 float height = 0.0f;
3782 const Vector3 naturalSize = GetNaturalSize();
3783 if( naturalSize.width > 0.0f )
3785 height = naturalSize.height * width / naturalSize.width;
3787 else // we treat 0 as 1:1 aspect ratio
3795 float Actor::GetWidthForHeightBase( float height )
3799 const Vector3 naturalSize = GetNaturalSize();
3800 if( naturalSize.height > 0.0f )
3802 width = naturalSize.width * height / naturalSize.height;
3804 else // we treat 0 as 1:1 aspect ratio
3812 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3814 // Fill to parent, taking size mode factor into account
3815 switch( child.GetResizePolicy( dimension ) )
3817 case ResizePolicy::FILL_TO_PARENT:
3819 return GetLatestSize( dimension );
3822 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3824 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3827 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3829 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3834 return GetLatestSize( dimension );
3839 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3841 // Can be overridden in derived class
3842 return CalculateChildSizeBase( child, dimension );
3845 float Actor::GetHeightForWidth( float width )
3847 // Can be overridden in derived class
3848 return GetHeightForWidthBase( width );
3851 float Actor::GetWidthForHeight( float height )
3853 // Can be overridden in derived class
3854 return GetWidthForHeightBase( height );
3857 float Actor::GetLatestSize( Dimension::Type dimension ) const
3859 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3862 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3864 Vector2 padding = GetPadding( dimension );
3866 return GetLatestSize( dimension ) + padding.x + padding.y;
3869 float Actor::NegotiateFromParent( Dimension::Type dimension )
3871 Actor* parent = GetParent();
3874 Vector2 padding( GetPadding( dimension ) );
3875 Vector2 parentPadding( parent->GetPadding( dimension ) );
3876 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3882 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3884 float maxDimensionPoint = 0.0f;
3886 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3888 ActorPtr child = GetChildAt( i );
3890 if( !child->RelayoutDependentOnParent( dimension ) )
3892 // Calculate the min and max points that the children range across
3893 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3894 float dimensionSize = child->GetRelayoutSize( dimension );
3895 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3899 return maxDimensionPoint;
3902 float Actor::GetSize( Dimension::Type dimension ) const
3904 return GetDimensionValue( GetTargetSize(), dimension );
3907 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3909 return GetDimensionValue( GetNaturalSize(), dimension );
3912 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3914 switch( GetResizePolicy( dimension ) )
3916 case ResizePolicy::USE_NATURAL_SIZE:
3918 return GetNaturalSize( dimension );
3921 case ResizePolicy::FIXED:
3923 return GetDimensionValue( GetPreferredSize(), dimension );
3926 case ResizePolicy::USE_ASSIGNED_SIZE:
3928 return GetDimensionValue( maximumSize, dimension );
3931 case ResizePolicy::FILL_TO_PARENT:
3932 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3933 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3935 return NegotiateFromParent( dimension );
3938 case ResizePolicy::FIT_TO_CHILDREN:
3940 return NegotiateFromChildren( dimension );
3943 case ResizePolicy::DIMENSION_DEPENDENCY:
3945 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3948 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3950 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3953 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3955 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3967 return 0.0f; // Default
3970 float Actor::ClampDimension( float size, Dimension::Type dimension )
3972 const float minSize = GetMinimumSize( dimension );
3973 const float maxSize = GetMaximumSize( dimension );
3975 return std::max( minSize, std::min( size, maxSize ) );
3978 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
3980 // Check if it needs to be negotiated
3981 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
3983 // Check that we havn't gotten into an infinite loop
3984 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
3985 bool recursionFound = false;
3986 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
3988 if( *it == searchActor )
3990 recursionFound = true;
3995 if( !recursionFound )
3997 // Record the path that we have taken
3998 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4000 // Dimension dependency check
4001 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4003 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4005 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4007 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4011 // Parent dependency check
4012 Actor* parent = GetParent();
4013 if( parent && RelayoutDependentOnParent( dimension ) )
4015 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4018 // Children dependency check
4019 if( RelayoutDependentOnChildren( dimension ) )
4021 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4023 ActorPtr child = GetChildAt( i );
4025 // Only relayout child first if it is not dependent on this actor
4026 if( !child->RelayoutDependentOnParent( dimension ) )
4028 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4033 // For deriving classes
4034 OnCalculateRelayoutSize( dimension );
4036 // All dependencies checked, calculate the size and set negotiated flag
4037 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4039 SetNegotiatedDimension( newSize, dimension );
4040 SetLayoutNegotiated( true, dimension );
4042 // For deriving classes
4043 OnLayoutNegotiated( newSize, dimension );
4045 // This actor has been successfully processed, pop it off the recursion stack
4046 recursionStack.pop_back();
4050 // TODO: Break infinite loop
4051 SetLayoutNegotiated( true, dimension );
4056 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4058 // Negotiate all dimensions that require it
4059 ActorDimensionStack recursionStack;
4061 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4063 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4066 NegotiateDimension( dimension, allocatedSize, recursionStack );
4070 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4072 switch( mRelayoutData->sizeSetPolicy )
4074 case SizeScalePolicy::USE_SIZE_SET:
4079 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4081 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4082 const Vector3 naturalSize = GetNaturalSize();
4083 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4085 const float sizeRatio = size.width / size.height;
4086 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4088 if( naturalSizeRatio < sizeRatio )
4090 return Vector2( naturalSizeRatio * size.height, size.height );
4092 else if( naturalSizeRatio > sizeRatio )
4094 return Vector2( size.width, size.width / naturalSizeRatio );
4105 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4107 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4108 const Vector3 naturalSize = GetNaturalSize();
4109 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4111 const float sizeRatio = size.width / size.height;
4112 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4114 if( naturalSizeRatio < sizeRatio )
4116 return Vector2( size.width, size.width / naturalSizeRatio );
4118 else if( naturalSizeRatio > sizeRatio )
4120 return Vector2( naturalSizeRatio * size.height, size.height );
4139 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4141 // Do the set actor size
4142 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4144 // Adjust for size set policy
4145 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4147 // Lock the flag to stop recursive relayouts on set size
4148 mRelayoutData->insideRelayout = true;
4149 SetSize( negotiatedSize );
4150 mRelayoutData->insideRelayout = false;
4152 // Clear flags for all dimensions
4153 SetLayoutDirty( false );
4155 // Give deriving classes a chance to respond
4156 OnRelayout( negotiatedSize, container );
4158 if( !mOnRelayoutSignal.Empty() )
4160 Dali::Actor handle( this );
4161 mOnRelayoutSignal.Emit( handle );
4165 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4167 // Force a size negotiation for actors that has assigned size during relayout
4168 // This is required as otherwise the flags that force a relayout will not
4169 // necessarilly be set. This will occur if the actor has already been laid out.
4170 // The dirty flags are then cleared. Then if the actor is added back into the
4171 // relayout container afterwards, the dirty flags would still be clear...
4172 // causing a relayout to be skipped. Here we force any actors added to the
4173 // container to be relayed out.
4174 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4176 SetLayoutNegotiated(false, Dimension::WIDTH);
4178 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4180 SetLayoutNegotiated(false, Dimension::HEIGHT);
4183 // Do the negotiation
4184 NegotiateDimensions( allocatedSize );
4186 // Set the actor size
4187 SetNegotiatedSize( container );
4189 // Negotiate down to children
4190 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4192 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4194 ActorPtr child = GetChildAt( i );
4196 // Forces children that have already been laid out to be relayed out
4197 // if they have assigned size during relayout.
4198 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4200 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4201 child->SetLayoutDirty(true, Dimension::WIDTH);
4203 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4205 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4206 child->SetLayoutDirty(true, Dimension::HEIGHT);
4209 // Only relayout if required
4210 if( child->RelayoutRequired() )
4212 container.Add( Dali::Actor( child.Get() ), newBounds );
4217 void Actor::RelayoutRequest( Dimension::Type dimension )
4219 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4220 if( relayoutController )
4222 Dali::Actor self( this );
4223 relayoutController->RequestRelayout( self, dimension );
4227 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4231 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4235 void Actor::SetPreferredSize( const Vector2& size )
4237 EnsureRelayoutData();
4239 if( size.width > 0.0f )
4241 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4244 if( size.height > 0.0f )
4246 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4249 mRelayoutData->preferredSize = size;
4254 Vector2 Actor::GetPreferredSize() const
4256 if ( mRelayoutData )
4258 return Vector2( mRelayoutData->preferredSize );
4261 return GetDefaultPreferredSize();
4264 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4266 EnsureRelayoutData();
4268 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4270 if( dimension & ( 1 << i ) )
4272 mRelayoutData->minimumSize[ i ] = size;
4279 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4281 if ( mRelayoutData )
4283 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4285 if( dimension & ( 1 << i ) )
4287 return mRelayoutData->minimumSize[ i ];
4292 return 0.0f; // Default
4295 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4297 EnsureRelayoutData();
4299 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4301 if( dimension & ( 1 << i ) )
4303 mRelayoutData->maximumSize[ i ] = size;
4310 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4312 if ( mRelayoutData )
4314 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4316 if( dimension & ( 1 << i ) )
4318 return mRelayoutData->maximumSize[ i ];
4323 return FLT_MAX; // Default
4326 Object* Actor::GetParentObject() const
4331 } // namespace Internal