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 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1887 return mTouchedSignal;
1890 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1892 return mTouchSignal;
1895 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1897 return mHoveredSignal;
1900 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1902 return mWheelEventSignal;
1905 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1907 return mOnStageSignal;
1910 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1912 return mOffStageSignal;
1915 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1917 return mOnRelayoutSignal;
1920 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1922 bool connected( true );
1923 Actor* actor = dynamic_cast< Actor* >( object );
1925 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1927 actor->TouchedSignal().Connect( tracker, functor );
1929 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1931 actor->HoveredSignal().Connect( tracker, functor );
1933 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1935 actor->WheelEventSignal().Connect( tracker, functor );
1937 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1939 actor->OnStageSignal().Connect( tracker, functor );
1941 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1943 actor->OffStageSignal().Connect( tracker, functor );
1945 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1947 actor->OnRelayoutSignal().Connect( tracker, functor );
1949 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1951 actor->TouchSignal().Connect( tracker, functor );
1955 // signalName does not match any signal
1962 Actor::Actor( DerivedType derivedType )
1967 mParentOrigin( NULL ),
1968 mAnchorPoint( NULL ),
1969 mRelayoutData( NULL ),
1970 mGestureData( NULL ),
1971 mTargetSize( 0.0f, 0.0f, 0.0f ),
1973 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1976 mIsRoot( ROOT_LAYER == derivedType ),
1977 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1978 mIsOnStage( false ),
1980 mLeaveRequired( false ),
1981 mKeyboardFocusable( false ),
1982 mDerivedRequiresTouch( false ),
1983 mDerivedRequiresHover( false ),
1984 mDerivedRequiresWheelEvent( false ),
1985 mOnStageSignalled( false ),
1986 mInsideOnSizeSet( false ),
1987 mInheritPosition( true ),
1988 mInheritOrientation( true ),
1989 mInheritScale( true ),
1990 mDrawMode( DrawMode::NORMAL ),
1991 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1992 mColorMode( Node::DEFAULT_COLOR_MODE ),
1993 mClippingMode( ClippingMode::DISABLED )
1997 void Actor::Initialize()
2000 SceneGraph::Node* node = CreateNode();
2002 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2003 mNode = node; // Keep raw-pointer to Node
2007 GetEventThreadServices().RegisterObject( this );
2012 // Remove mParent pointers from children even if we're destroying core,
2013 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2016 ActorConstIter endIter = mChildren->end();
2017 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2019 (*iter)->SetParent( NULL );
2025 // Guard to allow handle destruction after Core has been destroyed
2026 if( EventThreadServices::IsCoreRunning() )
2030 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2031 mNode = NULL; // Node is about to be destroyed
2034 GetEventThreadServices().UnregisterObject( this );
2037 // Cleanup optional gesture data
2038 delete mGestureData;
2040 // Cleanup optional parent origin and anchor
2041 delete mParentOrigin;
2042 delete mAnchorPoint;
2044 // Delete optional relayout data
2047 delete mRelayoutData;
2051 void Actor::ConnectToStage( unsigned int parentDepth )
2053 // This container is used instead of walking the Actor hierarchy.
2054 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2055 ActorContainer connectionList;
2057 // This stage is atomic i.e. not interrupted by user callbacks.
2058 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2060 // Notify applications about the newly connected actors.
2061 const ActorIter endIter = connectionList.end();
2062 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2064 (*iter)->NotifyStageConnection();
2070 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2072 DALI_ASSERT_ALWAYS( !OnStage() );
2076 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2078 ConnectToSceneGraph();
2080 // Notification for internal derived classes
2081 OnStageConnectionInternal();
2083 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2084 connectionList.push_back( ActorPtr( this ) );
2086 // Recursively connect children
2089 ActorConstIter endIter = mChildren->end();
2090 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2092 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2098 * This method is called when the Actor is connected to the Stage.
2099 * The parent must have added its Node to the scene-graph.
2100 * The child must connect its Node to the parent's Node.
2101 * This is recursive; the child calls ConnectToStage() for its children.
2103 void Actor::ConnectToSceneGraph()
2105 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2109 // Reparent Node in next Update
2110 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2113 unsigned int rendererCount( GetRendererCount() );
2114 for( unsigned int i(0); i<rendererCount; ++i )
2116 GetRendererAt(i)->Connect();
2119 // Request relayout on all actors that are added to the scenegraph
2122 // Notification for Object::Observers
2126 void Actor::NotifyStageConnection()
2128 // Actors can be removed (in a callback), before the on-stage stage is reported.
2129 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2130 if( OnStage() && !mOnStageSignalled )
2132 // Notification for external (CustomActor) derived classes
2133 OnStageConnectionExternal( mDepth );
2135 if( !mOnStageSignal.Empty() )
2137 Dali::Actor handle( this );
2138 mOnStageSignal.Emit( handle );
2141 // Guard against Remove during callbacks
2144 mOnStageSignalled = true; // signal required next time Actor is removed
2149 void Actor::DisconnectFromStage()
2151 // This container is used instead of walking the Actor hierachy.
2152 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2153 ActorContainer disconnectionList;
2155 // This stage is atomic i.e. not interrupted by user callbacks
2156 RecursiveDisconnectFromStage( disconnectionList );
2158 // Notify applications about the newly disconnected actors.
2159 const ActorIter endIter = disconnectionList.end();
2160 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2162 (*iter)->NotifyStageDisconnection();
2166 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2168 DALI_ASSERT_ALWAYS( OnStage() );
2170 // Recursively disconnect children
2173 ActorConstIter endIter = mChildren->end();
2174 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2176 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2180 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2181 disconnectionList.push_back( ActorPtr( this ) );
2183 // Notification for internal derived classes
2184 OnStageDisconnectionInternal();
2186 DisconnectFromSceneGraph();
2192 * This method is called by an actor or its parent, before a node removal message is sent.
2193 * This is recursive; the child calls DisconnectFromStage() for its children.
2195 void Actor::DisconnectFromSceneGraph()
2197 // Notification for Object::Observers
2198 OnSceneObjectRemove();
2200 unsigned int rendererCount( GetRendererCount() );
2201 for( unsigned int i(0); i<rendererCount; ++i )
2203 GetRendererAt(i)->Disconnect();
2207 void Actor::NotifyStageDisconnection()
2209 // Actors can be added (in a callback), before the off-stage state is reported.
2210 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2211 // only do this step if there is a stage, i.e. Core is not being shut down
2212 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2214 // Notification for external (CustomeActor) derived classes
2215 OnStageDisconnectionExternal();
2217 if( !mOffStageSignal.Empty() )
2219 Dali::Actor handle( this );
2220 mOffStageSignal.Emit( handle );
2223 // Guard against Add during callbacks
2226 mOnStageSignalled = false; // signal required next time Actor is added
2231 bool Actor::IsNodeConnected() const
2233 bool connected( false );
2235 if( OnStage() && ( NULL != mNode ) )
2237 if( IsRoot() || mNode->GetParent() )
2246 unsigned int Actor::GetDefaultPropertyCount() const
2248 return DEFAULT_PROPERTY_COUNT;
2251 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2253 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2255 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2257 indices.PushBack( i );
2261 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2263 if( index < DEFAULT_PROPERTY_COUNT )
2265 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2271 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2273 Property::Index index = Property::INVALID_INDEX;
2275 // Look for name in default properties
2276 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2278 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2279 if( 0 == name.compare( property->name ) )
2289 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2291 if( index < DEFAULT_PROPERTY_COUNT )
2293 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2299 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2301 if( index < DEFAULT_PROPERTY_COUNT )
2303 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2309 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2311 if( index < DEFAULT_PROPERTY_COUNT )
2313 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2319 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2321 if( index < DEFAULT_PROPERTY_COUNT )
2323 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2326 // index out of range...return Property::NONE
2327 return Property::NONE;
2330 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2334 case Dali::Actor::Property::PARENT_ORIGIN:
2336 Property::Type type = property.GetType();
2337 if( type == Property::VECTOR3 )
2339 SetParentOrigin( property.Get< Vector3 >() );
2341 else if ( type == Property::STRING )
2343 std::string parentOriginString;
2344 property.Get( parentOriginString );
2345 Vector3 parentOrigin;
2346 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2348 SetParentOrigin( parentOrigin );
2354 case Dali::Actor::Property::PARENT_ORIGIN_X:
2356 SetParentOriginX( property.Get< float >() );
2360 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2362 SetParentOriginY( property.Get< float >() );
2366 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2368 SetParentOriginZ( property.Get< float >() );
2372 case Dali::Actor::Property::ANCHOR_POINT:
2374 Property::Type type = property.GetType();
2375 if( type == Property::VECTOR3 )
2377 SetAnchorPoint( property.Get< Vector3 >() );
2379 else if ( type == Property::STRING )
2381 std::string anchorPointString;
2382 property.Get( anchorPointString );
2384 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2386 SetAnchorPoint( anchor );
2392 case Dali::Actor::Property::ANCHOR_POINT_X:
2394 SetAnchorPointX( property.Get< float >() );
2398 case Dali::Actor::Property::ANCHOR_POINT_Y:
2400 SetAnchorPointY( property.Get< float >() );
2404 case Dali::Actor::Property::ANCHOR_POINT_Z:
2406 SetAnchorPointZ( property.Get< float >() );
2410 case Dali::Actor::Property::SIZE:
2412 SetSize( property.Get< Vector3 >() );
2416 case Dali::Actor::Property::SIZE_WIDTH:
2418 SetWidth( property.Get< float >() );
2422 case Dali::Actor::Property::SIZE_HEIGHT:
2424 SetHeight( property.Get< float >() );
2428 case Dali::Actor::Property::SIZE_DEPTH:
2430 SetDepth( property.Get< float >() );
2434 case Dali::Actor::Property::POSITION:
2436 SetPosition( property.Get< Vector3 >() );
2440 case Dali::Actor::Property::POSITION_X:
2442 SetX( property.Get< float >() );
2446 case Dali::Actor::Property::POSITION_Y:
2448 SetY( property.Get< float >() );
2452 case Dali::Actor::Property::POSITION_Z:
2454 SetZ( property.Get< float >() );
2458 case Dali::Actor::Property::ORIENTATION:
2460 SetOrientation( property.Get< Quaternion >() );
2464 case Dali::Actor::Property::SCALE:
2466 SetScale( property.Get< Vector3 >() );
2470 case Dali::Actor::Property::SCALE_X:
2472 SetScaleX( property.Get< float >() );
2476 case Dali::Actor::Property::SCALE_Y:
2478 SetScaleY( property.Get< float >() );
2482 case Dali::Actor::Property::SCALE_Z:
2484 SetScaleZ( property.Get< float >() );
2488 case Dali::Actor::Property::VISIBLE:
2490 SetVisible( property.Get< bool >() );
2494 case Dali::Actor::Property::COLOR:
2496 SetColor( property.Get< Vector4 >() );
2500 case Dali::Actor::Property::COLOR_RED:
2502 SetColorRed( property.Get< float >() );
2506 case Dali::Actor::Property::COLOR_GREEN:
2508 SetColorGreen( property.Get< float >() );
2512 case Dali::Actor::Property::COLOR_BLUE:
2514 SetColorBlue( property.Get< float >() );
2518 case Dali::Actor::Property::COLOR_ALPHA:
2520 SetOpacity( property.Get< float >() );
2524 case Dali::Actor::Property::NAME:
2526 SetName( property.Get< std::string >() );
2530 case Dali::Actor::Property::SENSITIVE:
2532 SetSensitive( property.Get< bool >() );
2536 case Dali::Actor::Property::LEAVE_REQUIRED:
2538 SetLeaveRequired( property.Get< bool >() );
2542 case Dali::Actor::Property::INHERIT_POSITION:
2544 SetInheritPosition( property.Get< bool >() );
2548 case Dali::Actor::Property::INHERIT_ORIENTATION:
2550 SetInheritOrientation( property.Get< bool >() );
2554 case Dali::Actor::Property::INHERIT_SCALE:
2556 SetInheritScale( property.Get< bool >() );
2560 case Dali::Actor::Property::COLOR_MODE:
2563 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2565 SetColorMode( mode );
2570 case Dali::Actor::Property::POSITION_INHERITANCE:
2572 PositionInheritanceMode mode;
2573 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2575 SetPositionInheritanceMode( mode );
2580 case Dali::Actor::Property::DRAW_MODE:
2582 DrawMode::Type mode;
2583 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2585 SetDrawMode( mode );
2590 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2592 SetSizeModeFactor( property.Get< Vector3 >() );
2596 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2598 ResizePolicy::Type type;
2599 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2601 SetResizePolicy( type, Dimension::WIDTH );
2606 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2608 ResizePolicy::Type type;
2609 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2611 SetResizePolicy( type, Dimension::HEIGHT );
2616 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2618 SizeScalePolicy::Type type;
2619 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2621 SetSizeScalePolicy( type );
2626 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2628 if( property.Get< bool >() )
2630 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2635 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2637 if( property.Get< bool >() )
2639 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2644 case Dali::Actor::Property::PADDING:
2646 Vector4 padding = property.Get< Vector4 >();
2647 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2648 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2652 case Dali::Actor::Property::MINIMUM_SIZE:
2654 Vector2 size = property.Get< Vector2 >();
2655 SetMinimumSize( size.x, Dimension::WIDTH );
2656 SetMinimumSize( size.y, Dimension::HEIGHT );
2660 case Dali::Actor::Property::MAXIMUM_SIZE:
2662 Vector2 size = property.Get< Vector2 >();
2663 SetMaximumSize( size.x, Dimension::WIDTH );
2664 SetMaximumSize( size.y, Dimension::HEIGHT );
2668 case Dali::DevelActor::Property::SIBLING_ORDER:
2672 if( property.Get( value ) )
2674 if( static_cast<unsigned int>(value) != mSiblingOrder )
2676 mSiblingOrder = value;
2679 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2686 case Dali::Actor::Property::CLIPPING_MODE:
2688 ClippingMode::Type convertedValue = mClippingMode;
2689 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2691 mClippingMode = convertedValue;
2694 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2702 // this can happen in the case of a non-animatable default property so just do nothing
2708 // TODO: This method needs to be removed
2709 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2711 switch( entry.GetType() )
2713 case Property::BOOLEAN:
2715 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2716 DALI_ASSERT_DEBUG( NULL != property );
2718 // property is being used in a separate thread; queue a message to set the property
2719 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2724 case Property::INTEGER:
2726 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2727 DALI_ASSERT_DEBUG( NULL != property );
2729 // property is being used in a separate thread; queue a message to set the property
2730 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2735 case Property::FLOAT:
2737 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2738 DALI_ASSERT_DEBUG( NULL != property );
2740 // property is being used in a separate thread; queue a message to set the property
2741 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2746 case Property::VECTOR2:
2748 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2749 DALI_ASSERT_DEBUG( NULL != property );
2751 // property is being used in a separate thread; queue a message to set the property
2752 if(entry.componentIndex == 0)
2754 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2756 else if(entry.componentIndex == 1)
2758 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2762 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2768 case Property::VECTOR3:
2770 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2771 DALI_ASSERT_DEBUG( NULL != property );
2773 // property is being used in a separate thread; queue a message to set the property
2774 if(entry.componentIndex == 0)
2776 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2778 else if(entry.componentIndex == 1)
2780 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2782 else if(entry.componentIndex == 2)
2784 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2788 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2794 case Property::VECTOR4:
2796 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2797 DALI_ASSERT_DEBUG( NULL != property );
2799 // property is being used in a separate thread; queue a message to set the property
2800 if(entry.componentIndex == 0)
2802 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2804 else if(entry.componentIndex == 1)
2806 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2808 else if(entry.componentIndex == 2)
2810 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2812 else if(entry.componentIndex == 3)
2814 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2818 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2824 case Property::ROTATION:
2826 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2827 DALI_ASSERT_DEBUG( NULL != property );
2829 // property is being used in a separate thread; queue a message to set the property
2830 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2835 case Property::MATRIX:
2837 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2838 DALI_ASSERT_DEBUG( NULL != property );
2840 // property is being used in a separate thread; queue a message to set the property
2841 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2846 case Property::MATRIX3:
2848 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2849 DALI_ASSERT_DEBUG( NULL != property );
2851 // property is being used in a separate thread; queue a message to set the property
2852 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2859 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2865 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2867 Property::Value value;
2871 case Dali::Actor::Property::PARENT_ORIGIN:
2873 value = GetCurrentParentOrigin();
2877 case Dali::Actor::Property::PARENT_ORIGIN_X:
2879 value = GetCurrentParentOrigin().x;
2883 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2885 value = GetCurrentParentOrigin().y;
2889 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2891 value = GetCurrentParentOrigin().z;
2895 case Dali::Actor::Property::ANCHOR_POINT:
2897 value = GetCurrentAnchorPoint();
2901 case Dali::Actor::Property::ANCHOR_POINT_X:
2903 value = GetCurrentAnchorPoint().x;
2907 case Dali::Actor::Property::ANCHOR_POINT_Y:
2909 value = GetCurrentAnchorPoint().y;
2913 case Dali::Actor::Property::ANCHOR_POINT_Z:
2915 value = GetCurrentAnchorPoint().z;
2919 case Dali::Actor::Property::SIZE:
2921 value = GetTargetSize();
2925 case Dali::Actor::Property::SIZE_WIDTH:
2927 value = GetTargetSize().width;
2931 case Dali::Actor::Property::SIZE_HEIGHT:
2933 value = GetTargetSize().height;
2937 case Dali::Actor::Property::SIZE_DEPTH:
2939 value = GetTargetSize().depth;
2943 case Dali::Actor::Property::POSITION:
2945 value = GetTargetPosition();
2949 case Dali::Actor::Property::POSITION_X:
2951 value = GetTargetPosition().x;
2955 case Dali::Actor::Property::POSITION_Y:
2957 value = GetTargetPosition().y;
2961 case Dali::Actor::Property::POSITION_Z:
2963 value = GetTargetPosition().z;
2967 case Dali::Actor::Property::WORLD_POSITION:
2969 value = GetCurrentWorldPosition();
2973 case Dali::Actor::Property::WORLD_POSITION_X:
2975 value = GetCurrentWorldPosition().x;
2979 case Dali::Actor::Property::WORLD_POSITION_Y:
2981 value = GetCurrentWorldPosition().y;
2985 case Dali::Actor::Property::WORLD_POSITION_Z:
2987 value = GetCurrentWorldPosition().z;
2991 case Dali::Actor::Property::ORIENTATION:
2993 value = GetCurrentOrientation();
2997 case Dali::Actor::Property::WORLD_ORIENTATION:
2999 value = GetCurrentWorldOrientation();
3003 case Dali::Actor::Property::SCALE:
3005 value = GetCurrentScale();
3009 case Dali::Actor::Property::SCALE_X:
3011 value = GetCurrentScale().x;
3015 case Dali::Actor::Property::SCALE_Y:
3017 value = GetCurrentScale().y;
3021 case Dali::Actor::Property::SCALE_Z:
3023 value = GetCurrentScale().z;
3027 case Dali::Actor::Property::WORLD_SCALE:
3029 value = GetCurrentWorldScale();
3033 case Dali::Actor::Property::VISIBLE:
3035 value = IsVisible();
3039 case Dali::Actor::Property::COLOR:
3041 value = GetCurrentColor();
3045 case Dali::Actor::Property::COLOR_RED:
3047 value = GetCurrentColor().r;
3051 case Dali::Actor::Property::COLOR_GREEN:
3053 value = GetCurrentColor().g;
3057 case Dali::Actor::Property::COLOR_BLUE:
3059 value = GetCurrentColor().b;
3063 case Dali::Actor::Property::COLOR_ALPHA:
3065 value = GetCurrentColor().a;
3069 case Dali::Actor::Property::WORLD_COLOR:
3071 value = GetCurrentWorldColor();
3075 case Dali::Actor::Property::WORLD_MATRIX:
3077 value = GetCurrentWorldMatrix();
3081 case Dali::Actor::Property::NAME:
3087 case Dali::Actor::Property::SENSITIVE:
3089 value = IsSensitive();
3093 case Dali::Actor::Property::LEAVE_REQUIRED:
3095 value = GetLeaveRequired();
3099 case Dali::Actor::Property::INHERIT_POSITION:
3101 value = IsPositionInherited();
3105 case Dali::Actor::Property::INHERIT_ORIENTATION:
3107 value = IsOrientationInherited();
3111 case Dali::Actor::Property::INHERIT_SCALE:
3113 value = IsScaleInherited();
3117 case Dali::Actor::Property::COLOR_MODE:
3119 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3123 case Dali::Actor::Property::POSITION_INHERITANCE:
3125 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3129 case Dali::Actor::Property::DRAW_MODE:
3131 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3135 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3137 value = GetSizeModeFactor();
3141 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3143 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3147 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3149 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3153 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3155 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3159 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3161 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3165 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3167 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3171 case Dali::Actor::Property::PADDING:
3173 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3174 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3175 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3179 case Dali::Actor::Property::MINIMUM_SIZE:
3181 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3185 case Dali::Actor::Property::MAXIMUM_SIZE:
3187 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3191 case Dali::Actor::Property::CLIPPING_MODE:
3193 value = mClippingMode;
3197 case Dali::DevelActor::Property::SIBLING_ORDER:
3199 value = static_cast<int>(mSiblingOrder);
3205 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3213 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3218 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3220 // This method should only return an object connected to the scene-graph
3221 return OnStage() ? mNode : NULL;
3224 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3226 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3228 const PropertyBase* property( NULL );
3230 // This method should only return a property of an object connected to the scene-graph
3236 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3238 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3239 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3241 property = animatable->GetSceneGraphProperty();
3243 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3244 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3246 CustomPropertyMetadata* custom = FindCustomProperty( index );
3247 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3249 property = custom->GetSceneGraphProperty();
3251 else if( NULL != mNode )
3255 case Dali::Actor::Property::SIZE:
3256 property = &mNode->mSize;
3259 case Dali::Actor::Property::SIZE_WIDTH:
3260 property = &mNode->mSize;
3263 case Dali::Actor::Property::SIZE_HEIGHT:
3264 property = &mNode->mSize;
3267 case Dali::Actor::Property::SIZE_DEPTH:
3268 property = &mNode->mSize;
3271 case Dali::Actor::Property::POSITION:
3272 property = &mNode->mPosition;
3275 case Dali::Actor::Property::POSITION_X:
3276 property = &mNode->mPosition;
3279 case Dali::Actor::Property::POSITION_Y:
3280 property = &mNode->mPosition;
3283 case Dali::Actor::Property::POSITION_Z:
3284 property = &mNode->mPosition;
3287 case Dali::Actor::Property::ORIENTATION:
3288 property = &mNode->mOrientation;
3291 case Dali::Actor::Property::SCALE:
3292 property = &mNode->mScale;
3295 case Dali::Actor::Property::SCALE_X:
3296 property = &mNode->mScale;
3299 case Dali::Actor::Property::SCALE_Y:
3300 property = &mNode->mScale;
3303 case Dali::Actor::Property::SCALE_Z:
3304 property = &mNode->mScale;
3307 case Dali::Actor::Property::VISIBLE:
3308 property = &mNode->mVisible;
3311 case Dali::Actor::Property::COLOR:
3312 property = &mNode->mColor;
3315 case Dali::Actor::Property::COLOR_RED:
3316 property = &mNode->mColor;
3319 case Dali::Actor::Property::COLOR_GREEN:
3320 property = &mNode->mColor;
3323 case Dali::Actor::Property::COLOR_BLUE:
3324 property = &mNode->mColor;
3327 case Dali::Actor::Property::COLOR_ALPHA:
3328 property = &mNode->mColor;
3339 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3341 const PropertyInputImpl* property( NULL );
3343 // This method should only return a property of an object connected to the scene-graph
3349 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3351 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3352 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3354 property = animatable->GetSceneGraphProperty();
3356 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3357 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3359 CustomPropertyMetadata* custom = FindCustomProperty( index );
3360 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3361 property = custom->GetSceneGraphProperty();
3363 else if( NULL != mNode )
3367 case Dali::Actor::Property::PARENT_ORIGIN:
3368 property = &mNode->mParentOrigin;
3371 case Dali::Actor::Property::PARENT_ORIGIN_X:
3372 property = &mNode->mParentOrigin;
3375 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3376 property = &mNode->mParentOrigin;
3379 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3380 property = &mNode->mParentOrigin;
3383 case Dali::Actor::Property::ANCHOR_POINT:
3384 property = &mNode->mAnchorPoint;
3387 case Dali::Actor::Property::ANCHOR_POINT_X:
3388 property = &mNode->mAnchorPoint;
3391 case Dali::Actor::Property::ANCHOR_POINT_Y:
3392 property = &mNode->mAnchorPoint;
3395 case Dali::Actor::Property::ANCHOR_POINT_Z:
3396 property = &mNode->mAnchorPoint;
3399 case Dali::Actor::Property::SIZE:
3400 property = &mNode->mSize;
3403 case Dali::Actor::Property::SIZE_WIDTH:
3404 property = &mNode->mSize;
3407 case Dali::Actor::Property::SIZE_HEIGHT:
3408 property = &mNode->mSize;
3411 case Dali::Actor::Property::SIZE_DEPTH:
3412 property = &mNode->mSize;
3415 case Dali::Actor::Property::POSITION:
3416 property = &mNode->mPosition;
3419 case Dali::Actor::Property::POSITION_X:
3420 property = &mNode->mPosition;
3423 case Dali::Actor::Property::POSITION_Y:
3424 property = &mNode->mPosition;
3427 case Dali::Actor::Property::POSITION_Z:
3428 property = &mNode->mPosition;
3431 case Dali::Actor::Property::WORLD_POSITION:
3432 property = &mNode->mWorldPosition;
3435 case Dali::Actor::Property::WORLD_POSITION_X:
3436 property = &mNode->mWorldPosition;
3439 case Dali::Actor::Property::WORLD_POSITION_Y:
3440 property = &mNode->mWorldPosition;
3443 case Dali::Actor::Property::WORLD_POSITION_Z:
3444 property = &mNode->mWorldPosition;
3447 case Dali::Actor::Property::ORIENTATION:
3448 property = &mNode->mOrientation;
3451 case Dali::Actor::Property::WORLD_ORIENTATION:
3452 property = &mNode->mWorldOrientation;
3455 case Dali::Actor::Property::SCALE:
3456 property = &mNode->mScale;
3459 case Dali::Actor::Property::SCALE_X:
3460 property = &mNode->mScale;
3463 case Dali::Actor::Property::SCALE_Y:
3464 property = &mNode->mScale;
3467 case Dali::Actor::Property::SCALE_Z:
3468 property = &mNode->mScale;
3471 case Dali::Actor::Property::WORLD_SCALE:
3472 property = &mNode->mWorldScale;
3475 case Dali::Actor::Property::VISIBLE:
3476 property = &mNode->mVisible;
3479 case Dali::Actor::Property::COLOR:
3480 property = &mNode->mColor;
3483 case Dali::Actor::Property::COLOR_RED:
3484 property = &mNode->mColor;
3487 case Dali::Actor::Property::COLOR_GREEN:
3488 property = &mNode->mColor;
3491 case Dali::Actor::Property::COLOR_BLUE:
3492 property = &mNode->mColor;
3495 case Dali::Actor::Property::COLOR_ALPHA:
3496 property = &mNode->mColor;
3499 case Dali::Actor::Property::WORLD_COLOR:
3500 property = &mNode->mWorldColor;
3503 case Dali::Actor::Property::WORLD_MATRIX:
3504 property = &mNode->mWorldMatrix;
3515 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3517 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3519 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3521 // check whether the animatable property is registered already, if not then register one.
3522 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3523 if( animatableProperty )
3525 componentIndex = animatableProperty->componentIndex;
3532 case Dali::Actor::Property::PARENT_ORIGIN_X:
3533 case Dali::Actor::Property::ANCHOR_POINT_X:
3534 case Dali::Actor::Property::SIZE_WIDTH:
3535 case Dali::Actor::Property::POSITION_X:
3536 case Dali::Actor::Property::WORLD_POSITION_X:
3537 case Dali::Actor::Property::SCALE_X:
3538 case Dali::Actor::Property::COLOR_RED:
3544 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3545 case Dali::Actor::Property::ANCHOR_POINT_Y:
3546 case Dali::Actor::Property::SIZE_HEIGHT:
3547 case Dali::Actor::Property::POSITION_Y:
3548 case Dali::Actor::Property::WORLD_POSITION_Y:
3549 case Dali::Actor::Property::SCALE_Y:
3550 case Dali::Actor::Property::COLOR_GREEN:
3556 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3557 case Dali::Actor::Property::ANCHOR_POINT_Z:
3558 case Dali::Actor::Property::SIZE_DEPTH:
3559 case Dali::Actor::Property::POSITION_Z:
3560 case Dali::Actor::Property::WORLD_POSITION_Z:
3561 case Dali::Actor::Property::SCALE_Z:
3562 case Dali::Actor::Property::COLOR_BLUE:
3568 case Dali::Actor::Property::COLOR_ALPHA:
3582 return componentIndex;
3585 void Actor::SetParent( Actor* parent )
3589 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3593 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3596 // Instruct each actor to create a corresponding node in the scene graph
3597 ConnectToStage( parent->GetHierarchyDepth() );
3600 // Resolve the name and index for the child properties if any
3601 ResolveChildProperties();
3603 else // parent being set to NULL
3605 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3609 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3612 DALI_ASSERT_ALWAYS( mNode != NULL );
3616 // Disconnect the Node & its children from the scene-graph.
3617 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3620 // Instruct each actor to discard pointers to the scene-graph
3621 DisconnectFromStage();
3626 SceneGraph::Node* Actor::CreateNode() const
3631 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3634 Actor* actor = dynamic_cast< Actor* >( object );
3638 if( 0 == actionName.compare( ACTION_SHOW ) )
3640 actor->SetVisible( true );
3643 else if( 0 == actionName.compare( ACTION_HIDE ) )
3645 actor->SetVisible( false );
3653 void Actor::EnsureRelayoutData()
3655 // Assign relayout data.
3656 if( !mRelayoutData )
3658 mRelayoutData = new RelayoutData();
3662 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3664 // Check if actor is dependent on parent
3665 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3667 if( ( dimension & ( 1 << i ) ) )
3669 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3670 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3680 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3682 // Check if actor is dependent on children
3683 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3685 if( ( dimension & ( 1 << i ) ) )
3687 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3688 switch( resizePolicy )
3690 case ResizePolicy::FIT_TO_CHILDREN:
3691 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3707 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3709 return Actor::RelayoutDependentOnChildren( dimension );
3712 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3714 // Check each possible dimension and see if it is dependent on the input one
3715 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3717 if( dimension & ( 1 << i ) )
3719 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3726 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3728 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3730 if( dimension & ( 1 << i ) )
3732 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3737 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3739 // If more than one dimension is requested, just return the first one found
3740 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3742 if( ( dimension & ( 1 << i ) ) )
3744 return mRelayoutData->negotiatedDimensions[ i ];
3748 return 0.0f; // Default
3751 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3753 EnsureRelayoutData();
3755 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3757 if( dimension & ( 1 << i ) )
3759 mRelayoutData->dimensionPadding[ i ] = padding;
3764 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3766 if ( mRelayoutData )
3768 // If more than one dimension is requested, just return the first one found
3769 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3771 if( ( dimension & ( 1 << i ) ) )
3773 return mRelayoutData->dimensionPadding[ i ];
3778 return GetDefaultDimensionPadding();
3781 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3783 EnsureRelayoutData();
3785 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3787 if( dimension & ( 1 << i ) )
3789 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3794 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3796 if ( mRelayoutData )
3798 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3800 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3810 float Actor::GetHeightForWidthBase( float width )
3812 float height = 0.0f;
3814 const Vector3 naturalSize = GetNaturalSize();
3815 if( naturalSize.width > 0.0f )
3817 height = naturalSize.height * width / naturalSize.width;
3819 else // we treat 0 as 1:1 aspect ratio
3827 float Actor::GetWidthForHeightBase( float height )
3831 const Vector3 naturalSize = GetNaturalSize();
3832 if( naturalSize.height > 0.0f )
3834 width = naturalSize.width * height / naturalSize.height;
3836 else // we treat 0 as 1:1 aspect ratio
3844 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3846 // Fill to parent, taking size mode factor into account
3847 switch( child.GetResizePolicy( dimension ) )
3849 case ResizePolicy::FILL_TO_PARENT:
3851 return GetLatestSize( dimension );
3854 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3856 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3859 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3861 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3866 return GetLatestSize( dimension );
3871 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3873 // Can be overridden in derived class
3874 return CalculateChildSizeBase( child, dimension );
3877 float Actor::GetHeightForWidth( float width )
3879 // Can be overridden in derived class
3880 return GetHeightForWidthBase( width );
3883 float Actor::GetWidthForHeight( float height )
3885 // Can be overridden in derived class
3886 return GetWidthForHeightBase( height );
3889 float Actor::GetLatestSize( Dimension::Type dimension ) const
3891 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3894 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3896 Vector2 padding = GetPadding( dimension );
3898 return GetLatestSize( dimension ) + padding.x + padding.y;
3901 float Actor::NegotiateFromParent( Dimension::Type dimension )
3903 Actor* parent = GetParent();
3906 Vector2 padding( GetPadding( dimension ) );
3907 Vector2 parentPadding( parent->GetPadding( dimension ) );
3908 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3914 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3916 float maxDimensionPoint = 0.0f;
3918 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3920 ActorPtr child = GetChildAt( i );
3922 if( !child->RelayoutDependentOnParent( dimension ) )
3924 // Calculate the min and max points that the children range across
3925 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3926 float dimensionSize = child->GetRelayoutSize( dimension );
3927 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3931 return maxDimensionPoint;
3934 float Actor::GetSize( Dimension::Type dimension ) const
3936 return GetDimensionValue( GetTargetSize(), dimension );
3939 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3941 return GetDimensionValue( GetNaturalSize(), dimension );
3944 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3946 switch( GetResizePolicy( dimension ) )
3948 case ResizePolicy::USE_NATURAL_SIZE:
3950 return GetNaturalSize( dimension );
3953 case ResizePolicy::FIXED:
3955 return GetDimensionValue( GetPreferredSize(), dimension );
3958 case ResizePolicy::USE_ASSIGNED_SIZE:
3960 return GetDimensionValue( maximumSize, dimension );
3963 case ResizePolicy::FILL_TO_PARENT:
3964 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3965 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3967 return NegotiateFromParent( dimension );
3970 case ResizePolicy::FIT_TO_CHILDREN:
3972 return NegotiateFromChildren( dimension );
3975 case ResizePolicy::DIMENSION_DEPENDENCY:
3977 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3980 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3982 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3985 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3987 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3999 return 0.0f; // Default
4002 float Actor::ClampDimension( float size, Dimension::Type dimension )
4004 const float minSize = GetMinimumSize( dimension );
4005 const float maxSize = GetMaximumSize( dimension );
4007 return std::max( minSize, std::min( size, maxSize ) );
4010 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4012 // Check if it needs to be negotiated
4013 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4015 // Check that we havn't gotten into an infinite loop
4016 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4017 bool recursionFound = false;
4018 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4020 if( *it == searchActor )
4022 recursionFound = true;
4027 if( !recursionFound )
4029 // Record the path that we have taken
4030 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4032 // Dimension dependency check
4033 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4035 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4037 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4039 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4043 // Parent dependency check
4044 Actor* parent = GetParent();
4045 if( parent && RelayoutDependentOnParent( dimension ) )
4047 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4050 // Children dependency check
4051 if( RelayoutDependentOnChildren( dimension ) )
4053 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4055 ActorPtr child = GetChildAt( i );
4057 // Only relayout child first if it is not dependent on this actor
4058 if( !child->RelayoutDependentOnParent( dimension ) )
4060 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4065 // For deriving classes
4066 OnCalculateRelayoutSize( dimension );
4068 // All dependencies checked, calculate the size and set negotiated flag
4069 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4071 SetNegotiatedDimension( newSize, dimension );
4072 SetLayoutNegotiated( true, dimension );
4074 // For deriving classes
4075 OnLayoutNegotiated( newSize, dimension );
4077 // This actor has been successfully processed, pop it off the recursion stack
4078 recursionStack.pop_back();
4082 // TODO: Break infinite loop
4083 SetLayoutNegotiated( true, dimension );
4088 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4090 // Negotiate all dimensions that require it
4091 ActorDimensionStack recursionStack;
4093 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4095 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4098 NegotiateDimension( dimension, allocatedSize, recursionStack );
4102 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4104 switch( mRelayoutData->sizeSetPolicy )
4106 case SizeScalePolicy::USE_SIZE_SET:
4111 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4113 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4114 const Vector3 naturalSize = GetNaturalSize();
4115 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4117 const float sizeRatio = size.width / size.height;
4118 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4120 if( naturalSizeRatio < sizeRatio )
4122 return Vector2( naturalSizeRatio * size.height, size.height );
4124 else if( naturalSizeRatio > sizeRatio )
4126 return Vector2( size.width, size.width / naturalSizeRatio );
4137 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4139 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4140 const Vector3 naturalSize = GetNaturalSize();
4141 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4143 const float sizeRatio = size.width / size.height;
4144 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4146 if( naturalSizeRatio < sizeRatio )
4148 return Vector2( size.width, size.width / naturalSizeRatio );
4150 else if( naturalSizeRatio > sizeRatio )
4152 return Vector2( naturalSizeRatio * size.height, size.height );
4171 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4173 // Do the set actor size
4174 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4176 // Adjust for size set policy
4177 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4179 // Lock the flag to stop recursive relayouts on set size
4180 mRelayoutData->insideRelayout = true;
4181 SetSize( negotiatedSize );
4182 mRelayoutData->insideRelayout = false;
4184 // Clear flags for all dimensions
4185 SetLayoutDirty( false );
4187 // Give deriving classes a chance to respond
4188 OnRelayout( negotiatedSize, container );
4190 if( !mOnRelayoutSignal.Empty() )
4192 Dali::Actor handle( this );
4193 mOnRelayoutSignal.Emit( handle );
4197 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4199 // Force a size negotiation for actors that has assigned size during relayout
4200 // This is required as otherwise the flags that force a relayout will not
4201 // necessarilly be set. This will occur if the actor has already been laid out.
4202 // The dirty flags are then cleared. Then if the actor is added back into the
4203 // relayout container afterwards, the dirty flags would still be clear...
4204 // causing a relayout to be skipped. Here we force any actors added to the
4205 // container to be relayed out.
4206 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4208 SetLayoutNegotiated(false, Dimension::WIDTH);
4210 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4212 SetLayoutNegotiated(false, Dimension::HEIGHT);
4215 // Do the negotiation
4216 NegotiateDimensions( allocatedSize );
4218 // Set the actor size
4219 SetNegotiatedSize( container );
4221 // Negotiate down to children
4222 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4224 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4226 ActorPtr child = GetChildAt( i );
4228 // Forces children that have already been laid out to be relayed out
4229 // if they have assigned size during relayout.
4230 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4232 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4233 child->SetLayoutDirty(true, Dimension::WIDTH);
4235 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4237 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4238 child->SetLayoutDirty(true, Dimension::HEIGHT);
4241 // Only relayout if required
4242 if( child->RelayoutRequired() )
4244 container.Add( Dali::Actor( child.Get() ), newBounds );
4249 void Actor::RelayoutRequest( Dimension::Type dimension )
4251 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4252 if( relayoutController )
4254 Dali::Actor self( this );
4255 relayoutController->RequestRelayout( self, dimension );
4259 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4263 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4267 void Actor::SetPreferredSize( const Vector2& size )
4269 EnsureRelayoutData();
4271 if( size.width > 0.0f )
4273 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4276 if( size.height > 0.0f )
4278 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4281 mRelayoutData->preferredSize = size;
4286 Vector2 Actor::GetPreferredSize() const
4288 if ( mRelayoutData )
4290 return Vector2( mRelayoutData->preferredSize );
4293 return GetDefaultPreferredSize();
4296 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4298 EnsureRelayoutData();
4300 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4302 if( dimension & ( 1 << i ) )
4304 mRelayoutData->minimumSize[ i ] = size;
4311 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4313 if ( mRelayoutData )
4315 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4317 if( dimension & ( 1 << i ) )
4319 return mRelayoutData->minimumSize[ i ];
4324 return 0.0f; // Default
4327 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4329 EnsureRelayoutData();
4331 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4333 if( dimension & ( 1 << i ) )
4335 mRelayoutData->maximumSize[ i ] = size;
4342 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4344 if ( mRelayoutData )
4346 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4348 if( dimension & ( 1 << i ) )
4350 return mRelayoutData->maximumSize[ i ];
4355 return FLT_MAX; // Default
4358 Object* Actor::GetParentObject() const
4363 } // namespace Internal