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/devel-api/actors/layer-devel.h>
28 #include <dali/devel-api/actors/actor-devel.h>
29 #include <dali/public-api/common/dali-common.h>
30 #include <dali/public-api/common/constants.h>
31 #include <dali/public-api/events/touch-data.h>
32 #include <dali/public-api/math/vector2.h>
33 #include <dali/public-api/math/vector3.h>
34 #include <dali/public-api/math/radian.h>
35 #include <dali/public-api/object/type-registry.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/common/animatable-property.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/nodes/node-declarations.h>
51 #include <dali/internal/update/animation/scene-graph-constraint.h>
52 #include <dali/internal/event/events/actor-gesture-data.h>
53 #include <dali/internal/common/message.h>
54 #include <dali/integration-api/debug.h>
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::PropertyBase;
66 unsigned int Actor::mActorCounter = 0;
70 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
71 inline const Vector3& GetDefaultSizeModeFactor()
76 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
77 inline const Vector2& GetDefaultPreferredSize()
82 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
83 inline const Vector2& GetDefaultDimensionPadding()
88 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
90 } // unnamed namespace
93 * Struct to collect relayout variables
95 struct Actor::RelayoutData
98 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
100 // Set size negotiation defaults
101 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
103 resizePolicies[ i ] = ResizePolicy::DEFAULT;
104 negotiatedDimensions[ i ] = 0.0f;
105 dimensionNegotiated[ i ] = false;
106 dimensionDirty[ i ] = false;
107 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
108 dimensionPadding[ i ] = GetDefaultDimensionPadding();
109 minimumSize[ i ] = 0.0f;
110 maximumSize[ i ] = FLT_MAX;
114 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
116 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
118 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
120 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
122 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
123 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
125 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
126 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
128 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
130 Vector2 preferredSize; ///< The preferred size of the actor
132 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
134 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
135 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
138 namespace // unnamed namespace
144 * We want to discourage the use of property strings (minimize string comparisons),
145 * particularly for the default properties.
146 * Name Type writable animatable constraint-input enum for index-checking
148 DALI_PROPERTY_TABLE_BEGIN
149 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
150 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
151 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
152 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
153 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
154 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
155 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
156 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
157 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
158 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
159 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
160 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
161 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
162 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
163 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
164 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
165 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
166 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
167 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
168 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
169 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
170 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
171 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
172 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
173 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
174 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
175 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
176 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
177 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
178 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
179 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
180 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
181 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
182 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
183 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
184 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
185 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
186 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
187 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
188 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
189 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
190 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
191 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
192 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
193 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
194 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
195 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
196 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
197 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
198 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
199 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
200 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
201 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
202 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
203 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
207 const char* const SIGNAL_TOUCHED = "touched";
208 const char* const SIGNAL_HOVERED = "hovered";
209 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
210 const char* const SIGNAL_ON_STAGE = "onStage";
211 const char* const SIGNAL_OFF_STAGE = "offStage";
212 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
213 const char* const SIGNAL_TOUCH = "touch";
217 const char* const ACTION_SHOW = "show";
218 const char* const ACTION_HIDE = "hide";
220 BaseHandle CreateActor()
222 return Dali::Actor::New();
225 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
227 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
228 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
229 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
232 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
233 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
235 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
236 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
241 const Vector3& value;
244 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
245 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
246 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
252 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
253 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
254 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
256 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
257 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
258 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
259 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
260 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
261 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
263 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
264 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
265 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
266 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
267 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
268 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
270 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
274 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
276 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
285 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
287 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
288 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
289 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
291 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
293 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
296 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
299 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
301 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
303 size_t sizeIgnored = 0;
304 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
306 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
313 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
315 // Values are the same so just use the same table as anchor-point
316 return GetAnchorPointConstant( value, parentOrigin );
320 * @brief Extract a given dimension from a Vector2
322 * @param[in] values The values to extract from
323 * @param[in] dimension The dimension to extract
324 * @return Return the value for the dimension
326 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
330 case Dimension::WIDTH:
334 case Dimension::HEIGHT:
336 return values.height;
347 * @brief Extract a given dimension from a Vector3
349 * @param[in] values The values to extract from
350 * @param[in] dimension The dimension to extract
351 * @return Return the value for the dimension
353 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
355 return GetDimensionValue( values.GetVectorXY(), dimension );
358 unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder )
360 return depth * Dali::DevelLayer::TREE_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
363 } // unnamed namespace
365 ActorPtr Actor::New()
367 ActorPtr actor( new Actor( BASIC ) );
369 // Second-phase construction
375 const std::string& Actor::GetName() const
380 void Actor::SetName( const std::string& name )
386 // ATTENTION: string for debug purposes is not thread safe.
387 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
391 unsigned int Actor::GetId() const
396 bool Actor::OnStage() const
401 Dali::Layer Actor::GetLayer()
405 // Short-circuit for Layer derived actors
408 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
411 // Find the immediate Layer parent
412 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
414 if( parent->IsLayer() )
416 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
423 void Actor::Add( Actor& child )
425 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
426 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
430 mChildren = new ActorContainer;
433 Actor* const oldParent( child.mParent );
435 // child might already be ours
436 if( this != oldParent )
438 // if we already have parent, unparent us first
441 oldParent->Remove( child ); // This causes OnChildRemove callback
443 // Old parent may need to readjust to missing child
444 if( oldParent->RelayoutDependentOnChildren() )
446 oldParent->RelayoutRequest();
450 // Guard against Add() during previous OnChildRemove callback
453 // Do this first, since user callbacks from within SetParent() may need to remove child
454 mChildren->push_back( ActorPtr( &child ) );
456 // SetParent asserts that child can be added
457 child.SetParent( this );
459 // Notification for derived classes
462 // Only put in a relayout request if there is a suitable dependency
463 if( RelayoutDependentOnChildren() )
471 void Actor::Remove( Actor& child )
473 if( (this == &child) || (!mChildren) )
475 // no children or removing itself
481 // Find the child in mChildren, and unparent it
482 ActorIter end = mChildren->end();
483 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
485 ActorPtr actor = (*iter);
487 if( actor.Get() == &child )
489 // Keep handle for OnChildRemove notification
492 // Do this first, since user callbacks from within SetParent() may need to add the child
493 mChildren->erase( iter );
495 DALI_ASSERT_DEBUG( actor->GetParent() == this );
496 actor->SetParent( NULL );
504 // Only put in a relayout request if there is a suitable dependency
505 if( RelayoutDependentOnChildren() )
511 // Notification for derived classes
512 OnChildRemove( child );
515 void Actor::Unparent()
519 // Remove this actor from the parent. The remove will put a relayout request in for
520 // the parent if required
521 mParent->Remove( *this );
522 // mParent is now NULL!
526 unsigned int Actor::GetChildCount() const
528 return ( NULL != mChildren ) ? mChildren->size() : 0;
531 ActorPtr Actor::GetChildAt( unsigned int index ) const
533 DALI_ASSERT_ALWAYS( index < GetChildCount() );
535 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
538 ActorPtr Actor::FindChildByName( const std::string& actorName )
541 if( actorName == mName )
547 ActorIter end = mChildren->end();
548 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
550 child = (*iter)->FindChildByName( actorName );
561 ActorPtr Actor::FindChildById( const unsigned int id )
570 ActorIter end = mChildren->end();
571 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
573 child = (*iter)->FindChildById( id );
584 void Actor::SetParentOrigin( const Vector3& origin )
588 // mNode is being used in a separate thread; queue a message to set the value & base value
589 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
592 // Cache for event-thread access
595 // not allocated, check if different from default
596 if( ParentOrigin::DEFAULT != origin )
598 mParentOrigin = new Vector3( origin );
603 // check if different from current costs more than just set
604 *mParentOrigin = origin;
608 void Actor::SetParentOriginX( float x )
610 const Vector3& current = GetCurrentParentOrigin();
612 SetParentOrigin( Vector3( x, current.y, current.z ) );
615 void Actor::SetParentOriginY( float y )
617 const Vector3& current = GetCurrentParentOrigin();
619 SetParentOrigin( Vector3( current.x, y, current.z ) );
622 void Actor::SetParentOriginZ( float z )
624 const Vector3& current = GetCurrentParentOrigin();
626 SetParentOrigin( Vector3( current.x, current.y, z ) );
629 const Vector3& Actor::GetCurrentParentOrigin() const
631 // Cached for event-thread access
632 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
635 void Actor::SetAnchorPoint( const Vector3& anchor )
639 // mNode is being used in a separate thread; queue a message to set the value & base value
640 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
643 // Cache for event-thread access
646 // not allocated, check if different from default
647 if( AnchorPoint::DEFAULT != anchor )
649 mAnchorPoint = new Vector3( anchor );
654 // check if different from current costs more than just set
655 *mAnchorPoint = anchor;
659 void Actor::SetAnchorPointX( float x )
661 const Vector3& current = GetCurrentAnchorPoint();
663 SetAnchorPoint( Vector3( x, current.y, current.z ) );
666 void Actor::SetAnchorPointY( float y )
668 const Vector3& current = GetCurrentAnchorPoint();
670 SetAnchorPoint( Vector3( current.x, y, current.z ) );
673 void Actor::SetAnchorPointZ( float z )
675 const Vector3& current = GetCurrentAnchorPoint();
677 SetAnchorPoint( Vector3( current.x, current.y, z ) );
680 const Vector3& Actor::GetCurrentAnchorPoint() const
682 // Cached for event-thread access
683 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
686 void Actor::SetPosition( float x, float y )
688 SetPosition( Vector3( x, y, 0.0f ) );
691 void Actor::SetPosition( float x, float y, float z )
693 SetPosition( Vector3( x, y, z ) );
696 void Actor::SetPosition( const Vector3& position )
698 mTargetPosition = position;
702 // mNode is being used in a separate thread; queue a message to set the value & base value
703 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
707 void Actor::SetX( float x )
709 mTargetPosition.x = x;
713 // mNode is being used in a separate thread; queue a message to set the value & base value
714 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
718 void Actor::SetY( float y )
720 mTargetPosition.y = y;
724 // mNode is being used in a separate thread; queue a message to set the value & base value
725 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
729 void Actor::SetZ( float z )
731 mTargetPosition.z = z;
735 // mNode is being used in a separate thread; queue a message to set the value & base value
736 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
740 void Actor::TranslateBy( const Vector3& distance )
742 mTargetPosition += distance;
746 // mNode is being used in a separate thread; queue a message to set the value & base value
747 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
751 const Vector3& Actor::GetCurrentPosition() const
755 // mNode is being used in a separate thread; copy the value from the previous update
756 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
759 return Vector3::ZERO;
762 const Vector3& Actor::GetTargetPosition() const
764 return mTargetPosition;
767 const Vector3& Actor::GetCurrentWorldPosition() const
771 // mNode is being used in a separate thread; copy the value from the previous update
772 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
775 return Vector3::ZERO;
778 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
780 // this flag is not animatable so keep the value
781 mPositionInheritanceMode = mode;
784 // mNode is being used in a separate thread; queue a message to set the value
785 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
789 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
791 // Cached for event-thread access
792 return mPositionInheritanceMode;
795 void Actor::SetInheritPosition( bool inherit )
797 if( mInheritPosition != inherit && NULL != mNode )
799 // non animateable so keep local copy
800 mInheritPosition = inherit;
801 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
805 bool Actor::IsPositionInherited() const
807 return mInheritPosition;
810 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
812 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
813 normalizedAxis.Normalize();
815 Quaternion orientation( angle, normalizedAxis );
817 SetOrientation( orientation );
820 void Actor::SetOrientation( const Quaternion& orientation )
824 // mNode is being used in a separate thread; queue a message to set the value & base value
825 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
829 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
833 // mNode is being used in a separate thread; queue a message to set the value & base value
834 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
838 void Actor::RotateBy( const Quaternion& relativeRotation )
842 // mNode is being used in a separate thread; queue a message to set the value & base value
843 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
847 const Quaternion& Actor::GetCurrentOrientation() const
851 // mNode is being used in a separate thread; copy the value from the previous update
852 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
855 return Quaternion::IDENTITY;
858 const Quaternion& Actor::GetCurrentWorldOrientation() const
862 // mNode is being used in a separate thread; copy the value from the previous update
863 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
866 return Quaternion::IDENTITY;
869 void Actor::SetScale( float scale )
871 SetScale( Vector3( scale, scale, scale ) );
874 void Actor::SetScale( float x, float y, float z )
876 SetScale( Vector3( x, y, z ) );
879 void Actor::SetScale( const Vector3& scale )
883 // mNode is being used in a separate thread; queue a message to set the value & base value
884 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
888 void Actor::SetScaleX( float x )
892 // mNode is being used in a separate thread; queue a message to set the value & base value
893 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
897 void Actor::SetScaleY( float y )
901 // mNode is being used in a separate thread; queue a message to set the value & base value
902 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
906 void Actor::SetScaleZ( float z )
910 // mNode is being used in a separate thread; queue a message to set the value & base value
911 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
915 void Actor::ScaleBy(const Vector3& relativeScale)
919 // mNode is being used in a separate thread; queue a message to set the value & base value
920 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
924 const Vector3& Actor::GetCurrentScale() const
928 // mNode is being used in a separate thread; copy the value from the previous update
929 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
935 const Vector3& Actor::GetCurrentWorldScale() const
939 // mNode is being used in a separate thread; copy the value from the previous update
940 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
946 void Actor::SetInheritScale( bool inherit )
949 if( mInheritScale != inherit && NULL != mNode )
951 // non animateable so keep local copy
952 mInheritScale = inherit;
953 // mNode is being used in a separate thread; queue a message to set the value
954 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
958 bool Actor::IsScaleInherited() const
960 return mInheritScale;
963 Matrix Actor::GetCurrentWorldMatrix() const
967 return mNode->GetWorldMatrix(0);
970 return Matrix::IDENTITY;
973 void Actor::SetVisible( bool visible )
977 // mNode is being used in a separate thread; queue a message to set the value & base value
978 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
982 bool Actor::IsVisible() const
986 // mNode is being used in a separate thread; copy the value from the previous update
987 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
993 void Actor::SetOpacity( float opacity )
997 // mNode is being used in a separate thread; queue a message to set the value & base value
998 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1002 float Actor::GetCurrentOpacity() const
1006 // mNode is being used in a separate thread; copy the value from the previous update
1007 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1013 ClippingMode::Type Actor::GetClippingMode() const
1015 return mClippingMode;
1018 const Vector4& Actor::GetCurrentWorldColor() const
1022 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1025 return Color::WHITE;
1028 void Actor::SetColor( const Vector4& color )
1032 // mNode is being used in a separate thread; queue a message to set the value & base value
1033 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1037 void Actor::SetColorRed( float red )
1041 // mNode is being used in a separate thread; queue a message to set the value & base value
1042 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1046 void Actor::SetColorGreen( float green )
1050 // mNode is being used in a separate thread; queue a message to set the value & base value
1051 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1055 void Actor::SetColorBlue( float blue )
1059 // mNode is being used in a separate thread; queue a message to set the value & base value
1060 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1064 const Vector4& Actor::GetCurrentColor() const
1068 // mNode is being used in a separate thread; copy the value from the previous update
1069 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1072 return Color::WHITE;
1075 void Actor::SetInheritOrientation( bool inherit )
1077 if( mInheritOrientation != inherit && NULL != mNode)
1079 // non animateable so keep local copy
1080 mInheritOrientation = inherit;
1081 // mNode is being used in a separate thread; queue a message to set the value
1082 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1086 bool Actor::IsOrientationInherited() const
1088 return mInheritOrientation;
1091 void Actor::SetSizeModeFactor( const Vector3& factor )
1093 EnsureRelayoutData();
1095 mRelayoutData->sizeModeFactor = factor;
1098 const Vector3& Actor::GetSizeModeFactor() const
1100 if ( mRelayoutData )
1102 return mRelayoutData->sizeModeFactor;
1105 return GetDefaultSizeModeFactor();
1108 void Actor::SetColorMode( ColorMode colorMode )
1110 // non animateable so keep local copy
1111 mColorMode = colorMode;
1114 // mNode is being used in a separate thread; queue a message to set the value
1115 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1119 ColorMode Actor::GetColorMode() const
1121 // we have cached copy
1125 void Actor::SetSize( float width, float height )
1127 SetSize( Vector2( width, height ) );
1130 void Actor::SetSize( float width, float height, float depth )
1132 SetSize( Vector3( width, height, depth ) );
1135 void Actor::SetSize( const Vector2& size )
1137 SetSize( Vector3( size.width, size.height, 0.f ) );
1140 void Actor::SetSizeInternal( const Vector2& size )
1142 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1145 void Actor::SetSize( const Vector3& size )
1147 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1149 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1150 SetPreferredSize( size.GetVectorXY() );
1154 SetSizeInternal( size );
1158 void Actor::SetSizeInternal( const Vector3& size )
1160 // dont allow recursive loop
1161 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1162 // 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
1163 if( ( NULL != mNode )&&
1164 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1165 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1166 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1170 // mNode is being used in a separate thread; queue a message to set the value & base value
1171 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1173 // Notification for derived classes
1174 mInsideOnSizeSet = true;
1175 OnSizeSet( mTargetSize );
1176 mInsideOnSizeSet = false;
1178 // Raise a relayout request if the flag is not locked
1179 if( mRelayoutData && !mRelayoutData->insideRelayout )
1186 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1188 mTargetSize = targetSize;
1190 // Notify deriving classes
1191 OnSizeAnimation( animation, mTargetSize );
1194 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1196 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1198 mTargetSize.width = targetSize;
1200 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1202 mTargetSize.height = targetSize;
1204 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1206 mTargetSize.depth = targetSize;
1208 // Notify deriving classes
1209 OnSizeAnimation( animation, mTargetSize );
1212 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1214 mTargetPosition = targetPosition;
1217 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1219 if ( Dali::Actor::Property::POSITION_X == property )
1221 mTargetPosition.x = targetPosition;
1223 else if ( Dali::Actor::Property::POSITION_Y == property )
1225 mTargetPosition.y = targetPosition;
1227 else if ( Dali::Actor::Property::POSITION_Z == property )
1229 mTargetPosition.z = targetPosition;
1233 void Actor::SetWidth( float width )
1235 mTargetSize.width = width;
1239 // mNode is being used in a separate thread; queue a message to set the value & base value
1240 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1244 void Actor::SetHeight( float height )
1246 mTargetSize.height = height;
1250 // mNode is being used in a separate thread; queue a message to set the value & base value
1251 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1255 void Actor::SetDepth( float depth )
1257 mTargetSize.depth = depth;
1261 // mNode is being used in a separate thread; queue a message to set the value & base value
1262 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1266 const Vector3& Actor::GetTargetSize() const
1271 const Vector3& Actor::GetCurrentSize() const
1275 // mNode is being used in a separate thread; copy the value from the previous update
1276 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1279 return Vector3::ZERO;
1282 Vector3 Actor::GetNaturalSize() const
1284 // It is up to deriving classes to return the appropriate natural size
1285 return Vector3( 0.0f, 0.0f, 0.0f );
1288 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1290 EnsureRelayoutData();
1292 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1294 if( dimension & ( 1 << i ) )
1296 mRelayoutData->resizePolicies[ i ] = policy;
1300 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1302 if( dimension & Dimension::WIDTH )
1304 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1307 if( dimension & Dimension::HEIGHT )
1309 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1313 // If calling SetResizePolicy, assume we want relayout enabled
1314 SetRelayoutEnabled( true );
1316 OnSetResizePolicy( policy, dimension );
1318 // Trigger relayout on this control
1322 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1324 if ( mRelayoutData )
1326 // If more than one dimension is requested, just return the first one found
1327 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1329 if( ( dimension & ( 1 << i ) ) )
1331 return mRelayoutData->resizePolicies[ i ];
1336 return ResizePolicy::DEFAULT;
1339 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1341 EnsureRelayoutData();
1343 mRelayoutData->sizeSetPolicy = policy;
1346 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1348 if ( mRelayoutData )
1350 return mRelayoutData->sizeSetPolicy;
1353 return DEFAULT_SIZE_SCALE_POLICY;
1356 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1358 EnsureRelayoutData();
1360 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1362 if( dimension & ( 1 << i ) )
1364 mRelayoutData->dimensionDependencies[ i ] = dependency;
1369 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1371 if ( mRelayoutData )
1373 // If more than one dimension is requested, just return the first one found
1374 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1376 if( ( dimension & ( 1 << i ) ) )
1378 return mRelayoutData->dimensionDependencies[ i ];
1383 return Dimension::ALL_DIMENSIONS; // Default
1386 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1388 // If relayout data has not been allocated yet and the client is requesting
1389 // to disable it, do nothing
1390 if( mRelayoutData || relayoutEnabled )
1392 EnsureRelayoutData();
1394 mRelayoutData->relayoutEnabled = relayoutEnabled;
1398 bool Actor::IsRelayoutEnabled() const
1400 // Assume that if relayout data has not been allocated yet then
1401 // relayout is disabled
1402 return mRelayoutData && mRelayoutData->relayoutEnabled;
1405 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1407 EnsureRelayoutData();
1409 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1411 if( dimension & ( 1 << i ) )
1413 mRelayoutData->dimensionDirty[ i ] = dirty;
1418 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1420 if ( mRelayoutData )
1422 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1424 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1434 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1436 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1439 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1441 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1444 unsigned int Actor::AddRenderer( Renderer& renderer )
1448 mRenderers = new RendererContainer;
1451 unsigned int index = mRenderers->size();
1452 RendererPtr rendererPtr = RendererPtr( &renderer );
1453 mRenderers->push_back( rendererPtr );
1454 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1458 rendererPtr->Connect();
1464 unsigned int Actor::GetRendererCount() const
1466 unsigned int rendererCount(0);
1469 rendererCount = mRenderers->size();
1472 return rendererCount;
1475 RendererPtr Actor::GetRendererAt( unsigned int index )
1477 RendererPtr renderer;
1478 if( index < GetRendererCount() )
1480 renderer = ( *mRenderers )[ index ];
1486 void Actor::RemoveRenderer( Renderer& renderer )
1490 RendererIter end = mRenderers->end();
1491 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1493 if( (*iter).Get() == &renderer )
1495 mRenderers->erase( iter );
1496 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1503 void Actor::RemoveRenderer( unsigned int index )
1505 if( index < GetRendererCount() )
1507 RendererPtr renderer = ( *mRenderers )[ index ];
1508 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1509 mRenderers->erase( mRenderers->begin()+index );
1513 bool Actor::IsOverlay() const
1515 return ( DrawMode::OVERLAY_2D == mDrawMode );
1518 void Actor::SetDrawMode( DrawMode::Type drawMode )
1520 // this flag is not animatable so keep the value
1521 mDrawMode = drawMode;
1522 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1524 // mNode is being used in a separate thread; queue a message to set the value
1525 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1529 DrawMode::Type Actor::GetDrawMode() const
1534 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1536 // only valid when on-stage
1537 StagePtr stage = Stage::GetCurrent();
1538 if( stage && OnStage() )
1540 const RenderTaskList& taskList = stage->GetRenderTaskList();
1542 Vector2 converted( screenX, screenY );
1544 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1545 const int taskCount = taskList.GetTaskCount();
1546 for( int i = taskCount - 1; i >= 0; --i )
1548 Dali::RenderTask task = taskList.GetTask( i );
1549 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1551 // found a task where this conversion was ok so return
1559 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1561 bool retval = false;
1562 // only valid when on-stage
1565 CameraActor* camera = renderTask.GetCameraActor();
1569 renderTask.GetViewport( viewport );
1571 // need to translate coordinates to render tasks coordinate space
1572 Vector2 converted( screenX, screenY );
1573 if( renderTask.TranslateCoordinates( converted ) )
1575 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1582 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1584 // Early-out if mNode is NULL
1590 // Get the ModelView matrix
1592 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1594 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1595 Matrix invertedMvp( false/*don't init*/);
1596 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1597 bool success = invertedMvp.Invert();
1599 // Convert to GL coordinates
1600 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1605 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1612 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1618 if( XyPlaneIntersect( nearPos, farPos, local ) )
1620 Vector3 size = GetCurrentSize();
1621 localX = local.x + size.x * 0.5f;
1622 localY = local.y + size.y * 0.5f;
1633 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1636 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1638 Mathematical Formulation
1640 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1642 ( p - c ) dot ( p - c ) = r^2
1644 Given a ray with a point of origin 'o', and a direction vector 'd':
1646 ray(t) = o + td, t >= 0
1648 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1650 (o + td - c ) dot ( o + td - c ) = r^2
1652 To solve for t we first expand the above into a more recognisable quadratic equation form
1654 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1663 B = 2( o - c ) dot d
1664 C = ( o - c ) dot ( o - c ) - r^2
1666 which can be solved using a standard quadratic formula.
1668 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1670 Practical Simplification
1672 In a renderer, we often differentiate between world space and object space. In the object space
1673 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1674 into object space, the mathematical solution presented above can be simplified significantly.
1676 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1680 and we can find the t at which the (transformed) ray intersects the sphere by
1682 ( o + td ) dot ( o + td ) = r^2
1684 According to the reasoning above, we expand the above quadratic equation into the general form
1688 which now has coefficients:
1695 // Early out if mNode is NULL
1701 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1703 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1704 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1705 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1707 // Compute the radius is not needed, square radius it's enough.
1708 const Vector3& size( mNode->GetSize( bufferIndex ) );
1710 // Scale the sphere.
1711 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1713 const float width = size.width * scale.width;
1714 const float height = size.height * scale.height;
1716 float squareSphereRadius = 0.5f * ( width * width + height * height );
1718 float a = rayDir.Dot( rayDir ); // a
1719 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1720 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1722 return ( b2 * b2 - a * c ) >= 0.f;
1725 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1729 if( OnStage() && NULL != mNode )
1731 // Transforms the ray to the local reference system.
1732 // Calculate the inverse of Model matrix
1733 Matrix invModelMatrix( false/*don't init*/);
1735 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1736 invModelMatrix = mNode->GetWorldMatrix(0);
1737 invModelMatrix.Invert();
1739 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1740 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1742 // Test with the actor's XY plane (Normal = 0 0 1 1).
1744 float a = -rayOriginLocal.z;
1745 float b = rayDirLocal.z;
1747 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1749 // Ray travels distance * rayDirLocal to intersect with plane.
1752 const Vector3& size = mNode->GetSize( bufferIndex );
1754 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1755 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1757 // Test with the actor's geometry.
1758 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1765 void Actor::SetLeaveRequired( bool required )
1767 mLeaveRequired = required;
1770 bool Actor::GetLeaveRequired() const
1772 return mLeaveRequired;
1775 void Actor::SetKeyboardFocusable( bool focusable )
1777 mKeyboardFocusable = focusable;
1780 bool Actor::IsKeyboardFocusable() const
1782 return mKeyboardFocusable;
1785 bool Actor::GetTouchRequired() const
1787 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1790 bool Actor::GetHoverRequired() const
1792 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1795 bool Actor::GetWheelEventRequired() const
1797 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1800 bool Actor::IsHittable() const
1802 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1805 ActorGestureData& Actor::GetGestureData()
1807 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1808 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1809 if( NULL == mGestureData )
1811 mGestureData = new ActorGestureData;
1813 return *mGestureData;
1816 bool Actor::IsGestureRequred( Gesture::Type type ) const
1818 return mGestureData && mGestureData->IsGestureRequred( type );
1821 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1823 bool consumed = false;
1825 if( !mTouchSignal.Empty() )
1827 Dali::Actor handle( this );
1828 consumed = mTouchSignal.Emit( handle, touch );
1831 if( !mTouchedSignal.Empty() )
1833 Dali::Actor handle( this );
1834 consumed |= mTouchedSignal.Emit( handle, event );
1839 // Notification for derived classes
1840 consumed = OnTouchEvent( event ); // TODO
1846 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1848 bool consumed = false;
1850 if( !mHoveredSignal.Empty() )
1852 Dali::Actor handle( this );
1853 consumed = mHoveredSignal.Emit( handle, event );
1858 // Notification for derived classes
1859 consumed = OnHoverEvent( event );
1865 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1867 bool consumed = false;
1869 if( !mWheelEventSignal.Empty() )
1871 Dali::Actor handle( this );
1872 consumed = mWheelEventSignal.Emit( handle, event );
1877 // Notification for derived classes
1878 consumed = OnWheelEvent( event );
1884 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1886 return mTouchedSignal;
1889 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1891 return mTouchSignal;
1894 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1896 return mHoveredSignal;
1899 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1901 return mWheelEventSignal;
1904 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1906 return mOnStageSignal;
1909 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1911 return mOffStageSignal;
1914 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1916 return mOnRelayoutSignal;
1919 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1921 bool connected( true );
1922 Actor* actor = dynamic_cast< Actor* >( object );
1924 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1926 actor->TouchedSignal().Connect( tracker, functor );
1928 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1930 actor->HoveredSignal().Connect( tracker, functor );
1932 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1934 actor->WheelEventSignal().Connect( tracker, functor );
1936 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1938 actor->OnStageSignal().Connect( tracker, functor );
1940 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1942 actor->OffStageSignal().Connect( tracker, functor );
1944 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1946 actor->OnRelayoutSignal().Connect( tracker, functor );
1948 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1950 actor->TouchSignal().Connect( tracker, functor );
1954 // signalName does not match any signal
1961 Actor::Actor( DerivedType derivedType )
1966 mParentOrigin( NULL ),
1967 mAnchorPoint( NULL ),
1968 mRelayoutData( NULL ),
1969 mGestureData( NULL ),
1970 mTargetSize( 0.0f, 0.0f, 0.0f ),
1972 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1975 mIsRoot( ROOT_LAYER == derivedType ),
1976 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1977 mIsOnStage( false ),
1979 mLeaveRequired( false ),
1980 mKeyboardFocusable( false ),
1981 mDerivedRequiresTouch( false ),
1982 mDerivedRequiresHover( false ),
1983 mDerivedRequiresWheelEvent( false ),
1984 mOnStageSignalled( false ),
1985 mInsideOnSizeSet( false ),
1986 mInheritPosition( true ),
1987 mInheritOrientation( true ),
1988 mInheritScale( true ),
1989 mDrawMode( DrawMode::NORMAL ),
1990 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1991 mColorMode( Node::DEFAULT_COLOR_MODE ),
1992 mClippingMode( ClippingMode::DISABLED )
1996 void Actor::Initialize()
1999 SceneGraph::Node* node = CreateNode();
2001 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2002 mNode = node; // Keep raw-pointer to Node
2006 GetEventThreadServices().RegisterObject( this );
2011 // Remove mParent pointers from children even if we're destroying core,
2012 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2015 ActorConstIter endIter = mChildren->end();
2016 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2018 (*iter)->SetParent( NULL );
2024 // Guard to allow handle destruction after Core has been destroyed
2025 if( EventThreadServices::IsCoreRunning() )
2029 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2030 mNode = NULL; // Node is about to be destroyed
2033 GetEventThreadServices().UnregisterObject( this );
2036 // Cleanup optional gesture data
2037 delete mGestureData;
2039 // Cleanup optional parent origin and anchor
2040 delete mParentOrigin;
2041 delete mAnchorPoint;
2043 // Delete optional relayout data
2046 delete mRelayoutData;
2050 void Actor::ConnectToStage( unsigned int parentDepth )
2052 // This container is used instead of walking the Actor hierarchy.
2053 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2054 ActorContainer connectionList;
2056 // This stage is atomic i.e. not interrupted by user callbacks.
2057 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2059 // Notify applications about the newly connected actors.
2060 const ActorIter endIter = connectionList.end();
2061 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2063 (*iter)->NotifyStageConnection();
2069 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2071 DALI_ASSERT_ALWAYS( !OnStage() );
2075 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2077 ConnectToSceneGraph();
2079 // Notification for internal derived classes
2080 OnStageConnectionInternal();
2082 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2083 connectionList.push_back( ActorPtr( this ) );
2085 // Recursively connect children
2088 ActorConstIter endIter = mChildren->end();
2089 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2091 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2097 * This method is called when the Actor is connected to the Stage.
2098 * The parent must have added its Node to the scene-graph.
2099 * The child must connect its Node to the parent's Node.
2100 * This is recursive; the child calls ConnectToStage() for its children.
2102 void Actor::ConnectToSceneGraph()
2104 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2108 // Reparent Node in next Update
2109 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2112 unsigned int rendererCount( GetRendererCount() );
2113 for( unsigned int i(0); i<rendererCount; ++i )
2115 GetRendererAt(i)->Connect();
2118 // Request relayout on all actors that are added to the scenegraph
2121 // Notification for Object::Observers
2125 void Actor::NotifyStageConnection()
2127 // Actors can be removed (in a callback), before the on-stage stage is reported.
2128 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2129 if( OnStage() && !mOnStageSignalled )
2131 // Notification for external (CustomActor) derived classes
2132 OnStageConnectionExternal( mDepth );
2134 if( !mOnStageSignal.Empty() )
2136 Dali::Actor handle( this );
2137 mOnStageSignal.Emit( handle );
2140 // Guard against Remove during callbacks
2143 mOnStageSignalled = true; // signal required next time Actor is removed
2148 void Actor::DisconnectFromStage()
2150 // This container is used instead of walking the Actor hierachy.
2151 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2152 ActorContainer disconnectionList;
2154 // This stage is atomic i.e. not interrupted by user callbacks
2155 RecursiveDisconnectFromStage( disconnectionList );
2157 // Notify applications about the newly disconnected actors.
2158 const ActorIter endIter = disconnectionList.end();
2159 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2161 (*iter)->NotifyStageDisconnection();
2165 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2167 DALI_ASSERT_ALWAYS( OnStage() );
2169 // Recursively disconnect children
2172 ActorConstIter endIter = mChildren->end();
2173 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2175 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2179 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2180 disconnectionList.push_back( ActorPtr( this ) );
2182 // Notification for internal derived classes
2183 OnStageDisconnectionInternal();
2185 DisconnectFromSceneGraph();
2191 * This method is called by an actor or its parent, before a node removal message is sent.
2192 * This is recursive; the child calls DisconnectFromStage() for its children.
2194 void Actor::DisconnectFromSceneGraph()
2196 // Notification for Object::Observers
2197 OnSceneObjectRemove();
2199 unsigned int rendererCount( GetRendererCount() );
2200 for( unsigned int i(0); i<rendererCount; ++i )
2202 GetRendererAt(i)->Disconnect();
2206 void Actor::NotifyStageDisconnection()
2208 // Actors can be added (in a callback), before the off-stage state is reported.
2209 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2210 // only do this step if there is a stage, i.e. Core is not being shut down
2211 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2213 // Notification for external (CustomeActor) derived classes
2214 OnStageDisconnectionExternal();
2216 if( !mOffStageSignal.Empty() )
2218 Dali::Actor handle( this );
2219 mOffStageSignal.Emit( handle );
2222 // Guard against Add during callbacks
2225 mOnStageSignalled = false; // signal required next time Actor is added
2230 bool Actor::IsNodeConnected() const
2232 bool connected( false );
2234 if( OnStage() && ( NULL != mNode ) )
2236 if( IsRoot() || mNode->GetParent() )
2245 unsigned int Actor::GetDefaultPropertyCount() const
2247 return DEFAULT_PROPERTY_COUNT;
2250 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2252 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2254 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2256 indices.PushBack( i );
2260 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2262 if( index < DEFAULT_PROPERTY_COUNT )
2264 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2270 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2272 Property::Index index = Property::INVALID_INDEX;
2274 // Look for name in default properties
2275 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2277 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2278 if( 0 == name.compare( property->name ) )
2288 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2290 if( index < DEFAULT_PROPERTY_COUNT )
2292 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2298 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2300 if( index < DEFAULT_PROPERTY_COUNT )
2302 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2308 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2310 if( index < DEFAULT_PROPERTY_COUNT )
2312 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2318 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2320 if( index < DEFAULT_PROPERTY_COUNT )
2322 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2325 // index out of range...return Property::NONE
2326 return Property::NONE;
2329 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2333 case Dali::Actor::Property::PARENT_ORIGIN:
2335 Property::Type type = property.GetType();
2336 if( type == Property::VECTOR3 )
2338 SetParentOrigin( property.Get< Vector3 >() );
2340 else if ( type == Property::STRING )
2342 std::string parentOriginString;
2343 property.Get( parentOriginString );
2344 Vector3 parentOrigin;
2345 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2347 SetParentOrigin( parentOrigin );
2353 case Dali::Actor::Property::PARENT_ORIGIN_X:
2355 SetParentOriginX( property.Get< float >() );
2359 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2361 SetParentOriginY( property.Get< float >() );
2365 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2367 SetParentOriginZ( property.Get< float >() );
2371 case Dali::Actor::Property::ANCHOR_POINT:
2373 Property::Type type = property.GetType();
2374 if( type == Property::VECTOR3 )
2376 SetAnchorPoint( property.Get< Vector3 >() );
2378 else if ( type == Property::STRING )
2380 std::string anchorPointString;
2381 property.Get( anchorPointString );
2383 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2385 SetAnchorPoint( anchor );
2391 case Dali::Actor::Property::ANCHOR_POINT_X:
2393 SetAnchorPointX( property.Get< float >() );
2397 case Dali::Actor::Property::ANCHOR_POINT_Y:
2399 SetAnchorPointY( property.Get< float >() );
2403 case Dali::Actor::Property::ANCHOR_POINT_Z:
2405 SetAnchorPointZ( property.Get< float >() );
2409 case Dali::Actor::Property::SIZE:
2411 SetSize( property.Get< Vector3 >() );
2415 case Dali::Actor::Property::SIZE_WIDTH:
2417 SetWidth( property.Get< float >() );
2421 case Dali::Actor::Property::SIZE_HEIGHT:
2423 SetHeight( property.Get< float >() );
2427 case Dali::Actor::Property::SIZE_DEPTH:
2429 SetDepth( property.Get< float >() );
2433 case Dali::Actor::Property::POSITION:
2435 SetPosition( property.Get< Vector3 >() );
2439 case Dali::Actor::Property::POSITION_X:
2441 SetX( property.Get< float >() );
2445 case Dali::Actor::Property::POSITION_Y:
2447 SetY( property.Get< float >() );
2451 case Dali::Actor::Property::POSITION_Z:
2453 SetZ( property.Get< float >() );
2457 case Dali::Actor::Property::ORIENTATION:
2459 SetOrientation( property.Get< Quaternion >() );
2463 case Dali::Actor::Property::SCALE:
2465 SetScale( property.Get< Vector3 >() );
2469 case Dali::Actor::Property::SCALE_X:
2471 SetScaleX( property.Get< float >() );
2475 case Dali::Actor::Property::SCALE_Y:
2477 SetScaleY( property.Get< float >() );
2481 case Dali::Actor::Property::SCALE_Z:
2483 SetScaleZ( property.Get< float >() );
2487 case Dali::Actor::Property::VISIBLE:
2489 SetVisible( property.Get< bool >() );
2493 case Dali::Actor::Property::COLOR:
2495 SetColor( property.Get< Vector4 >() );
2499 case Dali::Actor::Property::COLOR_RED:
2501 SetColorRed( property.Get< float >() );
2505 case Dali::Actor::Property::COLOR_GREEN:
2507 SetColorGreen( property.Get< float >() );
2511 case Dali::Actor::Property::COLOR_BLUE:
2513 SetColorBlue( property.Get< float >() );
2517 case Dali::Actor::Property::COLOR_ALPHA:
2519 SetOpacity( property.Get< float >() );
2523 case Dali::Actor::Property::NAME:
2525 SetName( property.Get< std::string >() );
2529 case Dali::Actor::Property::SENSITIVE:
2531 SetSensitive( property.Get< bool >() );
2535 case Dali::Actor::Property::LEAVE_REQUIRED:
2537 SetLeaveRequired( property.Get< bool >() );
2541 case Dali::Actor::Property::INHERIT_POSITION:
2543 SetInheritPosition( property.Get< bool >() );
2547 case Dali::Actor::Property::INHERIT_ORIENTATION:
2549 SetInheritOrientation( property.Get< bool >() );
2553 case Dali::Actor::Property::INHERIT_SCALE:
2555 SetInheritScale( property.Get< bool >() );
2559 case Dali::Actor::Property::COLOR_MODE:
2562 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2564 SetColorMode( mode );
2569 case Dali::Actor::Property::POSITION_INHERITANCE:
2571 PositionInheritanceMode mode;
2572 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2574 SetPositionInheritanceMode( mode );
2579 case Dali::Actor::Property::DRAW_MODE:
2581 DrawMode::Type mode;
2582 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2584 SetDrawMode( mode );
2589 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2591 SetSizeModeFactor( property.Get< Vector3 >() );
2595 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2597 ResizePolicy::Type type;
2598 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2600 SetResizePolicy( type, Dimension::WIDTH );
2605 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2607 ResizePolicy::Type type;
2608 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2610 SetResizePolicy( type, Dimension::HEIGHT );
2615 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2617 SizeScalePolicy::Type type;
2618 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2620 SetSizeScalePolicy( type );
2625 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2627 if( property.Get< bool >() )
2629 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2634 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2636 if( property.Get< bool >() )
2638 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2643 case Dali::Actor::Property::PADDING:
2645 Vector4 padding = property.Get< Vector4 >();
2646 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2647 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2651 case Dali::Actor::Property::MINIMUM_SIZE:
2653 Vector2 size = property.Get< Vector2 >();
2654 SetMinimumSize( size.x, Dimension::WIDTH );
2655 SetMinimumSize( size.y, Dimension::HEIGHT );
2659 case Dali::Actor::Property::MAXIMUM_SIZE:
2661 Vector2 size = property.Get< Vector2 >();
2662 SetMaximumSize( size.x, Dimension::WIDTH );
2663 SetMaximumSize( size.y, Dimension::HEIGHT );
2667 case Dali::DevelActor::Property::SIBLING_ORDER:
2671 if( property.Get( value ) )
2673 if( static_cast<unsigned int>(value) != mSiblingOrder )
2675 mSiblingOrder = value;
2678 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2685 case Dali::Actor::Property::CLIPPING_MODE:
2687 ClippingMode::Type convertedValue = mClippingMode;
2688 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2690 mClippingMode = convertedValue;
2693 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2701 // this can happen in the case of a non-animatable default property so just do nothing
2707 // TODO: This method needs to be removed
2708 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2710 switch( entry.GetType() )
2712 case Property::BOOLEAN:
2714 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2715 DALI_ASSERT_DEBUG( NULL != property );
2717 // property is being used in a separate thread; queue a message to set the property
2718 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2723 case Property::INTEGER:
2725 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2726 DALI_ASSERT_DEBUG( NULL != property );
2728 // property is being used in a separate thread; queue a message to set the property
2729 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2734 case Property::FLOAT:
2736 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2737 DALI_ASSERT_DEBUG( NULL != property );
2739 // property is being used in a separate thread; queue a message to set the property
2740 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2745 case Property::VECTOR2:
2747 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2748 DALI_ASSERT_DEBUG( NULL != property );
2750 // property is being used in a separate thread; queue a message to set the property
2751 if(entry.componentIndex == 0)
2753 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2755 else if(entry.componentIndex == 1)
2757 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2761 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2767 case Property::VECTOR3:
2769 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2770 DALI_ASSERT_DEBUG( NULL != property );
2772 // property is being used in a separate thread; queue a message to set the property
2773 if(entry.componentIndex == 0)
2775 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2777 else if(entry.componentIndex == 1)
2779 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2781 else if(entry.componentIndex == 2)
2783 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2787 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2793 case Property::VECTOR4:
2795 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2796 DALI_ASSERT_DEBUG( NULL != property );
2798 // property is being used in a separate thread; queue a message to set the property
2799 if(entry.componentIndex == 0)
2801 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2803 else if(entry.componentIndex == 1)
2805 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2807 else if(entry.componentIndex == 2)
2809 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2811 else if(entry.componentIndex == 3)
2813 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2817 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2823 case Property::ROTATION:
2825 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2826 DALI_ASSERT_DEBUG( NULL != property );
2828 // property is being used in a separate thread; queue a message to set the property
2829 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2834 case Property::MATRIX:
2836 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2837 DALI_ASSERT_DEBUG( NULL != property );
2839 // property is being used in a separate thread; queue a message to set the property
2840 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2845 case Property::MATRIX3:
2847 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2848 DALI_ASSERT_DEBUG( NULL != property );
2850 // property is being used in a separate thread; queue a message to set the property
2851 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2858 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2864 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2866 Property::Value value;
2870 case Dali::Actor::Property::PARENT_ORIGIN:
2872 value = GetCurrentParentOrigin();
2876 case Dali::Actor::Property::PARENT_ORIGIN_X:
2878 value = GetCurrentParentOrigin().x;
2882 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2884 value = GetCurrentParentOrigin().y;
2888 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2890 value = GetCurrentParentOrigin().z;
2894 case Dali::Actor::Property::ANCHOR_POINT:
2896 value = GetCurrentAnchorPoint();
2900 case Dali::Actor::Property::ANCHOR_POINT_X:
2902 value = GetCurrentAnchorPoint().x;
2906 case Dali::Actor::Property::ANCHOR_POINT_Y:
2908 value = GetCurrentAnchorPoint().y;
2912 case Dali::Actor::Property::ANCHOR_POINT_Z:
2914 value = GetCurrentAnchorPoint().z;
2918 case Dali::Actor::Property::SIZE:
2920 value = GetTargetSize();
2924 case Dali::Actor::Property::SIZE_WIDTH:
2926 value = GetTargetSize().width;
2930 case Dali::Actor::Property::SIZE_HEIGHT:
2932 value = GetTargetSize().height;
2936 case Dali::Actor::Property::SIZE_DEPTH:
2938 value = GetTargetSize().depth;
2942 case Dali::Actor::Property::POSITION:
2944 value = GetTargetPosition();
2948 case Dali::Actor::Property::POSITION_X:
2950 value = GetTargetPosition().x;
2954 case Dali::Actor::Property::POSITION_Y:
2956 value = GetTargetPosition().y;
2960 case Dali::Actor::Property::POSITION_Z:
2962 value = GetTargetPosition().z;
2966 case Dali::Actor::Property::WORLD_POSITION:
2968 value = GetCurrentWorldPosition();
2972 case Dali::Actor::Property::WORLD_POSITION_X:
2974 value = GetCurrentWorldPosition().x;
2978 case Dali::Actor::Property::WORLD_POSITION_Y:
2980 value = GetCurrentWorldPosition().y;
2984 case Dali::Actor::Property::WORLD_POSITION_Z:
2986 value = GetCurrentWorldPosition().z;
2990 case Dali::Actor::Property::ORIENTATION:
2992 value = GetCurrentOrientation();
2996 case Dali::Actor::Property::WORLD_ORIENTATION:
2998 value = GetCurrentWorldOrientation();
3002 case Dali::Actor::Property::SCALE:
3004 value = GetCurrentScale();
3008 case Dali::Actor::Property::SCALE_X:
3010 value = GetCurrentScale().x;
3014 case Dali::Actor::Property::SCALE_Y:
3016 value = GetCurrentScale().y;
3020 case Dali::Actor::Property::SCALE_Z:
3022 value = GetCurrentScale().z;
3026 case Dali::Actor::Property::WORLD_SCALE:
3028 value = GetCurrentWorldScale();
3032 case Dali::Actor::Property::VISIBLE:
3034 value = IsVisible();
3038 case Dali::Actor::Property::COLOR:
3040 value = GetCurrentColor();
3044 case Dali::Actor::Property::COLOR_RED:
3046 value = GetCurrentColor().r;
3050 case Dali::Actor::Property::COLOR_GREEN:
3052 value = GetCurrentColor().g;
3056 case Dali::Actor::Property::COLOR_BLUE:
3058 value = GetCurrentColor().b;
3062 case Dali::Actor::Property::COLOR_ALPHA:
3064 value = GetCurrentColor().a;
3068 case Dali::Actor::Property::WORLD_COLOR:
3070 value = GetCurrentWorldColor();
3074 case Dali::Actor::Property::WORLD_MATRIX:
3076 value = GetCurrentWorldMatrix();
3080 case Dali::Actor::Property::NAME:
3086 case Dali::Actor::Property::SENSITIVE:
3088 value = IsSensitive();
3092 case Dali::Actor::Property::LEAVE_REQUIRED:
3094 value = GetLeaveRequired();
3098 case Dali::Actor::Property::INHERIT_POSITION:
3100 value = IsPositionInherited();
3104 case Dali::Actor::Property::INHERIT_ORIENTATION:
3106 value = IsOrientationInherited();
3110 case Dali::Actor::Property::INHERIT_SCALE:
3112 value = IsScaleInherited();
3116 case Dali::Actor::Property::COLOR_MODE:
3118 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3122 case Dali::Actor::Property::POSITION_INHERITANCE:
3124 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3128 case Dali::Actor::Property::DRAW_MODE:
3130 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3134 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3136 value = GetSizeModeFactor();
3140 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3142 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3146 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3148 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3152 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3154 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3158 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3160 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3164 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3166 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3170 case Dali::Actor::Property::PADDING:
3172 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3173 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3174 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3178 case Dali::Actor::Property::MINIMUM_SIZE:
3180 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3184 case Dali::Actor::Property::MAXIMUM_SIZE:
3186 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3190 case Dali::Actor::Property::CLIPPING_MODE:
3192 value = mClippingMode;
3196 case Dali::DevelActor::Property::SIBLING_ORDER:
3198 value = static_cast<int>(mSiblingOrder);
3204 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3212 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3217 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3219 // This method should only return an object connected to the scene-graph
3220 return OnStage() ? mNode : NULL;
3223 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3225 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3227 const PropertyBase* property( NULL );
3229 // This method should only return a property of an object connected to the scene-graph
3235 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3237 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3238 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3240 property = animatable->GetSceneGraphProperty();
3242 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3243 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3245 CustomPropertyMetadata* custom = FindCustomProperty( index );
3246 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3248 property = custom->GetSceneGraphProperty();
3250 else if( NULL != mNode )
3254 case Dali::Actor::Property::SIZE:
3255 property = &mNode->mSize;
3258 case Dali::Actor::Property::SIZE_WIDTH:
3259 property = &mNode->mSize;
3262 case Dali::Actor::Property::SIZE_HEIGHT:
3263 property = &mNode->mSize;
3266 case Dali::Actor::Property::SIZE_DEPTH:
3267 property = &mNode->mSize;
3270 case Dali::Actor::Property::POSITION:
3271 property = &mNode->mPosition;
3274 case Dali::Actor::Property::POSITION_X:
3275 property = &mNode->mPosition;
3278 case Dali::Actor::Property::POSITION_Y:
3279 property = &mNode->mPosition;
3282 case Dali::Actor::Property::POSITION_Z:
3283 property = &mNode->mPosition;
3286 case Dali::Actor::Property::ORIENTATION:
3287 property = &mNode->mOrientation;
3290 case Dali::Actor::Property::SCALE:
3291 property = &mNode->mScale;
3294 case Dali::Actor::Property::SCALE_X:
3295 property = &mNode->mScale;
3298 case Dali::Actor::Property::SCALE_Y:
3299 property = &mNode->mScale;
3302 case Dali::Actor::Property::SCALE_Z:
3303 property = &mNode->mScale;
3306 case Dali::Actor::Property::VISIBLE:
3307 property = &mNode->mVisible;
3310 case Dali::Actor::Property::COLOR:
3311 property = &mNode->mColor;
3314 case Dali::Actor::Property::COLOR_RED:
3315 property = &mNode->mColor;
3318 case Dali::Actor::Property::COLOR_GREEN:
3319 property = &mNode->mColor;
3322 case Dali::Actor::Property::COLOR_BLUE:
3323 property = &mNode->mColor;
3326 case Dali::Actor::Property::COLOR_ALPHA:
3327 property = &mNode->mColor;
3338 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3340 const PropertyInputImpl* property( NULL );
3342 // This method should only return a property of an object connected to the scene-graph
3348 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3350 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3351 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3353 property = animatable->GetSceneGraphProperty();
3355 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3356 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3358 CustomPropertyMetadata* custom = FindCustomProperty( index );
3359 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3360 property = custom->GetSceneGraphProperty();
3362 else if( NULL != mNode )
3366 case Dali::Actor::Property::PARENT_ORIGIN:
3367 property = &mNode->mParentOrigin;
3370 case Dali::Actor::Property::PARENT_ORIGIN_X:
3371 property = &mNode->mParentOrigin;
3374 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3375 property = &mNode->mParentOrigin;
3378 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3379 property = &mNode->mParentOrigin;
3382 case Dali::Actor::Property::ANCHOR_POINT:
3383 property = &mNode->mAnchorPoint;
3386 case Dali::Actor::Property::ANCHOR_POINT_X:
3387 property = &mNode->mAnchorPoint;
3390 case Dali::Actor::Property::ANCHOR_POINT_Y:
3391 property = &mNode->mAnchorPoint;
3394 case Dali::Actor::Property::ANCHOR_POINT_Z:
3395 property = &mNode->mAnchorPoint;
3398 case Dali::Actor::Property::SIZE:
3399 property = &mNode->mSize;
3402 case Dali::Actor::Property::SIZE_WIDTH:
3403 property = &mNode->mSize;
3406 case Dali::Actor::Property::SIZE_HEIGHT:
3407 property = &mNode->mSize;
3410 case Dali::Actor::Property::SIZE_DEPTH:
3411 property = &mNode->mSize;
3414 case Dali::Actor::Property::POSITION:
3415 property = &mNode->mPosition;
3418 case Dali::Actor::Property::POSITION_X:
3419 property = &mNode->mPosition;
3422 case Dali::Actor::Property::POSITION_Y:
3423 property = &mNode->mPosition;
3426 case Dali::Actor::Property::POSITION_Z:
3427 property = &mNode->mPosition;
3430 case Dali::Actor::Property::WORLD_POSITION:
3431 property = &mNode->mWorldPosition;
3434 case Dali::Actor::Property::WORLD_POSITION_X:
3435 property = &mNode->mWorldPosition;
3438 case Dali::Actor::Property::WORLD_POSITION_Y:
3439 property = &mNode->mWorldPosition;
3442 case Dali::Actor::Property::WORLD_POSITION_Z:
3443 property = &mNode->mWorldPosition;
3446 case Dali::Actor::Property::ORIENTATION:
3447 property = &mNode->mOrientation;
3450 case Dali::Actor::Property::WORLD_ORIENTATION:
3451 property = &mNode->mWorldOrientation;
3454 case Dali::Actor::Property::SCALE:
3455 property = &mNode->mScale;
3458 case Dali::Actor::Property::SCALE_X:
3459 property = &mNode->mScale;
3462 case Dali::Actor::Property::SCALE_Y:
3463 property = &mNode->mScale;
3466 case Dali::Actor::Property::SCALE_Z:
3467 property = &mNode->mScale;
3470 case Dali::Actor::Property::WORLD_SCALE:
3471 property = &mNode->mWorldScale;
3474 case Dali::Actor::Property::VISIBLE:
3475 property = &mNode->mVisible;
3478 case Dali::Actor::Property::COLOR:
3479 property = &mNode->mColor;
3482 case Dali::Actor::Property::COLOR_RED:
3483 property = &mNode->mColor;
3486 case Dali::Actor::Property::COLOR_GREEN:
3487 property = &mNode->mColor;
3490 case Dali::Actor::Property::COLOR_BLUE:
3491 property = &mNode->mColor;
3494 case Dali::Actor::Property::COLOR_ALPHA:
3495 property = &mNode->mColor;
3498 case Dali::Actor::Property::WORLD_COLOR:
3499 property = &mNode->mWorldColor;
3502 case Dali::Actor::Property::WORLD_MATRIX:
3503 property = &mNode->mWorldMatrix;
3514 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3516 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3518 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3520 // check whether the animatable property is registered already, if not then register one.
3521 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3522 if( animatableProperty )
3524 componentIndex = animatableProperty->componentIndex;
3531 case Dali::Actor::Property::PARENT_ORIGIN_X:
3532 case Dali::Actor::Property::ANCHOR_POINT_X:
3533 case Dali::Actor::Property::SIZE_WIDTH:
3534 case Dali::Actor::Property::POSITION_X:
3535 case Dali::Actor::Property::WORLD_POSITION_X:
3536 case Dali::Actor::Property::SCALE_X:
3537 case Dali::Actor::Property::COLOR_RED:
3543 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3544 case Dali::Actor::Property::ANCHOR_POINT_Y:
3545 case Dali::Actor::Property::SIZE_HEIGHT:
3546 case Dali::Actor::Property::POSITION_Y:
3547 case Dali::Actor::Property::WORLD_POSITION_Y:
3548 case Dali::Actor::Property::SCALE_Y:
3549 case Dali::Actor::Property::COLOR_GREEN:
3555 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3556 case Dali::Actor::Property::ANCHOR_POINT_Z:
3557 case Dali::Actor::Property::SIZE_DEPTH:
3558 case Dali::Actor::Property::POSITION_Z:
3559 case Dali::Actor::Property::WORLD_POSITION_Z:
3560 case Dali::Actor::Property::SCALE_Z:
3561 case Dali::Actor::Property::COLOR_BLUE:
3567 case Dali::Actor::Property::COLOR_ALPHA:
3581 return componentIndex;
3584 void Actor::SetParent( Actor* parent )
3588 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3592 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3595 // Instruct each actor to create a corresponding node in the scene graph
3596 ConnectToStage( parent->GetHierarchyDepth() );
3599 // Resolve the name and index for the child properties if any
3600 ResolveChildProperties();
3602 else // parent being set to NULL
3604 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3608 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3611 DALI_ASSERT_ALWAYS( mNode != NULL );
3615 // Disconnect the Node & its children from the scene-graph.
3616 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3619 // Instruct each actor to discard pointers to the scene-graph
3620 DisconnectFromStage();
3625 SceneGraph::Node* Actor::CreateNode() const
3630 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3633 Actor* actor = dynamic_cast< Actor* >( object );
3637 if( 0 == actionName.compare( ACTION_SHOW ) )
3639 actor->SetVisible( true );
3642 else if( 0 == actionName.compare( ACTION_HIDE ) )
3644 actor->SetVisible( false );
3652 void Actor::EnsureRelayoutData()
3654 // Assign relayout data.
3655 if( !mRelayoutData )
3657 mRelayoutData = new RelayoutData();
3661 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3663 // Check if actor is dependent on parent
3664 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3666 if( ( dimension & ( 1 << i ) ) )
3668 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3669 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3679 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3681 // Check if actor is dependent on children
3682 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3684 if( ( dimension & ( 1 << i ) ) )
3686 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3687 switch( resizePolicy )
3689 case ResizePolicy::FIT_TO_CHILDREN:
3690 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3706 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3708 return Actor::RelayoutDependentOnChildren( dimension );
3711 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3713 // Check each possible dimension and see if it is dependent on the input one
3714 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3716 if( dimension & ( 1 << i ) )
3718 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3725 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3727 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3729 if( dimension & ( 1 << i ) )
3731 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3736 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3738 // If more than one dimension is requested, just return the first one found
3739 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3741 if( ( dimension & ( 1 << i ) ) )
3743 return mRelayoutData->negotiatedDimensions[ i ];
3747 return 0.0f; // Default
3750 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3752 EnsureRelayoutData();
3754 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3756 if( dimension & ( 1 << i ) )
3758 mRelayoutData->dimensionPadding[ i ] = padding;
3763 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3765 if ( mRelayoutData )
3767 // If more than one dimension is requested, just return the first one found
3768 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3770 if( ( dimension & ( 1 << i ) ) )
3772 return mRelayoutData->dimensionPadding[ i ];
3777 return GetDefaultDimensionPadding();
3780 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3782 EnsureRelayoutData();
3784 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3786 if( dimension & ( 1 << i ) )
3788 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3793 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3795 if ( mRelayoutData )
3797 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3799 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3809 float Actor::GetHeightForWidthBase( float width )
3811 float height = 0.0f;
3813 const Vector3 naturalSize = GetNaturalSize();
3814 if( naturalSize.width > 0.0f )
3816 height = naturalSize.height * width / naturalSize.width;
3818 else // we treat 0 as 1:1 aspect ratio
3826 float Actor::GetWidthForHeightBase( float height )
3830 const Vector3 naturalSize = GetNaturalSize();
3831 if( naturalSize.height > 0.0f )
3833 width = naturalSize.width * height / naturalSize.height;
3835 else // we treat 0 as 1:1 aspect ratio
3843 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3845 // Fill to parent, taking size mode factor into account
3846 switch( child.GetResizePolicy( dimension ) )
3848 case ResizePolicy::FILL_TO_PARENT:
3850 return GetLatestSize( dimension );
3853 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3855 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3858 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3860 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3865 return GetLatestSize( dimension );
3870 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3872 // Can be overridden in derived class
3873 return CalculateChildSizeBase( child, dimension );
3876 float Actor::GetHeightForWidth( float width )
3878 // Can be overridden in derived class
3879 return GetHeightForWidthBase( width );
3882 float Actor::GetWidthForHeight( float height )
3884 // Can be overridden in derived class
3885 return GetWidthForHeightBase( height );
3888 float Actor::GetLatestSize( Dimension::Type dimension ) const
3890 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3893 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3895 Vector2 padding = GetPadding( dimension );
3897 return GetLatestSize( dimension ) + padding.x + padding.y;
3900 float Actor::NegotiateFromParent( Dimension::Type dimension )
3902 Actor* parent = GetParent();
3905 Vector2 padding( GetPadding( dimension ) );
3906 Vector2 parentPadding( parent->GetPadding( dimension ) );
3907 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3913 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3915 float maxDimensionPoint = 0.0f;
3917 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3919 ActorPtr child = GetChildAt( i );
3921 if( !child->RelayoutDependentOnParent( dimension ) )
3923 // Calculate the min and max points that the children range across
3924 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3925 float dimensionSize = child->GetRelayoutSize( dimension );
3926 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3930 return maxDimensionPoint;
3933 float Actor::GetSize( Dimension::Type dimension ) const
3935 return GetDimensionValue( GetTargetSize(), dimension );
3938 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3940 return GetDimensionValue( GetNaturalSize(), dimension );
3943 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3945 switch( GetResizePolicy( dimension ) )
3947 case ResizePolicy::USE_NATURAL_SIZE:
3949 return GetNaturalSize( dimension );
3952 case ResizePolicy::FIXED:
3954 return GetDimensionValue( GetPreferredSize(), dimension );
3957 case ResizePolicy::USE_ASSIGNED_SIZE:
3959 return GetDimensionValue( maximumSize, dimension );
3962 case ResizePolicy::FILL_TO_PARENT:
3963 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3964 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3966 return NegotiateFromParent( dimension );
3969 case ResizePolicy::FIT_TO_CHILDREN:
3971 return NegotiateFromChildren( dimension );
3974 case ResizePolicy::DIMENSION_DEPENDENCY:
3976 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3979 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3981 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3984 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3986 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3998 return 0.0f; // Default
4001 float Actor::ClampDimension( float size, Dimension::Type dimension )
4003 const float minSize = GetMinimumSize( dimension );
4004 const float maxSize = GetMaximumSize( dimension );
4006 return std::max( minSize, std::min( size, maxSize ) );
4009 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4011 // Check if it needs to be negotiated
4012 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4014 // Check that we havn't gotten into an infinite loop
4015 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4016 bool recursionFound = false;
4017 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4019 if( *it == searchActor )
4021 recursionFound = true;
4026 if( !recursionFound )
4028 // Record the path that we have taken
4029 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4031 // Dimension dependency check
4032 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4034 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4036 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4038 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4042 // Parent dependency check
4043 Actor* parent = GetParent();
4044 if( parent && RelayoutDependentOnParent( dimension ) )
4046 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4049 // Children dependency check
4050 if( RelayoutDependentOnChildren( dimension ) )
4052 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4054 ActorPtr child = GetChildAt( i );
4056 // Only relayout child first if it is not dependent on this actor
4057 if( !child->RelayoutDependentOnParent( dimension ) )
4059 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4064 // For deriving classes
4065 OnCalculateRelayoutSize( dimension );
4067 // All dependencies checked, calculate the size and set negotiated flag
4068 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4070 SetNegotiatedDimension( newSize, dimension );
4071 SetLayoutNegotiated( true, dimension );
4073 // For deriving classes
4074 OnLayoutNegotiated( newSize, dimension );
4076 // This actor has been successfully processed, pop it off the recursion stack
4077 recursionStack.pop_back();
4081 // TODO: Break infinite loop
4082 SetLayoutNegotiated( true, dimension );
4087 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4089 // Negotiate all dimensions that require it
4090 ActorDimensionStack recursionStack;
4092 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4094 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4097 NegotiateDimension( dimension, allocatedSize, recursionStack );
4101 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4103 switch( mRelayoutData->sizeSetPolicy )
4105 case SizeScalePolicy::USE_SIZE_SET:
4110 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4112 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4113 const Vector3 naturalSize = GetNaturalSize();
4114 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4116 const float sizeRatio = size.width / size.height;
4117 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4119 if( naturalSizeRatio < sizeRatio )
4121 return Vector2( naturalSizeRatio * size.height, size.height );
4123 else if( naturalSizeRatio > sizeRatio )
4125 return Vector2( size.width, size.width / naturalSizeRatio );
4136 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4138 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4139 const Vector3 naturalSize = GetNaturalSize();
4140 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4142 const float sizeRatio = size.width / size.height;
4143 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4145 if( naturalSizeRatio < sizeRatio )
4147 return Vector2( size.width, size.width / naturalSizeRatio );
4149 else if( naturalSizeRatio > sizeRatio )
4151 return Vector2( naturalSizeRatio * size.height, size.height );
4170 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4172 // Do the set actor size
4173 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4175 // Adjust for size set policy
4176 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4178 // Lock the flag to stop recursive relayouts on set size
4179 mRelayoutData->insideRelayout = true;
4180 SetSize( negotiatedSize );
4181 mRelayoutData->insideRelayout = false;
4183 // Clear flags for all dimensions
4184 SetLayoutDirty( false );
4186 // Give deriving classes a chance to respond
4187 OnRelayout( negotiatedSize, container );
4189 if( !mOnRelayoutSignal.Empty() )
4191 Dali::Actor handle( this );
4192 mOnRelayoutSignal.Emit( handle );
4196 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4198 // Force a size negotiation for actors that has assigned size during relayout
4199 // This is required as otherwise the flags that force a relayout will not
4200 // necessarilly be set. This will occur if the actor has already been laid out.
4201 // The dirty flags are then cleared. Then if the actor is added back into the
4202 // relayout container afterwards, the dirty flags would still be clear...
4203 // causing a relayout to be skipped. Here we force any actors added to the
4204 // container to be relayed out.
4205 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4207 SetLayoutNegotiated(false, Dimension::WIDTH);
4209 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4211 SetLayoutNegotiated(false, Dimension::HEIGHT);
4214 // Do the negotiation
4215 NegotiateDimensions( allocatedSize );
4217 // Set the actor size
4218 SetNegotiatedSize( container );
4220 // Negotiate down to children
4221 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4223 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4225 ActorPtr child = GetChildAt( i );
4227 // Forces children that have already been laid out to be relayed out
4228 // if they have assigned size during relayout.
4229 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4231 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4232 child->SetLayoutDirty(true, Dimension::WIDTH);
4234 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4236 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4237 child->SetLayoutDirty(true, Dimension::HEIGHT);
4240 // Only relayout if required
4241 if( child->RelayoutRequired() )
4243 container.Add( Dali::Actor( child.Get() ), newBounds );
4248 void Actor::RelayoutRequest( Dimension::Type dimension )
4250 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4251 if( relayoutController )
4253 Dali::Actor self( this );
4254 relayoutController->RequestRelayout( self, dimension );
4258 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4262 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4266 void Actor::SetPreferredSize( const Vector2& size )
4268 EnsureRelayoutData();
4270 if( size.width > 0.0f )
4272 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4275 if( size.height > 0.0f )
4277 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4280 mRelayoutData->preferredSize = size;
4285 Vector2 Actor::GetPreferredSize() const
4287 if ( mRelayoutData )
4289 return Vector2( mRelayoutData->preferredSize );
4292 return GetDefaultPreferredSize();
4295 void Actor::SetMinimumSize( 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->minimumSize[ i ] = size;
4310 float Actor::GetMinimumSize( 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->minimumSize[ i ];
4323 return 0.0f; // Default
4326 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4328 EnsureRelayoutData();
4330 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4332 if( dimension & ( 1 << i ) )
4334 mRelayoutData->maximumSize[ i ] = size;
4341 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4343 if ( mRelayoutData )
4345 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4347 if( dimension & ( 1 << i ) )
4349 return mRelayoutData->maximumSize[ i ];
4354 return FLT_MAX; // Default
4357 Object* Actor::GetParentObject() const
4362 } // namespace Internal