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 useAssignedSize[ i ] = false;
105 negotiatedDimensions[ i ] = 0.0f;
106 dimensionNegotiated[ i ] = false;
107 dimensionDirty[ i ] = false;
108 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
109 dimensionPadding[ i ] = GetDefaultDimensionPadding();
110 minimumSize[ i ] = 0.0f;
111 maximumSize[ i ] = FLT_MAX;
115 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
116 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
118 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
120 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
122 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
124 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
125 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
127 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
128 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
130 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
132 Vector2 preferredSize; ///< The preferred size of the actor
134 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
136 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
137 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
140 namespace // unnamed namespace
146 * We want to discourage the use of property strings (minimize string comparisons),
147 * particularly for the default properties.
148 * Name Type writable animatable constraint-input enum for index-checking
150 DALI_PROPERTY_TABLE_BEGIN
151 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
152 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
153 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
154 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
155 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
156 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
157 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
158 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
159 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
160 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
161 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
162 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
163 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
164 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
165 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
166 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
167 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
168 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
169 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
170 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
171 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
172 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
173 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
174 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
175 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
176 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
177 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
178 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
179 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
180 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
181 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
182 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
183 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
184 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
185 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
186 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
187 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
188 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
189 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
190 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
191 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
192 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
193 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
194 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
195 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
196 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
197 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
198 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
199 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
200 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
201 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
202 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
203 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
204 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
205 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
209 const char* const SIGNAL_TOUCHED = "touched";
210 const char* const SIGNAL_HOVERED = "hovered";
211 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
212 const char* const SIGNAL_ON_STAGE = "onStage";
213 const char* const SIGNAL_OFF_STAGE = "offStage";
214 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
215 const char* const SIGNAL_TOUCH = "touch";
219 const char* const ACTION_SHOW = "show";
220 const char* const ACTION_HIDE = "hide";
222 BaseHandle CreateActor()
224 return Dali::Actor::New();
227 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
229 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
232 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
233 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
234 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
235 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
237 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
238 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
243 const Vector3& value;
246 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
252 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
253 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
254 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
255 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
256 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
258 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
259 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
260 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
261 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
262 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
263 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
265 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
266 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
267 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
268 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
269 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
270 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
272 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
276 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
278 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
287 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
289 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
293 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
295 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
298 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
301 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
303 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
305 size_t sizeIgnored = 0;
306 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
308 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
315 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
317 // Values are the same so just use the same table as anchor-point
318 return GetAnchorPointConstant( value, parentOrigin );
322 * @brief Extract a given dimension from a Vector2
324 * @param[in] values The values to extract from
325 * @param[in] dimension The dimension to extract
326 * @return Return the value for the dimension
328 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
332 case Dimension::WIDTH:
336 case Dimension::HEIGHT:
338 return values.height;
349 * @brief Extract a given dimension from a Vector3
351 * @param[in] values The values to extract from
352 * @param[in] dimension The dimension to extract
353 * @return Return the value for the dimension
355 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
357 return GetDimensionValue( values.GetVectorXY(), dimension );
360 unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder )
362 return depth * Dali::DevelLayer::TREE_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
365 } // unnamed namespace
367 ActorPtr Actor::New()
369 ActorPtr actor( new Actor( BASIC ) );
371 // Second-phase construction
377 const std::string& Actor::GetName() const
382 void Actor::SetName( const std::string& name )
388 // ATTENTION: string for debug purposes is not thread safe.
389 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
393 unsigned int Actor::GetId() const
398 bool Actor::OnStage() const
403 Dali::Layer Actor::GetLayer()
407 // Short-circuit for Layer derived actors
410 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
413 // Find the immediate Layer parent
414 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
416 if( parent->IsLayer() )
418 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
425 void Actor::Add( Actor& child )
427 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
428 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
432 mChildren = new ActorContainer;
435 Actor* const oldParent( child.mParent );
437 // child might already be ours
438 if( this != oldParent )
440 // if we already have parent, unparent us first
443 oldParent->Remove( child ); // This causes OnChildRemove callback
445 // Old parent may need to readjust to missing child
446 if( oldParent->RelayoutDependentOnChildren() )
448 oldParent->RelayoutRequest();
452 // Guard against Add() during previous OnChildRemove callback
455 // Do this first, since user callbacks from within SetParent() may need to remove child
456 mChildren->push_back( ActorPtr( &child ) );
458 // SetParent asserts that child can be added
459 child.SetParent( this );
461 // Notification for derived classes
464 // Only put in a relayout request if there is a suitable dependency
465 if( RelayoutDependentOnChildren() )
473 void Actor::Remove( Actor& child )
475 if( (this == &child) || (!mChildren) )
477 // no children or removing itself
483 // Find the child in mChildren, and unparent it
484 ActorIter end = mChildren->end();
485 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
487 ActorPtr actor = (*iter);
489 if( actor.Get() == &child )
491 // Keep handle for OnChildRemove notification
494 // Do this first, since user callbacks from within SetParent() may need to add the child
495 mChildren->erase( iter );
497 DALI_ASSERT_DEBUG( actor->GetParent() == this );
498 actor->SetParent( NULL );
506 // Only put in a relayout request if there is a suitable dependency
507 if( RelayoutDependentOnChildren() )
513 // Notification for derived classes
514 OnChildRemove( child );
517 void Actor::Unparent()
521 // Remove this actor from the parent. The remove will put a relayout request in for
522 // the parent if required
523 mParent->Remove( *this );
524 // mParent is now NULL!
528 unsigned int Actor::GetChildCount() const
530 return ( NULL != mChildren ) ? mChildren->size() : 0;
533 ActorPtr Actor::GetChildAt( unsigned int index ) const
535 DALI_ASSERT_ALWAYS( index < GetChildCount() );
537 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
540 ActorPtr Actor::FindChildByName( const std::string& actorName )
543 if( actorName == mName )
549 ActorIter end = mChildren->end();
550 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
552 child = (*iter)->FindChildByName( actorName );
563 ActorPtr Actor::FindChildById( const unsigned int id )
572 ActorIter end = mChildren->end();
573 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
575 child = (*iter)->FindChildById( id );
586 void Actor::SetParentOrigin( const Vector3& origin )
590 // mNode is being used in a separate thread; queue a message to set the value & base value
591 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
594 // Cache for event-thread access
597 // not allocated, check if different from default
598 if( ParentOrigin::DEFAULT != origin )
600 mParentOrigin = new Vector3( origin );
605 // check if different from current costs more than just set
606 *mParentOrigin = origin;
610 void Actor::SetParentOriginX( float x )
612 const Vector3& current = GetCurrentParentOrigin();
614 SetParentOrigin( Vector3( x, current.y, current.z ) );
617 void Actor::SetParentOriginY( float y )
619 const Vector3& current = GetCurrentParentOrigin();
621 SetParentOrigin( Vector3( current.x, y, current.z ) );
624 void Actor::SetParentOriginZ( float z )
626 const Vector3& current = GetCurrentParentOrigin();
628 SetParentOrigin( Vector3( current.x, current.y, z ) );
631 const Vector3& Actor::GetCurrentParentOrigin() const
633 // Cached for event-thread access
634 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
637 void Actor::SetAnchorPoint( const Vector3& anchor )
641 // mNode is being used in a separate thread; queue a message to set the value & base value
642 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
645 // Cache for event-thread access
648 // not allocated, check if different from default
649 if( AnchorPoint::DEFAULT != anchor )
651 mAnchorPoint = new Vector3( anchor );
656 // check if different from current costs more than just set
657 *mAnchorPoint = anchor;
661 void Actor::SetAnchorPointX( float x )
663 const Vector3& current = GetCurrentAnchorPoint();
665 SetAnchorPoint( Vector3( x, current.y, current.z ) );
668 void Actor::SetAnchorPointY( float y )
670 const Vector3& current = GetCurrentAnchorPoint();
672 SetAnchorPoint( Vector3( current.x, y, current.z ) );
675 void Actor::SetAnchorPointZ( float z )
677 const Vector3& current = GetCurrentAnchorPoint();
679 SetAnchorPoint( Vector3( current.x, current.y, z ) );
682 const Vector3& Actor::GetCurrentAnchorPoint() const
684 // Cached for event-thread access
685 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
688 void Actor::SetPosition( float x, float y )
690 SetPosition( Vector3( x, y, 0.0f ) );
693 void Actor::SetPosition( float x, float y, float z )
695 SetPosition( Vector3( x, y, z ) );
698 void Actor::SetPosition( const Vector3& position )
700 mTargetPosition = position;
704 // mNode is being used in a separate thread; queue a message to set the value & base value
705 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
709 void Actor::SetX( float x )
711 mTargetPosition.x = x;
715 // mNode is being used in a separate thread; queue a message to set the value & base value
716 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
720 void Actor::SetY( float y )
722 mTargetPosition.y = y;
726 // mNode is being used in a separate thread; queue a message to set the value & base value
727 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
731 void Actor::SetZ( float z )
733 mTargetPosition.z = z;
737 // mNode is being used in a separate thread; queue a message to set the value & base value
738 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
742 void Actor::TranslateBy( const Vector3& distance )
744 mTargetPosition += distance;
748 // mNode is being used in a separate thread; queue a message to set the value & base value
749 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
753 const Vector3& Actor::GetCurrentPosition() const
757 // mNode is being used in a separate thread; copy the value from the previous update
758 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
761 return Vector3::ZERO;
764 const Vector3& Actor::GetTargetPosition() const
766 return mTargetPosition;
769 const Vector3& Actor::GetCurrentWorldPosition() const
773 // mNode is being used in a separate thread; copy the value from the previous update
774 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
777 return Vector3::ZERO;
780 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
782 // this flag is not animatable so keep the value
783 mPositionInheritanceMode = mode;
786 // mNode is being used in a separate thread; queue a message to set the value
787 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
791 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
793 // Cached for event-thread access
794 return mPositionInheritanceMode;
797 void Actor::SetInheritPosition( bool inherit )
799 if( mInheritPosition != inherit && NULL != mNode )
801 // non animateable so keep local copy
802 mInheritPosition = inherit;
803 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
807 bool Actor::IsPositionInherited() const
809 return mInheritPosition;
812 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
814 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
815 normalizedAxis.Normalize();
817 Quaternion orientation( angle, normalizedAxis );
819 SetOrientation( orientation );
822 void Actor::SetOrientation( const Quaternion& orientation )
826 // mNode is being used in a separate thread; queue a message to set the value & base value
827 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
831 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
835 // mNode is being used in a separate thread; queue a message to set the value & base value
836 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
840 void Actor::RotateBy( const Quaternion& relativeRotation )
844 // mNode is being used in a separate thread; queue a message to set the value & base value
845 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
849 const Quaternion& Actor::GetCurrentOrientation() const
853 // mNode is being used in a separate thread; copy the value from the previous update
854 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
857 return Quaternion::IDENTITY;
860 const Quaternion& Actor::GetCurrentWorldOrientation() const
864 // mNode is being used in a separate thread; copy the value from the previous update
865 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
868 return Quaternion::IDENTITY;
871 void Actor::SetScale( float scale )
873 SetScale( Vector3( scale, scale, scale ) );
876 void Actor::SetScale( float x, float y, float z )
878 SetScale( Vector3( x, y, z ) );
881 void Actor::SetScale( const Vector3& scale )
885 // mNode is being used in a separate thread; queue a message to set the value & base value
886 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
890 void Actor::SetScaleX( float x )
894 // mNode is being used in a separate thread; queue a message to set the value & base value
895 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
899 void Actor::SetScaleY( float y )
903 // mNode is being used in a separate thread; queue a message to set the value & base value
904 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
908 void Actor::SetScaleZ( float z )
912 // mNode is being used in a separate thread; queue a message to set the value & base value
913 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
917 void Actor::ScaleBy(const Vector3& relativeScale)
921 // mNode is being used in a separate thread; queue a message to set the value & base value
922 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
926 const Vector3& Actor::GetCurrentScale() const
930 // mNode is being used in a separate thread; copy the value from the previous update
931 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
937 const Vector3& Actor::GetCurrentWorldScale() const
941 // mNode is being used in a separate thread; copy the value from the previous update
942 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
948 void Actor::SetInheritScale( bool inherit )
951 if( mInheritScale != inherit && NULL != mNode )
953 // non animateable so keep local copy
954 mInheritScale = inherit;
955 // mNode is being used in a separate thread; queue a message to set the value
956 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
960 bool Actor::IsScaleInherited() const
962 return mInheritScale;
965 Matrix Actor::GetCurrentWorldMatrix() const
969 return mNode->GetWorldMatrix(0);
972 return Matrix::IDENTITY;
975 void Actor::SetVisible( bool visible )
979 // mNode is being used in a separate thread; queue a message to set the value & base value
980 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
984 bool Actor::IsVisible() const
988 // mNode is being used in a separate thread; copy the value from the previous update
989 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
995 void Actor::SetOpacity( float opacity )
999 // mNode is being used in a separate thread; queue a message to set the value & base value
1000 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1004 float Actor::GetCurrentOpacity() const
1008 // mNode is being used in a separate thread; copy the value from the previous update
1009 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1015 ClippingMode::Type Actor::GetClippingMode() const
1017 return mClippingMode;
1020 const Vector4& Actor::GetCurrentWorldColor() const
1024 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1027 return Color::WHITE;
1030 void Actor::SetColor( const Vector4& color )
1034 // mNode is being used in a separate thread; queue a message to set the value & base value
1035 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1039 void Actor::SetColorRed( float red )
1043 // mNode is being used in a separate thread; queue a message to set the value & base value
1044 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1048 void Actor::SetColorGreen( float green )
1052 // mNode is being used in a separate thread; queue a message to set the value & base value
1053 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1057 void Actor::SetColorBlue( float blue )
1061 // mNode is being used in a separate thread; queue a message to set the value & base value
1062 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1066 const Vector4& Actor::GetCurrentColor() const
1070 // mNode is being used in a separate thread; copy the value from the previous update
1071 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1074 return Color::WHITE;
1077 void Actor::SetInheritOrientation( bool inherit )
1079 if( mInheritOrientation != inherit && NULL != mNode)
1081 // non animateable so keep local copy
1082 mInheritOrientation = inherit;
1083 // mNode is being used in a separate thread; queue a message to set the value
1084 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1088 bool Actor::IsOrientationInherited() const
1090 return mInheritOrientation;
1093 void Actor::SetSizeModeFactor( const Vector3& factor )
1095 EnsureRelayoutData();
1097 mRelayoutData->sizeModeFactor = factor;
1100 const Vector3& Actor::GetSizeModeFactor() const
1102 if ( mRelayoutData )
1104 return mRelayoutData->sizeModeFactor;
1107 return GetDefaultSizeModeFactor();
1110 void Actor::SetColorMode( ColorMode colorMode )
1112 // non animateable so keep local copy
1113 mColorMode = colorMode;
1116 // mNode is being used in a separate thread; queue a message to set the value
1117 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1121 ColorMode Actor::GetColorMode() const
1123 // we have cached copy
1127 void Actor::SetSize( float width, float height )
1129 SetSize( Vector2( width, height ) );
1132 void Actor::SetSize( float width, float height, float depth )
1134 SetSize( Vector3( width, height, depth ) );
1137 void Actor::SetSize( const Vector2& size )
1139 SetSize( Vector3( size.width, size.height, 0.f ) );
1142 void Actor::SetSizeInternal( const Vector2& size )
1144 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1147 void Actor::SetSize( const Vector3& size )
1149 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1151 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1152 SetPreferredSize( size.GetVectorXY() );
1156 SetSizeInternal( size );
1160 void Actor::SetSizeInternal( const Vector3& size )
1162 // dont allow recursive loop
1163 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1164 // 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
1165 if( ( NULL != mNode )&&
1166 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1167 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1168 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1172 // mNode is being used in a separate thread; queue a message to set the value & base value
1173 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1175 // Notification for derived classes
1176 mInsideOnSizeSet = true;
1177 OnSizeSet( mTargetSize );
1178 mInsideOnSizeSet = false;
1180 // Raise a relayout request if the flag is not locked
1181 if( mRelayoutData && !mRelayoutData->insideRelayout )
1188 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1190 mTargetSize = targetSize;
1192 // Notify deriving classes
1193 OnSizeAnimation( animation, mTargetSize );
1196 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1198 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1200 mTargetSize.width = targetSize;
1202 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1204 mTargetSize.height = targetSize;
1206 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1208 mTargetSize.depth = targetSize;
1210 // Notify deriving classes
1211 OnSizeAnimation( animation, mTargetSize );
1214 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1216 mTargetPosition = targetPosition;
1219 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1221 if ( Dali::Actor::Property::POSITION_X == property )
1223 mTargetPosition.x = targetPosition;
1225 else if ( Dali::Actor::Property::POSITION_Y == property )
1227 mTargetPosition.y = targetPosition;
1229 else if ( Dali::Actor::Property::POSITION_Z == property )
1231 mTargetPosition.z = targetPosition;
1235 void Actor::SetWidth( float width )
1237 mTargetSize.width = width;
1241 // mNode is being used in a separate thread; queue a message to set the value & base value
1242 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1246 void Actor::SetHeight( float height )
1248 mTargetSize.height = height;
1252 // mNode is being used in a separate thread; queue a message to set the value & base value
1253 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1257 void Actor::SetDepth( float depth )
1259 mTargetSize.depth = depth;
1263 // mNode is being used in a separate thread; queue a message to set the value & base value
1264 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1268 const Vector3& Actor::GetTargetSize() const
1273 const Vector3& Actor::GetCurrentSize() const
1277 // mNode is being used in a separate thread; copy the value from the previous update
1278 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1281 return Vector3::ZERO;
1284 Vector3 Actor::GetNaturalSize() const
1286 // It is up to deriving classes to return the appropriate natural size
1287 return Vector3( 0.0f, 0.0f, 0.0f );
1290 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1292 EnsureRelayoutData();
1294 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1296 if( dimension & ( 1 << i ) )
1298 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1300 mRelayoutData->useAssignedSize[ i ] = true;
1304 mRelayoutData->resizePolicies[ i ] = policy;
1305 mRelayoutData->useAssignedSize[ i ] = false;
1310 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1312 if( dimension & Dimension::WIDTH )
1314 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1317 if( dimension & Dimension::HEIGHT )
1319 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1323 // If calling SetResizePolicy, assume we want relayout enabled
1324 SetRelayoutEnabled( true );
1326 OnSetResizePolicy( policy, dimension );
1328 // Trigger relayout on this control
1332 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1334 if ( mRelayoutData )
1336 // If more than one dimension is requested, just return the first one found
1337 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1339 if( ( dimension & ( 1 << i ) ) )
1341 if( mRelayoutData->useAssignedSize[ i ] )
1343 return ResizePolicy::USE_ASSIGNED_SIZE;
1347 return mRelayoutData->resizePolicies[ i ];
1353 return ResizePolicy::DEFAULT;
1356 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1358 EnsureRelayoutData();
1360 mRelayoutData->sizeSetPolicy = policy;
1363 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1365 if ( mRelayoutData )
1367 return mRelayoutData->sizeSetPolicy;
1370 return DEFAULT_SIZE_SCALE_POLICY;
1373 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1375 EnsureRelayoutData();
1377 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1379 if( dimension & ( 1 << i ) )
1381 mRelayoutData->dimensionDependencies[ i ] = dependency;
1386 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1388 if ( mRelayoutData )
1390 // If more than one dimension is requested, just return the first one found
1391 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1393 if( ( dimension & ( 1 << i ) ) )
1395 return mRelayoutData->dimensionDependencies[ i ];
1400 return Dimension::ALL_DIMENSIONS; // Default
1403 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1405 // If relayout data has not been allocated yet and the client is requesting
1406 // to disable it, do nothing
1407 if( mRelayoutData || relayoutEnabled )
1409 EnsureRelayoutData();
1411 mRelayoutData->relayoutEnabled = relayoutEnabled;
1415 bool Actor::IsRelayoutEnabled() const
1417 // Assume that if relayout data has not been allocated yet then
1418 // relayout is disabled
1419 return mRelayoutData && mRelayoutData->relayoutEnabled;
1422 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1424 EnsureRelayoutData();
1426 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1428 if( dimension & ( 1 << i ) )
1430 mRelayoutData->dimensionDirty[ i ] = dirty;
1435 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1437 if ( mRelayoutData )
1439 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1441 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1451 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1453 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1456 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1458 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1461 unsigned int Actor::AddRenderer( Renderer& renderer )
1465 mRenderers = new RendererContainer;
1468 unsigned int index = mRenderers->size();
1469 RendererPtr rendererPtr = RendererPtr( &renderer );
1470 mRenderers->push_back( rendererPtr );
1471 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1475 rendererPtr->Connect();
1481 unsigned int Actor::GetRendererCount() const
1483 unsigned int rendererCount(0);
1486 rendererCount = mRenderers->size();
1489 return rendererCount;
1492 RendererPtr Actor::GetRendererAt( unsigned int index )
1494 RendererPtr renderer;
1495 if( index < GetRendererCount() )
1497 renderer = ( *mRenderers )[ index ];
1503 void Actor::RemoveRenderer( Renderer& renderer )
1507 RendererIter end = mRenderers->end();
1508 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1510 if( (*iter).Get() == &renderer )
1512 mRenderers->erase( iter );
1513 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1520 void Actor::RemoveRenderer( unsigned int index )
1522 if( index < GetRendererCount() )
1524 RendererPtr renderer = ( *mRenderers )[ index ];
1525 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1526 mRenderers->erase( mRenderers->begin()+index );
1530 bool Actor::IsOverlay() const
1532 return ( DrawMode::OVERLAY_2D == mDrawMode );
1535 void Actor::SetDrawMode( DrawMode::Type drawMode )
1537 // this flag is not animatable so keep the value
1538 mDrawMode = drawMode;
1539 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1541 // mNode is being used in a separate thread; queue a message to set the value
1542 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1546 DrawMode::Type Actor::GetDrawMode() const
1551 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1553 // only valid when on-stage
1554 StagePtr stage = Stage::GetCurrent();
1555 if( stage && OnStage() )
1557 const RenderTaskList& taskList = stage->GetRenderTaskList();
1559 Vector2 converted( screenX, screenY );
1561 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1562 const int taskCount = taskList.GetTaskCount();
1563 for( int i = taskCount - 1; i >= 0; --i )
1565 Dali::RenderTask task = taskList.GetTask( i );
1566 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1568 // found a task where this conversion was ok so return
1576 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1578 bool retval = false;
1579 // only valid when on-stage
1582 CameraActor* camera = renderTask.GetCameraActor();
1586 renderTask.GetViewport( viewport );
1588 // need to translate coordinates to render tasks coordinate space
1589 Vector2 converted( screenX, screenY );
1590 if( renderTask.TranslateCoordinates( converted ) )
1592 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1599 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1601 // Early-out if mNode is NULL
1607 // Get the ModelView matrix
1609 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1611 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1612 Matrix invertedMvp( false/*don't init*/);
1613 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1614 bool success = invertedMvp.Invert();
1616 // Convert to GL coordinates
1617 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1622 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1629 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1635 if( XyPlaneIntersect( nearPos, farPos, local ) )
1637 Vector3 size = GetCurrentSize();
1638 localX = local.x + size.x * 0.5f;
1639 localY = local.y + size.y * 0.5f;
1650 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1653 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1655 Mathematical Formulation
1657 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1659 ( p - c ) dot ( p - c ) = r^2
1661 Given a ray with a point of origin 'o', and a direction vector 'd':
1663 ray(t) = o + td, t >= 0
1665 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1667 (o + td - c ) dot ( o + td - c ) = r^2
1669 To solve for t we first expand the above into a more recognisable quadratic equation form
1671 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1680 B = 2( o - c ) dot d
1681 C = ( o - c ) dot ( o - c ) - r^2
1683 which can be solved using a standard quadratic formula.
1685 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1687 Practical Simplification
1689 In a renderer, we often differentiate between world space and object space. In the object space
1690 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1691 into object space, the mathematical solution presented above can be simplified significantly.
1693 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1697 and we can find the t at which the (transformed) ray intersects the sphere by
1699 ( o + td ) dot ( o + td ) = r^2
1701 According to the reasoning above, we expand the above quadratic equation into the general form
1705 which now has coefficients:
1712 // Early out if mNode is NULL
1718 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1720 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1721 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1722 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1724 // Compute the radius is not needed, square radius it's enough.
1725 const Vector3& size( mNode->GetSize( bufferIndex ) );
1727 // Scale the sphere.
1728 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1730 const float width = size.width * scale.width;
1731 const float height = size.height * scale.height;
1733 float squareSphereRadius = 0.5f * ( width * width + height * height );
1735 float a = rayDir.Dot( rayDir ); // a
1736 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1737 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1739 return ( b2 * b2 - a * c ) >= 0.f;
1742 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1746 if( OnStage() && NULL != mNode )
1748 // Transforms the ray to the local reference system.
1749 // Calculate the inverse of Model matrix
1750 Matrix invModelMatrix( false/*don't init*/);
1752 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1753 invModelMatrix = mNode->GetWorldMatrix(0);
1754 invModelMatrix.Invert();
1756 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1757 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1759 // Test with the actor's XY plane (Normal = 0 0 1 1).
1761 float a = -rayOriginLocal.z;
1762 float b = rayDirLocal.z;
1764 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1766 // Ray travels distance * rayDirLocal to intersect with plane.
1769 const Vector3& size = mNode->GetSize( bufferIndex );
1771 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1772 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1774 // Test with the actor's geometry.
1775 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1782 void Actor::SetLeaveRequired( bool required )
1784 mLeaveRequired = required;
1787 bool Actor::GetLeaveRequired() const
1789 return mLeaveRequired;
1792 void Actor::SetKeyboardFocusable( bool focusable )
1794 mKeyboardFocusable = focusable;
1797 bool Actor::IsKeyboardFocusable() const
1799 return mKeyboardFocusable;
1802 bool Actor::GetTouchRequired() const
1804 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1807 bool Actor::GetHoverRequired() const
1809 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1812 bool Actor::GetWheelEventRequired() const
1814 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1817 bool Actor::IsHittable() const
1819 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1822 ActorGestureData& Actor::GetGestureData()
1824 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1825 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1826 if( NULL == mGestureData )
1828 mGestureData = new ActorGestureData;
1830 return *mGestureData;
1833 bool Actor::IsGestureRequred( Gesture::Type type ) const
1835 return mGestureData && mGestureData->IsGestureRequred( type );
1838 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1840 bool consumed = false;
1842 if( !mTouchSignal.Empty() )
1844 Dali::Actor handle( this );
1845 consumed = mTouchSignal.Emit( handle, touch );
1848 if( !mTouchedSignal.Empty() )
1850 Dali::Actor handle( this );
1851 consumed |= mTouchedSignal.Emit( handle, event );
1856 // Notification for derived classes
1857 consumed = OnTouchEvent( event ); // TODO
1863 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1865 bool consumed = false;
1867 if( !mHoveredSignal.Empty() )
1869 Dali::Actor handle( this );
1870 consumed = mHoveredSignal.Emit( handle, event );
1875 // Notification for derived classes
1876 consumed = OnHoverEvent( event );
1882 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1884 bool consumed = false;
1886 if( !mWheelEventSignal.Empty() )
1888 Dali::Actor handle( this );
1889 consumed = mWheelEventSignal.Emit( handle, event );
1894 // Notification for derived classes
1895 consumed = OnWheelEvent( event );
1901 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1903 return mTouchedSignal;
1906 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1908 return mTouchSignal;
1911 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1913 return mHoveredSignal;
1916 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1918 return mWheelEventSignal;
1921 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1923 return mOnStageSignal;
1926 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1928 return mOffStageSignal;
1931 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1933 return mOnRelayoutSignal;
1936 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1938 bool connected( true );
1939 Actor* actor = dynamic_cast< Actor* >( object );
1941 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1943 actor->TouchedSignal().Connect( tracker, functor );
1945 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1947 actor->HoveredSignal().Connect( tracker, functor );
1949 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1951 actor->WheelEventSignal().Connect( tracker, functor );
1953 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1955 actor->OnStageSignal().Connect( tracker, functor );
1957 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1959 actor->OffStageSignal().Connect( tracker, functor );
1961 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1963 actor->OnRelayoutSignal().Connect( tracker, functor );
1965 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1967 actor->TouchSignal().Connect( tracker, functor );
1971 // signalName does not match any signal
1978 Actor::Actor( DerivedType derivedType )
1983 mParentOrigin( NULL ),
1984 mAnchorPoint( NULL ),
1985 mRelayoutData( NULL ),
1986 mGestureData( NULL ),
1987 mTargetSize( 0.0f, 0.0f, 0.0f ),
1989 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1992 mIsRoot( ROOT_LAYER == derivedType ),
1993 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1994 mIsOnStage( false ),
1996 mLeaveRequired( false ),
1997 mKeyboardFocusable( false ),
1998 mDerivedRequiresTouch( false ),
1999 mDerivedRequiresHover( false ),
2000 mDerivedRequiresWheelEvent( false ),
2001 mOnStageSignalled( false ),
2002 mInsideOnSizeSet( false ),
2003 mInheritPosition( true ),
2004 mInheritOrientation( true ),
2005 mInheritScale( true ),
2006 mDrawMode( DrawMode::NORMAL ),
2007 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2008 mColorMode( Node::DEFAULT_COLOR_MODE ),
2009 mClippingMode( ClippingMode::DISABLED )
2013 void Actor::Initialize()
2016 SceneGraph::Node* node = CreateNode();
2018 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2019 mNode = node; // Keep raw-pointer to Node
2023 GetEventThreadServices().RegisterObject( this );
2028 // Remove mParent pointers from children even if we're destroying core,
2029 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2032 ActorConstIter endIter = mChildren->end();
2033 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2035 (*iter)->SetParent( NULL );
2041 // Guard to allow handle destruction after Core has been destroyed
2042 if( EventThreadServices::IsCoreRunning() )
2046 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2047 mNode = NULL; // Node is about to be destroyed
2050 GetEventThreadServices().UnregisterObject( this );
2053 // Cleanup optional gesture data
2054 delete mGestureData;
2056 // Cleanup optional parent origin and anchor
2057 delete mParentOrigin;
2058 delete mAnchorPoint;
2060 // Delete optional relayout data
2063 delete mRelayoutData;
2067 void Actor::ConnectToStage( unsigned int parentDepth )
2069 // This container is used instead of walking the Actor hierarchy.
2070 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2071 ActorContainer connectionList;
2073 // This stage is atomic i.e. not interrupted by user callbacks.
2074 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2076 // Notify applications about the newly connected actors.
2077 const ActorIter endIter = connectionList.end();
2078 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2080 (*iter)->NotifyStageConnection();
2086 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2088 DALI_ASSERT_ALWAYS( !OnStage() );
2092 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2094 ConnectToSceneGraph();
2096 // Notification for internal derived classes
2097 OnStageConnectionInternal();
2099 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2100 connectionList.push_back( ActorPtr( this ) );
2102 // Recursively connect children
2105 ActorConstIter endIter = mChildren->end();
2106 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2108 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2114 * This method is called when the Actor is connected to the Stage.
2115 * The parent must have added its Node to the scene-graph.
2116 * The child must connect its Node to the parent's Node.
2117 * This is recursive; the child calls ConnectToStage() for its children.
2119 void Actor::ConnectToSceneGraph()
2121 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2125 // Reparent Node in next Update
2126 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2129 unsigned int rendererCount( GetRendererCount() );
2130 for( unsigned int i(0); i<rendererCount; ++i )
2132 GetRendererAt(i)->Connect();
2135 // Request relayout on all actors that are added to the scenegraph
2138 // Notification for Object::Observers
2142 void Actor::NotifyStageConnection()
2144 // Actors can be removed (in a callback), before the on-stage stage is reported.
2145 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2146 if( OnStage() && !mOnStageSignalled )
2148 // Notification for external (CustomActor) derived classes
2149 OnStageConnectionExternal( mDepth );
2151 if( !mOnStageSignal.Empty() )
2153 Dali::Actor handle( this );
2154 mOnStageSignal.Emit( handle );
2157 // Guard against Remove during callbacks
2160 mOnStageSignalled = true; // signal required next time Actor is removed
2165 void Actor::DisconnectFromStage()
2167 // This container is used instead of walking the Actor hierachy.
2168 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2169 ActorContainer disconnectionList;
2171 // This stage is atomic i.e. not interrupted by user callbacks
2172 RecursiveDisconnectFromStage( disconnectionList );
2174 // Notify applications about the newly disconnected actors.
2175 const ActorIter endIter = disconnectionList.end();
2176 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2178 (*iter)->NotifyStageDisconnection();
2182 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2184 DALI_ASSERT_ALWAYS( OnStage() );
2186 // Recursively disconnect children
2189 ActorConstIter endIter = mChildren->end();
2190 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2192 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2196 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2197 disconnectionList.push_back( ActorPtr( this ) );
2199 // Notification for internal derived classes
2200 OnStageDisconnectionInternal();
2202 DisconnectFromSceneGraph();
2208 * This method is called by an actor or its parent, before a node removal message is sent.
2209 * This is recursive; the child calls DisconnectFromStage() for its children.
2211 void Actor::DisconnectFromSceneGraph()
2213 // Notification for Object::Observers
2214 OnSceneObjectRemove();
2216 unsigned int rendererCount( GetRendererCount() );
2217 for( unsigned int i(0); i<rendererCount; ++i )
2219 GetRendererAt(i)->Disconnect();
2223 void Actor::NotifyStageDisconnection()
2225 // Actors can be added (in a callback), before the off-stage state is reported.
2226 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2227 // only do this step if there is a stage, i.e. Core is not being shut down
2228 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2230 // Notification for external (CustomeActor) derived classes
2231 OnStageDisconnectionExternal();
2233 if( !mOffStageSignal.Empty() )
2235 Dali::Actor handle( this );
2236 mOffStageSignal.Emit( handle );
2239 // Guard against Add during callbacks
2242 mOnStageSignalled = false; // signal required next time Actor is added
2247 bool Actor::IsNodeConnected() const
2249 bool connected( false );
2251 if( OnStage() && ( NULL != mNode ) )
2253 if( IsRoot() || mNode->GetParent() )
2262 unsigned int Actor::GetDefaultPropertyCount() const
2264 return DEFAULT_PROPERTY_COUNT;
2267 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2269 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2271 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2273 indices.PushBack( i );
2277 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2279 if( index < DEFAULT_PROPERTY_COUNT )
2281 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2287 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2289 Property::Index index = Property::INVALID_INDEX;
2291 // Look for name in default properties
2292 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2294 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2295 if( 0 == name.compare( property->name ) )
2305 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2307 if( index < DEFAULT_PROPERTY_COUNT )
2309 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2315 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2317 if( index < DEFAULT_PROPERTY_COUNT )
2319 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2325 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2327 if( index < DEFAULT_PROPERTY_COUNT )
2329 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2335 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2337 if( index < DEFAULT_PROPERTY_COUNT )
2339 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2342 // index out of range...return Property::NONE
2343 return Property::NONE;
2346 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2350 case Dali::Actor::Property::PARENT_ORIGIN:
2352 Property::Type type = property.GetType();
2353 if( type == Property::VECTOR3 )
2355 SetParentOrigin( property.Get< Vector3 >() );
2357 else if ( type == Property::STRING )
2359 std::string parentOriginString;
2360 property.Get( parentOriginString );
2361 Vector3 parentOrigin;
2362 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2364 SetParentOrigin( parentOrigin );
2370 case Dali::Actor::Property::PARENT_ORIGIN_X:
2372 SetParentOriginX( property.Get< float >() );
2376 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2378 SetParentOriginY( property.Get< float >() );
2382 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2384 SetParentOriginZ( property.Get< float >() );
2388 case Dali::Actor::Property::ANCHOR_POINT:
2390 Property::Type type = property.GetType();
2391 if( type == Property::VECTOR3 )
2393 SetAnchorPoint( property.Get< Vector3 >() );
2395 else if ( type == Property::STRING )
2397 std::string anchorPointString;
2398 property.Get( anchorPointString );
2400 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2402 SetAnchorPoint( anchor );
2408 case Dali::Actor::Property::ANCHOR_POINT_X:
2410 SetAnchorPointX( property.Get< float >() );
2414 case Dali::Actor::Property::ANCHOR_POINT_Y:
2416 SetAnchorPointY( property.Get< float >() );
2420 case Dali::Actor::Property::ANCHOR_POINT_Z:
2422 SetAnchorPointZ( property.Get< float >() );
2426 case Dali::Actor::Property::SIZE:
2428 SetSize( property.Get< Vector3 >() );
2432 case Dali::Actor::Property::SIZE_WIDTH:
2434 SetWidth( property.Get< float >() );
2438 case Dali::Actor::Property::SIZE_HEIGHT:
2440 SetHeight( property.Get< float >() );
2444 case Dali::Actor::Property::SIZE_DEPTH:
2446 SetDepth( property.Get< float >() );
2450 case Dali::Actor::Property::POSITION:
2452 SetPosition( property.Get< Vector3 >() );
2456 case Dali::Actor::Property::POSITION_X:
2458 SetX( property.Get< float >() );
2462 case Dali::Actor::Property::POSITION_Y:
2464 SetY( property.Get< float >() );
2468 case Dali::Actor::Property::POSITION_Z:
2470 SetZ( property.Get< float >() );
2474 case Dali::Actor::Property::ORIENTATION:
2476 SetOrientation( property.Get< Quaternion >() );
2480 case Dali::Actor::Property::SCALE:
2482 SetScale( property.Get< Vector3 >() );
2486 case Dali::Actor::Property::SCALE_X:
2488 SetScaleX( property.Get< float >() );
2492 case Dali::Actor::Property::SCALE_Y:
2494 SetScaleY( property.Get< float >() );
2498 case Dali::Actor::Property::SCALE_Z:
2500 SetScaleZ( property.Get< float >() );
2504 case Dali::Actor::Property::VISIBLE:
2506 SetVisible( property.Get< bool >() );
2510 case Dali::Actor::Property::COLOR:
2512 SetColor( property.Get< Vector4 >() );
2516 case Dali::Actor::Property::COLOR_RED:
2518 SetColorRed( property.Get< float >() );
2522 case Dali::Actor::Property::COLOR_GREEN:
2524 SetColorGreen( property.Get< float >() );
2528 case Dali::Actor::Property::COLOR_BLUE:
2530 SetColorBlue( property.Get< float >() );
2534 case Dali::Actor::Property::COLOR_ALPHA:
2536 SetOpacity( property.Get< float >() );
2540 case Dali::Actor::Property::NAME:
2542 SetName( property.Get< std::string >() );
2546 case Dali::Actor::Property::SENSITIVE:
2548 SetSensitive( property.Get< bool >() );
2552 case Dali::Actor::Property::LEAVE_REQUIRED:
2554 SetLeaveRequired( property.Get< bool >() );
2558 case Dali::Actor::Property::INHERIT_POSITION:
2560 SetInheritPosition( property.Get< bool >() );
2564 case Dali::Actor::Property::INHERIT_ORIENTATION:
2566 SetInheritOrientation( property.Get< bool >() );
2570 case Dali::Actor::Property::INHERIT_SCALE:
2572 SetInheritScale( property.Get< bool >() );
2576 case Dali::Actor::Property::COLOR_MODE:
2579 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2581 SetColorMode( mode );
2586 case Dali::Actor::Property::POSITION_INHERITANCE:
2588 PositionInheritanceMode mode;
2589 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2591 SetPositionInheritanceMode( mode );
2596 case Dali::Actor::Property::DRAW_MODE:
2598 DrawMode::Type mode;
2599 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2601 SetDrawMode( mode );
2606 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2608 SetSizeModeFactor( property.Get< Vector3 >() );
2612 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2614 ResizePolicy::Type type;
2615 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2617 SetResizePolicy( type, Dimension::WIDTH );
2622 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2624 ResizePolicy::Type type;
2625 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2627 SetResizePolicy( type, Dimension::HEIGHT );
2632 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2634 SizeScalePolicy::Type type;
2635 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2637 SetSizeScalePolicy( type );
2642 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2644 if( property.Get< bool >() )
2646 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2651 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2653 if( property.Get< bool >() )
2655 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2660 case Dali::Actor::Property::PADDING:
2662 Vector4 padding = property.Get< Vector4 >();
2663 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2664 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2668 case Dali::Actor::Property::MINIMUM_SIZE:
2670 Vector2 size = property.Get< Vector2 >();
2671 SetMinimumSize( size.x, Dimension::WIDTH );
2672 SetMinimumSize( size.y, Dimension::HEIGHT );
2676 case Dali::Actor::Property::MAXIMUM_SIZE:
2678 Vector2 size = property.Get< Vector2 >();
2679 SetMaximumSize( size.x, Dimension::WIDTH );
2680 SetMaximumSize( size.y, Dimension::HEIGHT );
2684 case Dali::DevelActor::Property::SIBLING_ORDER:
2688 if( property.Get( value ) )
2690 if( static_cast<unsigned int>(value) != mSiblingOrder )
2692 mSiblingOrder = value;
2695 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2702 case Dali::Actor::Property::CLIPPING_MODE:
2704 ClippingMode::Type convertedValue = mClippingMode;
2705 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2707 mClippingMode = convertedValue;
2710 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2718 // this can happen in the case of a non-animatable default property so just do nothing
2724 // TODO: This method needs to be removed
2725 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2727 switch( entry.GetType() )
2729 case Property::BOOLEAN:
2731 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2732 DALI_ASSERT_DEBUG( NULL != property );
2734 // property is being used in a separate thread; queue a message to set the property
2735 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2740 case Property::INTEGER:
2742 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2743 DALI_ASSERT_DEBUG( NULL != property );
2745 // property is being used in a separate thread; queue a message to set the property
2746 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2751 case Property::FLOAT:
2753 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2754 DALI_ASSERT_DEBUG( NULL != property );
2756 // property is being used in a separate thread; queue a message to set the property
2757 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2762 case Property::VECTOR2:
2764 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2765 DALI_ASSERT_DEBUG( NULL != property );
2767 // property is being used in a separate thread; queue a message to set the property
2768 if(entry.componentIndex == 0)
2770 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2772 else if(entry.componentIndex == 1)
2774 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2778 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2784 case Property::VECTOR3:
2786 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2787 DALI_ASSERT_DEBUG( NULL != property );
2789 // property is being used in a separate thread; queue a message to set the property
2790 if(entry.componentIndex == 0)
2792 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2794 else if(entry.componentIndex == 1)
2796 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2798 else if(entry.componentIndex == 2)
2800 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2804 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2810 case Property::VECTOR4:
2812 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2813 DALI_ASSERT_DEBUG( NULL != property );
2815 // property is being used in a separate thread; queue a message to set the property
2816 if(entry.componentIndex == 0)
2818 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2820 else if(entry.componentIndex == 1)
2822 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2824 else if(entry.componentIndex == 2)
2826 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2828 else if(entry.componentIndex == 3)
2830 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2834 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2840 case Property::ROTATION:
2842 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2843 DALI_ASSERT_DEBUG( NULL != property );
2845 // property is being used in a separate thread; queue a message to set the property
2846 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2851 case Property::MATRIX:
2853 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2854 DALI_ASSERT_DEBUG( NULL != property );
2856 // property is being used in a separate thread; queue a message to set the property
2857 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2862 case Property::MATRIX3:
2864 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2865 DALI_ASSERT_DEBUG( NULL != property );
2867 // property is being used in a separate thread; queue a message to set the property
2868 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2875 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2881 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2883 Property::Value value;
2887 case Dali::Actor::Property::PARENT_ORIGIN:
2889 value = GetCurrentParentOrigin();
2893 case Dali::Actor::Property::PARENT_ORIGIN_X:
2895 value = GetCurrentParentOrigin().x;
2899 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2901 value = GetCurrentParentOrigin().y;
2905 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2907 value = GetCurrentParentOrigin().z;
2911 case Dali::Actor::Property::ANCHOR_POINT:
2913 value = GetCurrentAnchorPoint();
2917 case Dali::Actor::Property::ANCHOR_POINT_X:
2919 value = GetCurrentAnchorPoint().x;
2923 case Dali::Actor::Property::ANCHOR_POINT_Y:
2925 value = GetCurrentAnchorPoint().y;
2929 case Dali::Actor::Property::ANCHOR_POINT_Z:
2931 value = GetCurrentAnchorPoint().z;
2935 case Dali::Actor::Property::SIZE:
2937 value = GetTargetSize();
2941 case Dali::Actor::Property::SIZE_WIDTH:
2943 value = GetTargetSize().width;
2947 case Dali::Actor::Property::SIZE_HEIGHT:
2949 value = GetTargetSize().height;
2953 case Dali::Actor::Property::SIZE_DEPTH:
2955 value = GetTargetSize().depth;
2959 case Dali::Actor::Property::POSITION:
2961 value = GetTargetPosition();
2965 case Dali::Actor::Property::POSITION_X:
2967 value = GetTargetPosition().x;
2971 case Dali::Actor::Property::POSITION_Y:
2973 value = GetTargetPosition().y;
2977 case Dali::Actor::Property::POSITION_Z:
2979 value = GetTargetPosition().z;
2983 case Dali::Actor::Property::WORLD_POSITION:
2985 value = GetCurrentWorldPosition();
2989 case Dali::Actor::Property::WORLD_POSITION_X:
2991 value = GetCurrentWorldPosition().x;
2995 case Dali::Actor::Property::WORLD_POSITION_Y:
2997 value = GetCurrentWorldPosition().y;
3001 case Dali::Actor::Property::WORLD_POSITION_Z:
3003 value = GetCurrentWorldPosition().z;
3007 case Dali::Actor::Property::ORIENTATION:
3009 value = GetCurrentOrientation();
3013 case Dali::Actor::Property::WORLD_ORIENTATION:
3015 value = GetCurrentWorldOrientation();
3019 case Dali::Actor::Property::SCALE:
3021 value = GetCurrentScale();
3025 case Dali::Actor::Property::SCALE_X:
3027 value = GetCurrentScale().x;
3031 case Dali::Actor::Property::SCALE_Y:
3033 value = GetCurrentScale().y;
3037 case Dali::Actor::Property::SCALE_Z:
3039 value = GetCurrentScale().z;
3043 case Dali::Actor::Property::WORLD_SCALE:
3045 value = GetCurrentWorldScale();
3049 case Dali::Actor::Property::VISIBLE:
3051 value = IsVisible();
3055 case Dali::Actor::Property::COLOR:
3057 value = GetCurrentColor();
3061 case Dali::Actor::Property::COLOR_RED:
3063 value = GetCurrentColor().r;
3067 case Dali::Actor::Property::COLOR_GREEN:
3069 value = GetCurrentColor().g;
3073 case Dali::Actor::Property::COLOR_BLUE:
3075 value = GetCurrentColor().b;
3079 case Dali::Actor::Property::COLOR_ALPHA:
3081 value = GetCurrentColor().a;
3085 case Dali::Actor::Property::WORLD_COLOR:
3087 value = GetCurrentWorldColor();
3091 case Dali::Actor::Property::WORLD_MATRIX:
3093 value = GetCurrentWorldMatrix();
3097 case Dali::Actor::Property::NAME:
3103 case Dali::Actor::Property::SENSITIVE:
3105 value = IsSensitive();
3109 case Dali::Actor::Property::LEAVE_REQUIRED:
3111 value = GetLeaveRequired();
3115 case Dali::Actor::Property::INHERIT_POSITION:
3117 value = IsPositionInherited();
3121 case Dali::Actor::Property::INHERIT_ORIENTATION:
3123 value = IsOrientationInherited();
3127 case Dali::Actor::Property::INHERIT_SCALE:
3129 value = IsScaleInherited();
3133 case Dali::Actor::Property::COLOR_MODE:
3135 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3139 case Dali::Actor::Property::POSITION_INHERITANCE:
3141 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3145 case Dali::Actor::Property::DRAW_MODE:
3147 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3151 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3153 value = GetSizeModeFactor();
3157 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3159 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3163 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3165 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3169 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3171 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3175 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3177 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3181 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3183 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3187 case Dali::Actor::Property::PADDING:
3189 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3190 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3191 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3195 case Dali::Actor::Property::MINIMUM_SIZE:
3197 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3201 case Dali::Actor::Property::MAXIMUM_SIZE:
3203 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3207 case Dali::Actor::Property::CLIPPING_MODE:
3209 value = mClippingMode;
3213 case Dali::DevelActor::Property::SIBLING_ORDER:
3215 value = static_cast<int>(mSiblingOrder);
3221 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3229 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3234 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3236 // This method should only return an object connected to the scene-graph
3237 return OnStage() ? mNode : NULL;
3240 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3242 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3244 const PropertyBase* property( NULL );
3246 // This method should only return a property of an object connected to the scene-graph
3252 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3254 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3255 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3257 property = animatable->GetSceneGraphProperty();
3259 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3260 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3262 CustomPropertyMetadata* custom = FindCustomProperty( index );
3263 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3265 property = custom->GetSceneGraphProperty();
3267 else if( NULL != mNode )
3271 case Dali::Actor::Property::SIZE:
3272 property = &mNode->mSize;
3275 case Dali::Actor::Property::SIZE_WIDTH:
3276 property = &mNode->mSize;
3279 case Dali::Actor::Property::SIZE_HEIGHT:
3280 property = &mNode->mSize;
3283 case Dali::Actor::Property::SIZE_DEPTH:
3284 property = &mNode->mSize;
3287 case Dali::Actor::Property::POSITION:
3288 property = &mNode->mPosition;
3291 case Dali::Actor::Property::POSITION_X:
3292 property = &mNode->mPosition;
3295 case Dali::Actor::Property::POSITION_Y:
3296 property = &mNode->mPosition;
3299 case Dali::Actor::Property::POSITION_Z:
3300 property = &mNode->mPosition;
3303 case Dali::Actor::Property::ORIENTATION:
3304 property = &mNode->mOrientation;
3307 case Dali::Actor::Property::SCALE:
3308 property = &mNode->mScale;
3311 case Dali::Actor::Property::SCALE_X:
3312 property = &mNode->mScale;
3315 case Dali::Actor::Property::SCALE_Y:
3316 property = &mNode->mScale;
3319 case Dali::Actor::Property::SCALE_Z:
3320 property = &mNode->mScale;
3323 case Dali::Actor::Property::VISIBLE:
3324 property = &mNode->mVisible;
3327 case Dali::Actor::Property::COLOR:
3328 property = &mNode->mColor;
3331 case Dali::Actor::Property::COLOR_RED:
3332 property = &mNode->mColor;
3335 case Dali::Actor::Property::COLOR_GREEN:
3336 property = &mNode->mColor;
3339 case Dali::Actor::Property::COLOR_BLUE:
3340 property = &mNode->mColor;
3343 case Dali::Actor::Property::COLOR_ALPHA:
3344 property = &mNode->mColor;
3355 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3357 const PropertyInputImpl* property( NULL );
3359 // This method should only return a property of an object connected to the scene-graph
3365 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3367 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3368 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3370 property = animatable->GetSceneGraphProperty();
3372 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3373 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3375 CustomPropertyMetadata* custom = FindCustomProperty( index );
3376 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3377 property = custom->GetSceneGraphProperty();
3379 else if( NULL != mNode )
3383 case Dali::Actor::Property::PARENT_ORIGIN:
3384 property = &mNode->mParentOrigin;
3387 case Dali::Actor::Property::PARENT_ORIGIN_X:
3388 property = &mNode->mParentOrigin;
3391 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3392 property = &mNode->mParentOrigin;
3395 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3396 property = &mNode->mParentOrigin;
3399 case Dali::Actor::Property::ANCHOR_POINT:
3400 property = &mNode->mAnchorPoint;
3403 case Dali::Actor::Property::ANCHOR_POINT_X:
3404 property = &mNode->mAnchorPoint;
3407 case Dali::Actor::Property::ANCHOR_POINT_Y:
3408 property = &mNode->mAnchorPoint;
3411 case Dali::Actor::Property::ANCHOR_POINT_Z:
3412 property = &mNode->mAnchorPoint;
3415 case Dali::Actor::Property::SIZE:
3416 property = &mNode->mSize;
3419 case Dali::Actor::Property::SIZE_WIDTH:
3420 property = &mNode->mSize;
3423 case Dali::Actor::Property::SIZE_HEIGHT:
3424 property = &mNode->mSize;
3427 case Dali::Actor::Property::SIZE_DEPTH:
3428 property = &mNode->mSize;
3431 case Dali::Actor::Property::POSITION:
3432 property = &mNode->mPosition;
3435 case Dali::Actor::Property::POSITION_X:
3436 property = &mNode->mPosition;
3439 case Dali::Actor::Property::POSITION_Y:
3440 property = &mNode->mPosition;
3443 case Dali::Actor::Property::POSITION_Z:
3444 property = &mNode->mPosition;
3447 case Dali::Actor::Property::WORLD_POSITION:
3448 property = &mNode->mWorldPosition;
3451 case Dali::Actor::Property::WORLD_POSITION_X:
3452 property = &mNode->mWorldPosition;
3455 case Dali::Actor::Property::WORLD_POSITION_Y:
3456 property = &mNode->mWorldPosition;
3459 case Dali::Actor::Property::WORLD_POSITION_Z:
3460 property = &mNode->mWorldPosition;
3463 case Dali::Actor::Property::ORIENTATION:
3464 property = &mNode->mOrientation;
3467 case Dali::Actor::Property::WORLD_ORIENTATION:
3468 property = &mNode->mWorldOrientation;
3471 case Dali::Actor::Property::SCALE:
3472 property = &mNode->mScale;
3475 case Dali::Actor::Property::SCALE_X:
3476 property = &mNode->mScale;
3479 case Dali::Actor::Property::SCALE_Y:
3480 property = &mNode->mScale;
3483 case Dali::Actor::Property::SCALE_Z:
3484 property = &mNode->mScale;
3487 case Dali::Actor::Property::WORLD_SCALE:
3488 property = &mNode->mWorldScale;
3491 case Dali::Actor::Property::VISIBLE:
3492 property = &mNode->mVisible;
3495 case Dali::Actor::Property::COLOR:
3496 property = &mNode->mColor;
3499 case Dali::Actor::Property::COLOR_RED:
3500 property = &mNode->mColor;
3503 case Dali::Actor::Property::COLOR_GREEN:
3504 property = &mNode->mColor;
3507 case Dali::Actor::Property::COLOR_BLUE:
3508 property = &mNode->mColor;
3511 case Dali::Actor::Property::COLOR_ALPHA:
3512 property = &mNode->mColor;
3515 case Dali::Actor::Property::WORLD_COLOR:
3516 property = &mNode->mWorldColor;
3519 case Dali::Actor::Property::WORLD_MATRIX:
3520 property = &mNode->mWorldMatrix;
3531 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3533 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3535 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3537 // check whether the animatable property is registered already, if not then register one.
3538 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3539 if( animatableProperty )
3541 componentIndex = animatableProperty->componentIndex;
3548 case Dali::Actor::Property::PARENT_ORIGIN_X:
3549 case Dali::Actor::Property::ANCHOR_POINT_X:
3550 case Dali::Actor::Property::SIZE_WIDTH:
3551 case Dali::Actor::Property::POSITION_X:
3552 case Dali::Actor::Property::WORLD_POSITION_X:
3553 case Dali::Actor::Property::SCALE_X:
3554 case Dali::Actor::Property::COLOR_RED:
3560 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3561 case Dali::Actor::Property::ANCHOR_POINT_Y:
3562 case Dali::Actor::Property::SIZE_HEIGHT:
3563 case Dali::Actor::Property::POSITION_Y:
3564 case Dali::Actor::Property::WORLD_POSITION_Y:
3565 case Dali::Actor::Property::SCALE_Y:
3566 case Dali::Actor::Property::COLOR_GREEN:
3572 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3573 case Dali::Actor::Property::ANCHOR_POINT_Z:
3574 case Dali::Actor::Property::SIZE_DEPTH:
3575 case Dali::Actor::Property::POSITION_Z:
3576 case Dali::Actor::Property::WORLD_POSITION_Z:
3577 case Dali::Actor::Property::SCALE_Z:
3578 case Dali::Actor::Property::COLOR_BLUE:
3584 case Dali::Actor::Property::COLOR_ALPHA:
3598 return componentIndex;
3601 void Actor::SetParent( Actor* parent )
3605 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3609 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3612 // Instruct each actor to create a corresponding node in the scene graph
3613 ConnectToStage( parent->GetHierarchyDepth() );
3616 // Resolve the name and index for the child properties if any
3617 ResolveChildProperties();
3619 else // parent being set to NULL
3621 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3625 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3628 DALI_ASSERT_ALWAYS( mNode != NULL );
3632 // Disconnect the Node & its children from the scene-graph.
3633 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3636 // Instruct each actor to discard pointers to the scene-graph
3637 DisconnectFromStage();
3642 SceneGraph::Node* Actor::CreateNode() const
3647 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3650 Actor* actor = dynamic_cast< Actor* >( object );
3654 if( 0 == actionName.compare( ACTION_SHOW ) )
3656 actor->SetVisible( true );
3659 else if( 0 == actionName.compare( ACTION_HIDE ) )
3661 actor->SetVisible( false );
3669 void Actor::EnsureRelayoutData()
3671 // Assign relayout data.
3672 if( !mRelayoutData )
3674 mRelayoutData = new RelayoutData();
3678 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3680 // Check if actor is dependent on parent
3681 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3683 if( ( dimension & ( 1 << i ) ) )
3685 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3686 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3696 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3698 // Check if actor is dependent on children
3699 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3701 if( ( dimension & ( 1 << i ) ) )
3703 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3704 switch( resizePolicy )
3706 case ResizePolicy::FIT_TO_CHILDREN:
3707 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3723 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3725 return Actor::RelayoutDependentOnChildren( dimension );
3728 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3730 // Check each possible dimension and see if it is dependent on the input one
3731 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3733 if( dimension & ( 1 << i ) )
3735 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3742 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3744 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3746 if( dimension & ( 1 << i ) )
3748 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3753 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3755 // If more than one dimension is requested, just return the first one found
3756 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3758 if( ( dimension & ( 1 << i ) ) )
3760 return mRelayoutData->negotiatedDimensions[ i ];
3764 return 0.0f; // Default
3767 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3769 EnsureRelayoutData();
3771 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3773 if( dimension & ( 1 << i ) )
3775 mRelayoutData->dimensionPadding[ i ] = padding;
3780 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3782 if ( mRelayoutData )
3784 // If more than one dimension is requested, just return the first one found
3785 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3787 if( ( dimension & ( 1 << i ) ) )
3789 return mRelayoutData->dimensionPadding[ i ];
3794 return GetDefaultDimensionPadding();
3797 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3799 EnsureRelayoutData();
3801 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3803 if( dimension & ( 1 << i ) )
3805 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3810 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3812 if ( mRelayoutData )
3814 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3816 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3826 float Actor::GetHeightForWidthBase( float width )
3828 float height = 0.0f;
3830 const Vector3 naturalSize = GetNaturalSize();
3831 if( naturalSize.width > 0.0f )
3833 height = naturalSize.height * width / naturalSize.width;
3835 else // we treat 0 as 1:1 aspect ratio
3843 float Actor::GetWidthForHeightBase( float height )
3847 const Vector3 naturalSize = GetNaturalSize();
3848 if( naturalSize.height > 0.0f )
3850 width = naturalSize.width * height / naturalSize.height;
3852 else // we treat 0 as 1:1 aspect ratio
3860 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3862 // Fill to parent, taking size mode factor into account
3863 switch( child.GetResizePolicy( dimension ) )
3865 case ResizePolicy::FILL_TO_PARENT:
3867 return GetLatestSize( dimension );
3870 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3872 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3875 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3877 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3882 return GetLatestSize( dimension );
3887 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3889 // Can be overridden in derived class
3890 return CalculateChildSizeBase( child, dimension );
3893 float Actor::GetHeightForWidth( float width )
3895 // Can be overridden in derived class
3896 return GetHeightForWidthBase( width );
3899 float Actor::GetWidthForHeight( float height )
3901 // Can be overridden in derived class
3902 return GetWidthForHeightBase( height );
3905 float Actor::GetLatestSize( Dimension::Type dimension ) const
3907 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3910 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3912 Vector2 padding = GetPadding( dimension );
3914 return GetLatestSize( dimension ) + padding.x + padding.y;
3917 float Actor::NegotiateFromParent( Dimension::Type dimension )
3919 Actor* parent = GetParent();
3922 Vector2 padding( GetPadding( dimension ) );
3923 Vector2 parentPadding( parent->GetPadding( dimension ) );
3924 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3930 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3932 float maxDimensionPoint = 0.0f;
3934 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3936 ActorPtr child = GetChildAt( i );
3938 if( !child->RelayoutDependentOnParent( dimension ) )
3940 // Calculate the min and max points that the children range across
3941 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3942 float dimensionSize = child->GetRelayoutSize( dimension );
3943 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3947 return maxDimensionPoint;
3950 float Actor::GetSize( Dimension::Type dimension ) const
3952 return GetDimensionValue( GetTargetSize(), dimension );
3955 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3957 return GetDimensionValue( GetNaturalSize(), dimension );
3960 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3962 switch( GetResizePolicy( dimension ) )
3964 case ResizePolicy::USE_NATURAL_SIZE:
3966 return GetNaturalSize( dimension );
3969 case ResizePolicy::FIXED:
3971 return GetDimensionValue( GetPreferredSize(), dimension );
3974 case ResizePolicy::USE_ASSIGNED_SIZE:
3976 return GetDimensionValue( maximumSize, dimension );
3979 case ResizePolicy::FILL_TO_PARENT:
3980 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3981 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3983 return NegotiateFromParent( dimension );
3986 case ResizePolicy::FIT_TO_CHILDREN:
3988 return NegotiateFromChildren( dimension );
3991 case ResizePolicy::DIMENSION_DEPENDENCY:
3993 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3996 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3998 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4001 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4003 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4015 return 0.0f; // Default
4018 float Actor::ClampDimension( float size, Dimension::Type dimension )
4020 const float minSize = GetMinimumSize( dimension );
4021 const float maxSize = GetMaximumSize( dimension );
4023 return std::max( minSize, std::min( size, maxSize ) );
4026 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4028 // Check if it needs to be negotiated
4029 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4031 // Check that we havn't gotten into an infinite loop
4032 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4033 bool recursionFound = false;
4034 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4036 if( *it == searchActor )
4038 recursionFound = true;
4043 if( !recursionFound )
4045 // Record the path that we have taken
4046 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4048 // Dimension dependency check
4049 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4051 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4053 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4055 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4059 // Parent dependency check
4060 Actor* parent = GetParent();
4061 if( parent && RelayoutDependentOnParent( dimension ) )
4063 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4066 // Children dependency check
4067 if( RelayoutDependentOnChildren( dimension ) )
4069 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4071 ActorPtr child = GetChildAt( i );
4073 // Only relayout child first if it is not dependent on this actor
4074 if( !child->RelayoutDependentOnParent( dimension ) )
4076 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4081 // For deriving classes
4082 OnCalculateRelayoutSize( dimension );
4084 // All dependencies checked, calculate the size and set negotiated flag
4085 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4087 SetNegotiatedDimension( newSize, dimension );
4088 SetLayoutNegotiated( true, dimension );
4090 // For deriving classes
4091 OnLayoutNegotiated( newSize, dimension );
4093 // This actor has been successfully processed, pop it off the recursion stack
4094 recursionStack.pop_back();
4098 // TODO: Break infinite loop
4099 SetLayoutNegotiated( true, dimension );
4104 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4106 // Negotiate all dimensions that require it
4107 ActorDimensionStack recursionStack;
4109 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4111 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4114 NegotiateDimension( dimension, allocatedSize, recursionStack );
4118 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4120 switch( mRelayoutData->sizeSetPolicy )
4122 case SizeScalePolicy::USE_SIZE_SET:
4127 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4129 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4130 const Vector3 naturalSize = GetNaturalSize();
4131 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4133 const float sizeRatio = size.width / size.height;
4134 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4136 if( naturalSizeRatio < sizeRatio )
4138 return Vector2( naturalSizeRatio * size.height, size.height );
4140 else if( naturalSizeRatio > sizeRatio )
4142 return Vector2( size.width, size.width / naturalSizeRatio );
4153 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4155 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4156 const Vector3 naturalSize = GetNaturalSize();
4157 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4159 const float sizeRatio = size.width / size.height;
4160 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4162 if( naturalSizeRatio < sizeRatio )
4164 return Vector2( size.width, size.width / naturalSizeRatio );
4166 else if( naturalSizeRatio > sizeRatio )
4168 return Vector2( naturalSizeRatio * size.height, size.height );
4187 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4189 // Do the set actor size
4190 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4192 // Adjust for size set policy
4193 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4195 // Lock the flag to stop recursive relayouts on set size
4196 mRelayoutData->insideRelayout = true;
4197 SetSize( negotiatedSize );
4198 mRelayoutData->insideRelayout = false;
4200 // Clear flags for all dimensions
4201 SetLayoutDirty( false );
4203 // Give deriving classes a chance to respond
4204 OnRelayout( negotiatedSize, container );
4206 if( !mOnRelayoutSignal.Empty() )
4208 Dali::Actor handle( this );
4209 mOnRelayoutSignal.Emit( handle );
4213 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4215 // Force a size negotiation for actors that has assigned size during relayout
4216 // This is required as otherwise the flags that force a relayout will not
4217 // necessarilly be set. This will occur if the actor has already been laid out.
4218 // The dirty flags are then cleared. Then if the actor is added back into the
4219 // relayout container afterwards, the dirty flags would still be clear...
4220 // causing a relayout to be skipped. Here we force any actors added to the
4221 // container to be relayed out.
4222 if( GetUseAssignedSize(Dimension::WIDTH ) )
4224 SetLayoutNegotiated( false, Dimension::WIDTH );
4226 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4228 SetLayoutNegotiated( false, Dimension::HEIGHT );
4231 // Do the negotiation
4232 NegotiateDimensions( allocatedSize );
4234 // Set the actor size
4235 SetNegotiatedSize( container );
4237 // Negotiate down to children
4238 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4240 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4242 ActorPtr child = GetChildAt( i );
4244 // Forces children that have already been laid out to be relayed out
4245 // if they have assigned size during relayout.
4246 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4248 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4249 child->SetLayoutDirty(true, Dimension::WIDTH);
4252 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4254 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4255 child->SetLayoutDirty(true, Dimension::HEIGHT);
4258 // Only relayout if required
4259 if( child->RelayoutRequired() )
4261 container.Add( Dali::Actor( child.Get() ), newBounds );
4266 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4270 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4272 if( dimension & ( 1 << i ) )
4274 mRelayoutData->useAssignedSize[ i ] = use;
4280 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4282 if ( mRelayoutData )
4284 // If more than one dimension is requested, just return the first one found
4285 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4287 if( dimension & ( 1 << i ) )
4289 return mRelayoutData->useAssignedSize[ i ];
4297 void Actor::RelayoutRequest( Dimension::Type dimension )
4299 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4300 if( relayoutController )
4302 Dali::Actor self( this );
4303 relayoutController->RequestRelayout( self, dimension );
4307 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4311 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4315 void Actor::SetPreferredSize( const Vector2& size )
4317 EnsureRelayoutData();
4319 if( size.width > 0.0f )
4321 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4324 if( size.height > 0.0f )
4326 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4329 mRelayoutData->preferredSize = size;
4334 Vector2 Actor::GetPreferredSize() const
4336 if ( mRelayoutData )
4338 return Vector2( mRelayoutData->preferredSize );
4341 return GetDefaultPreferredSize();
4344 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4346 EnsureRelayoutData();
4348 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4350 if( dimension & ( 1 << i ) )
4352 mRelayoutData->minimumSize[ i ] = size;
4359 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4361 if ( mRelayoutData )
4363 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4365 if( dimension & ( 1 << i ) )
4367 return mRelayoutData->minimumSize[ i ];
4372 return 0.0f; // Default
4375 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4377 EnsureRelayoutData();
4379 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4381 if( dimension & ( 1 << i ) )
4383 mRelayoutData->maximumSize[ i ] = size;
4390 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4392 if ( mRelayoutData )
4394 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4396 if( dimension & ( 1 << i ) )
4398 return mRelayoutData->maximumSize[ i ];
4403 return FLT_MAX; // Default
4406 Object* Actor::GetParentObject() const
4411 } // namespace Internal