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/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/common/animatable-property.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/nodes/node-declarations.h>
51 #include <dali/internal/update/animation/scene-graph-constraint.h>
52 #include <dali/internal/event/events/actor-gesture-data.h>
53 #include <dali/internal/common/message.h>
54 #include <dali/integration-api/debug.h>
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::PropertyBase;
66 unsigned int Actor::mActorCounter = 0;
70 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
71 inline const Vector3& GetDefaultSizeModeFactor()
76 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
77 inline const Vector2& GetDefaultPreferredSize()
82 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
83 inline const Vector2& GetDefaultDimensionPadding()
88 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
90 } // unnamed namespace
93 * Struct to collect relayout variables
95 struct Actor::RelayoutData
98 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
100 // Set size negotiation defaults
101 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
103 resizePolicies[ i ] = ResizePolicy::DEFAULT;
104 negotiatedDimensions[ i ] = 0.0f;
105 dimensionNegotiated[ i ] = false;
106 dimensionDirty[ i ] = false;
107 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
108 dimensionPadding[ i ] = GetDefaultDimensionPadding();
109 minimumSize[ i ] = 0.0f;
110 maximumSize[ i ] = FLT_MAX;
114 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
116 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
118 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
120 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
122 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
123 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
125 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
126 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
128 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
130 Vector2 preferredSize; ///< The preferred size of the actor
132 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
134 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
135 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
138 namespace // unnamed namespace
144 * We want to discourage the use of property strings (minimize string comparisons),
145 * particularly for the default properties.
146 * Name Type writable animatable constraint-input enum for index-checking
148 DALI_PROPERTY_TABLE_BEGIN
149 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
150 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
151 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
152 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
153 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
154 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
155 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
156 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
157 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
158 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
159 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
160 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
161 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
162 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
163 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
164 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
165 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
166 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
167 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
168 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
169 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
170 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
171 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
172 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
173 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
174 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
175 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
176 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
177 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
178 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
179 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
180 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
181 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
182 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
183 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
184 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
185 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
186 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
187 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
188 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
189 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
190 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
191 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
192 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
193 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
194 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
195 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
196 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
197 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
198 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
199 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
200 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
201 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
202 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
203 DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::DevelActor::Property::BATCH_PARENT )
204 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
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 mRelayoutData->resizePolicies[ i ] = policy;
1302 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1304 if( dimension & Dimension::WIDTH )
1306 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1309 if( dimension & Dimension::HEIGHT )
1311 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1315 // If calling SetResizePolicy, assume we want relayout enabled
1316 SetRelayoutEnabled( true );
1318 OnSetResizePolicy( policy, dimension );
1320 // Trigger relayout on this control
1324 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1326 if ( mRelayoutData )
1328 // If more than one dimension is requested, just return the first one found
1329 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1331 if( ( dimension & ( 1 << i ) ) )
1333 return mRelayoutData->resizePolicies[ i ];
1338 return ResizePolicy::DEFAULT;
1341 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1343 EnsureRelayoutData();
1345 mRelayoutData->sizeSetPolicy = policy;
1348 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1350 if ( mRelayoutData )
1352 return mRelayoutData->sizeSetPolicy;
1355 return DEFAULT_SIZE_SCALE_POLICY;
1358 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1360 EnsureRelayoutData();
1362 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1364 if( dimension & ( 1 << i ) )
1366 mRelayoutData->dimensionDependencies[ i ] = dependency;
1371 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1373 if ( mRelayoutData )
1375 // If more than one dimension is requested, just return the first one found
1376 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1378 if( ( dimension & ( 1 << i ) ) )
1380 return mRelayoutData->dimensionDependencies[ i ];
1385 return Dimension::ALL_DIMENSIONS; // Default
1388 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1390 // If relayout data has not been allocated yet and the client is requesting
1391 // to disable it, do nothing
1392 if( mRelayoutData || relayoutEnabled )
1394 EnsureRelayoutData();
1396 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1398 mRelayoutData->relayoutEnabled = relayoutEnabled;
1402 bool Actor::IsRelayoutEnabled() const
1404 // Assume that if relayout data has not been allocated yet then
1405 // relayout is disabled
1406 return mRelayoutData && mRelayoutData->relayoutEnabled;
1409 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1411 EnsureRelayoutData();
1413 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1415 if( dimension & ( 1 << i ) )
1417 mRelayoutData->dimensionDirty[ i ] = dirty;
1422 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1424 if ( mRelayoutData )
1426 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1428 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1438 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1440 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1443 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1445 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1448 unsigned int Actor::AddRenderer( Renderer& renderer )
1452 mRenderers = new RendererContainer;
1455 unsigned int index = mRenderers->size();
1456 RendererPtr rendererPtr = RendererPtr( &renderer );
1457 mRenderers->push_back( rendererPtr );
1458 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1462 rendererPtr->Connect();
1468 unsigned int Actor::GetRendererCount() const
1470 unsigned int rendererCount(0);
1473 rendererCount = mRenderers->size();
1476 return rendererCount;
1479 RendererPtr Actor::GetRendererAt( unsigned int index )
1481 RendererPtr renderer;
1482 if( index < GetRendererCount() )
1484 renderer = ( *mRenderers )[ index ];
1490 void Actor::RemoveRenderer( Renderer& renderer )
1494 RendererIter end = mRenderers->end();
1495 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1497 if( (*iter).Get() == &renderer )
1499 mRenderers->erase( iter );
1500 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1507 void Actor::RemoveRenderer( unsigned int index )
1509 if( index < GetRendererCount() )
1511 RendererPtr renderer = ( *mRenderers )[ index ];
1512 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1513 mRenderers->erase( mRenderers->begin()+index );
1517 bool Actor::IsOverlay() const
1519 return ( DrawMode::OVERLAY_2D == mDrawMode );
1522 void Actor::SetDrawMode( DrawMode::Type drawMode )
1524 // this flag is not animatable so keep the value
1525 mDrawMode = drawMode;
1526 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1528 // mNode is being used in a separate thread; queue a message to set the value
1529 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1533 DrawMode::Type Actor::GetDrawMode() const
1538 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1540 // only valid when on-stage
1541 StagePtr stage = Stage::GetCurrent();
1542 if( stage && OnStage() )
1544 const RenderTaskList& taskList = stage->GetRenderTaskList();
1546 Vector2 converted( screenX, screenY );
1548 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1549 const int taskCount = taskList.GetTaskCount();
1550 for( int i = taskCount - 1; i >= 0; --i )
1552 Dali::RenderTask task = taskList.GetTask( i );
1553 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1555 // found a task where this conversion was ok so return
1563 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1565 bool retval = false;
1566 // only valid when on-stage
1569 CameraActor* camera = renderTask.GetCameraActor();
1573 renderTask.GetViewport( viewport );
1575 // need to translate coordinates to render tasks coordinate space
1576 Vector2 converted( screenX, screenY );
1577 if( renderTask.TranslateCoordinates( converted ) )
1579 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1586 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1588 // Early-out if mNode is NULL
1594 // Get the ModelView matrix
1596 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1598 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1599 Matrix invertedMvp( false/*don't init*/);
1600 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1601 bool success = invertedMvp.Invert();
1603 // Convert to GL coordinates
1604 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1609 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1616 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1622 if( XyPlaneIntersect( nearPos, farPos, local ) )
1624 Vector3 size = GetCurrentSize();
1625 localX = local.x + size.x * 0.5f;
1626 localY = local.y + size.y * 0.5f;
1637 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1640 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1642 Mathematical Formulation
1644 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1646 ( p - c ) dot ( p - c ) = r^2
1648 Given a ray with a point of origin 'o', and a direction vector 'd':
1650 ray(t) = o + td, t >= 0
1652 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1654 (o + td - c ) dot ( o + td - c ) = r^2
1656 To solve for t we first expand the above into a more recognisable quadratic equation form
1658 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1667 B = 2( o - c ) dot d
1668 C = ( o - c ) dot ( o - c ) - r^2
1670 which can be solved using a standard quadratic formula.
1672 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1674 Practical Simplification
1676 In a renderer, we often differentiate between world space and object space. In the object space
1677 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1678 into object space, the mathematical solution presented above can be simplified significantly.
1680 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1684 and we can find the t at which the (transformed) ray intersects the sphere by
1686 ( o + td ) dot ( o + td ) = r^2
1688 According to the reasoning above, we expand the above quadratic equation into the general form
1692 which now has coefficients:
1699 // Early out if mNode is NULL
1705 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1707 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1708 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1709 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1711 // Compute the radius is not needed, square radius it's enough.
1712 const Vector3& size( mNode->GetSize( bufferIndex ) );
1714 // Scale the sphere.
1715 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1717 const float width = size.width * scale.width;
1718 const float height = size.height * scale.height;
1720 float squareSphereRadius = 0.5f * ( width * width + height * height );
1722 float a = rayDir.Dot( rayDir ); // a
1723 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1724 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1726 return ( b2 * b2 - a * c ) >= 0.f;
1729 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1733 if( OnStage() && NULL != mNode )
1735 // Transforms the ray to the local reference system.
1736 // Calculate the inverse of Model matrix
1737 Matrix invModelMatrix( false/*don't init*/);
1739 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1740 invModelMatrix = mNode->GetWorldMatrix(0);
1741 invModelMatrix.Invert();
1743 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1744 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1746 // Test with the actor's XY plane (Normal = 0 0 1 1).
1748 float a = -rayOriginLocal.z;
1749 float b = rayDirLocal.z;
1751 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1753 // Ray travels distance * rayDirLocal to intersect with plane.
1756 const Vector3& size = mNode->GetSize( bufferIndex );
1758 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1759 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1761 // Test with the actor's geometry.
1762 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1769 void Actor::SetLeaveRequired( bool required )
1771 mLeaveRequired = required;
1774 bool Actor::GetLeaveRequired() const
1776 return mLeaveRequired;
1779 void Actor::SetKeyboardFocusable( bool focusable )
1781 mKeyboardFocusable = focusable;
1784 bool Actor::IsKeyboardFocusable() const
1786 return mKeyboardFocusable;
1789 bool Actor::GetTouchRequired() const
1791 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1794 bool Actor::GetHoverRequired() const
1796 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1799 bool Actor::GetWheelEventRequired() const
1801 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1804 bool Actor::IsHittable() const
1806 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1809 ActorGestureData& Actor::GetGestureData()
1811 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1812 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1813 if( NULL == mGestureData )
1815 mGestureData = new ActorGestureData;
1817 return *mGestureData;
1820 bool Actor::IsGestureRequred( Gesture::Type type ) const
1822 return mGestureData && mGestureData->IsGestureRequred( type );
1825 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1827 bool consumed = false;
1829 if( !mTouchSignal.Empty() )
1831 Dali::Actor handle( this );
1832 consumed = mTouchSignal.Emit( handle, touch );
1835 if( !mTouchedSignal.Empty() )
1837 Dali::Actor handle( this );
1838 consumed |= mTouchedSignal.Emit( handle, event );
1843 // Notification for derived classes
1844 consumed = OnTouchEvent( event ); // TODO
1850 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1852 bool consumed = false;
1854 if( !mHoveredSignal.Empty() )
1856 Dali::Actor handle( this );
1857 consumed = mHoveredSignal.Emit( handle, event );
1862 // Notification for derived classes
1863 consumed = OnHoverEvent( event );
1869 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1871 bool consumed = false;
1873 if( !mWheelEventSignal.Empty() )
1875 Dali::Actor handle( this );
1876 consumed = mWheelEventSignal.Emit( handle, event );
1881 // Notification for derived classes
1882 consumed = OnWheelEvent( event );
1888 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1890 return mTouchedSignal;
1893 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1895 return mTouchSignal;
1898 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1900 return mHoveredSignal;
1903 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1905 return mWheelEventSignal;
1908 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1910 return mOnStageSignal;
1913 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1915 return mOffStageSignal;
1918 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1920 return mOnRelayoutSignal;
1923 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1925 bool connected( true );
1926 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1928 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1930 actor->TouchedSignal().Connect( tracker, functor );
1932 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1934 actor->HoveredSignal().Connect( tracker, functor );
1936 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1938 actor->WheelEventSignal().Connect( tracker, functor );
1940 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1942 actor->OnStageSignal().Connect( tracker, functor );
1944 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1946 actor->OffStageSignal().Connect( tracker, functor );
1948 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1950 actor->OnRelayoutSignal().Connect( tracker, functor );
1952 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1954 actor->TouchSignal().Connect( tracker, functor );
1958 // signalName does not match any signal
1965 Actor::Actor( DerivedType derivedType )
1970 mParentOrigin( NULL ),
1971 mAnchorPoint( NULL ),
1972 mRelayoutData( NULL ),
1973 mGestureData( NULL ),
1974 mTargetSize( 0.0f, 0.0f, 0.0f ),
1976 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1979 mIsRoot( ROOT_LAYER == derivedType ),
1980 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1981 mIsOnStage( false ),
1983 mLeaveRequired( false ),
1984 mKeyboardFocusable( false ),
1985 mDerivedRequiresTouch( false ),
1986 mDerivedRequiresHover( false ),
1987 mDerivedRequiresWheelEvent( false ),
1988 mOnStageSignalled( false ),
1989 mInsideOnSizeSet( false ),
1990 mInheritPosition( true ),
1991 mInheritOrientation( true ),
1992 mInheritScale( true ),
1993 mDrawMode( DrawMode::NORMAL ),
1994 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1995 mColorMode( Node::DEFAULT_COLOR_MODE ),
1996 mClippingMode( ClippingMode::DISABLED ),
1997 mIsBatchParent( false )
2001 void Actor::Initialize()
2004 SceneGraph::Node* node = CreateNode();
2006 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2007 mNode = node; // Keep raw-pointer to Node
2011 GetEventThreadServices().RegisterObject( this );
2016 // Remove mParent pointers from children even if we're destroying core,
2017 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2020 ActorConstIter endIter = mChildren->end();
2021 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2023 (*iter)->SetParent( NULL );
2029 // Guard to allow handle destruction after Core has been destroyed
2030 if( EventThreadServices::IsCoreRunning() )
2034 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2035 mNode = NULL; // Node is about to be destroyed
2038 GetEventThreadServices().UnregisterObject( this );
2041 // Cleanup optional gesture data
2042 delete mGestureData;
2044 // Cleanup optional parent origin and anchor
2045 delete mParentOrigin;
2046 delete mAnchorPoint;
2048 // Delete optional relayout data
2051 delete mRelayoutData;
2055 void Actor::ConnectToStage( unsigned int parentDepth )
2057 // This container is used instead of walking the Actor hierarchy.
2058 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2059 ActorContainer connectionList;
2061 // This stage is atomic i.e. not interrupted by user callbacks.
2062 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2064 // Notify applications about the newly connected actors.
2065 const ActorIter endIter = connectionList.end();
2066 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2068 (*iter)->NotifyStageConnection();
2074 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2076 DALI_ASSERT_ALWAYS( !OnStage() );
2080 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2082 ConnectToSceneGraph();
2084 // Notification for internal derived classes
2085 OnStageConnectionInternal();
2087 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2088 connectionList.push_back( ActorPtr( this ) );
2090 // Recursively connect children
2093 ActorConstIter endIter = mChildren->end();
2094 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2096 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2102 * This method is called when the Actor is connected to the Stage.
2103 * The parent must have added its Node to the scene-graph.
2104 * The child must connect its Node to the parent's Node.
2105 * This is recursive; the child calls ConnectToStage() for its children.
2107 void Actor::ConnectToSceneGraph()
2109 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2113 // Reparent Node in next Update
2114 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2117 unsigned int rendererCount( GetRendererCount() );
2118 for( unsigned int i(0); i<rendererCount; ++i )
2120 GetRendererAt(i)->Connect();
2123 // Request relayout on all actors that are added to the scenegraph
2126 // Notification for Object::Observers
2130 void Actor::NotifyStageConnection()
2132 // Actors can be removed (in a callback), before the on-stage stage is reported.
2133 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2134 if( OnStage() && !mOnStageSignalled )
2136 // Notification for external (CustomActor) derived classes
2137 OnStageConnectionExternal( mDepth );
2139 if( !mOnStageSignal.Empty() )
2141 Dali::Actor handle( this );
2142 mOnStageSignal.Emit( handle );
2145 // Guard against Remove during callbacks
2148 mOnStageSignalled = true; // signal required next time Actor is removed
2153 void Actor::DisconnectFromStage()
2155 // This container is used instead of walking the Actor hierachy.
2156 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2157 ActorContainer disconnectionList;
2159 // This stage is atomic i.e. not interrupted by user callbacks
2160 RecursiveDisconnectFromStage( disconnectionList );
2162 // Notify applications about the newly disconnected actors.
2163 const ActorIter endIter = disconnectionList.end();
2164 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2166 (*iter)->NotifyStageDisconnection();
2170 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2172 DALI_ASSERT_ALWAYS( OnStage() );
2174 // Recursively disconnect children
2177 ActorConstIter endIter = mChildren->end();
2178 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2180 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2184 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2185 disconnectionList.push_back( ActorPtr( this ) );
2187 // Notification for internal derived classes
2188 OnStageDisconnectionInternal();
2190 DisconnectFromSceneGraph();
2196 * This method is called by an actor or its parent, before a node removal message is sent.
2197 * This is recursive; the child calls DisconnectFromStage() for its children.
2199 void Actor::DisconnectFromSceneGraph()
2201 // Notification for Object::Observers
2202 OnSceneObjectRemove();
2204 unsigned int rendererCount( GetRendererCount() );
2205 for( unsigned int i(0); i<rendererCount; ++i )
2207 GetRendererAt(i)->Disconnect();
2211 void Actor::NotifyStageDisconnection()
2213 // Actors can be added (in a callback), before the off-stage state is reported.
2214 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2215 // only do this step if there is a stage, i.e. Core is not being shut down
2216 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2218 // Notification for external (CustomeActor) derived classes
2219 OnStageDisconnectionExternal();
2221 if( !mOffStageSignal.Empty() )
2223 Dali::Actor handle( this );
2224 mOffStageSignal.Emit( handle );
2227 // Guard against Add during callbacks
2230 mOnStageSignalled = false; // signal required next time Actor is added
2235 bool Actor::IsNodeConnected() const
2237 bool connected( false );
2239 if( OnStage() && ( NULL != mNode ) )
2241 if( IsRoot() || mNode->GetParent() )
2250 unsigned int Actor::GetDefaultPropertyCount() const
2252 return DEFAULT_PROPERTY_COUNT;
2255 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2257 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2259 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2261 indices.PushBack( i );
2265 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2267 if( index < DEFAULT_PROPERTY_COUNT )
2269 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2275 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2277 Property::Index index = Property::INVALID_INDEX;
2279 // Look for name in default properties
2280 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2282 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2283 if( 0 == name.compare( property->name ) )
2293 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2295 if( index < DEFAULT_PROPERTY_COUNT )
2297 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2303 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2305 if( index < DEFAULT_PROPERTY_COUNT )
2307 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2313 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2315 if( index < DEFAULT_PROPERTY_COUNT )
2317 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2323 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2325 if( index < DEFAULT_PROPERTY_COUNT )
2327 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2330 // index out of range...return Property::NONE
2331 return Property::NONE;
2334 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2338 case Dali::Actor::Property::PARENT_ORIGIN:
2340 Property::Type type = property.GetType();
2341 if( type == Property::VECTOR3 )
2343 SetParentOrigin( property.Get< Vector3 >() );
2345 else if ( type == Property::STRING )
2347 std::string parentOriginString;
2348 property.Get( parentOriginString );
2349 Vector3 parentOrigin;
2350 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2352 SetParentOrigin( parentOrigin );
2358 case Dali::Actor::Property::PARENT_ORIGIN_X:
2360 SetParentOriginX( property.Get< float >() );
2364 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2366 SetParentOriginY( property.Get< float >() );
2370 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2372 SetParentOriginZ( property.Get< float >() );
2376 case Dali::Actor::Property::ANCHOR_POINT:
2378 Property::Type type = property.GetType();
2379 if( type == Property::VECTOR3 )
2381 SetAnchorPoint( property.Get< Vector3 >() );
2383 else if ( type == Property::STRING )
2385 std::string anchorPointString;
2386 property.Get( anchorPointString );
2388 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2390 SetAnchorPoint( anchor );
2396 case Dali::Actor::Property::ANCHOR_POINT_X:
2398 SetAnchorPointX( property.Get< float >() );
2402 case Dali::Actor::Property::ANCHOR_POINT_Y:
2404 SetAnchorPointY( property.Get< float >() );
2408 case Dali::Actor::Property::ANCHOR_POINT_Z:
2410 SetAnchorPointZ( property.Get< float >() );
2414 case Dali::Actor::Property::SIZE:
2416 SetSize( property.Get< Vector3 >() );
2420 case Dali::Actor::Property::SIZE_WIDTH:
2422 SetWidth( property.Get< float >() );
2426 case Dali::Actor::Property::SIZE_HEIGHT:
2428 SetHeight( property.Get< float >() );
2432 case Dali::Actor::Property::SIZE_DEPTH:
2434 SetDepth( property.Get< float >() );
2438 case Dali::Actor::Property::POSITION:
2440 SetPosition( property.Get< Vector3 >() );
2444 case Dali::Actor::Property::POSITION_X:
2446 SetX( property.Get< float >() );
2450 case Dali::Actor::Property::POSITION_Y:
2452 SetY( property.Get< float >() );
2456 case Dali::Actor::Property::POSITION_Z:
2458 SetZ( property.Get< float >() );
2462 case Dali::Actor::Property::ORIENTATION:
2464 SetOrientation( property.Get< Quaternion >() );
2468 case Dali::Actor::Property::SCALE:
2470 SetScale( property.Get< Vector3 >() );
2474 case Dali::Actor::Property::SCALE_X:
2476 SetScaleX( property.Get< float >() );
2480 case Dali::Actor::Property::SCALE_Y:
2482 SetScaleY( property.Get< float >() );
2486 case Dali::Actor::Property::SCALE_Z:
2488 SetScaleZ( property.Get< float >() );
2492 case Dali::Actor::Property::VISIBLE:
2494 SetVisible( property.Get< bool >() );
2498 case Dali::Actor::Property::COLOR:
2500 SetColor( property.Get< Vector4 >() );
2504 case Dali::Actor::Property::COLOR_RED:
2506 SetColorRed( property.Get< float >() );
2510 case Dali::Actor::Property::COLOR_GREEN:
2512 SetColorGreen( property.Get< float >() );
2516 case Dali::Actor::Property::COLOR_BLUE:
2518 SetColorBlue( property.Get< float >() );
2522 case Dali::Actor::Property::COLOR_ALPHA:
2524 SetOpacity( property.Get< float >() );
2528 case Dali::Actor::Property::NAME:
2530 SetName( property.Get< std::string >() );
2534 case Dali::Actor::Property::SENSITIVE:
2536 SetSensitive( property.Get< bool >() );
2540 case Dali::Actor::Property::LEAVE_REQUIRED:
2542 SetLeaveRequired( property.Get< bool >() );
2546 case Dali::Actor::Property::INHERIT_POSITION:
2548 SetInheritPosition( property.Get< bool >() );
2552 case Dali::Actor::Property::INHERIT_ORIENTATION:
2554 SetInheritOrientation( property.Get< bool >() );
2558 case Dali::Actor::Property::INHERIT_SCALE:
2560 SetInheritScale( property.Get< bool >() );
2564 case Dali::Actor::Property::COLOR_MODE:
2567 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2569 SetColorMode( mode );
2574 case Dali::Actor::Property::POSITION_INHERITANCE:
2576 PositionInheritanceMode mode;
2577 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2579 SetPositionInheritanceMode( mode );
2584 case Dali::Actor::Property::DRAW_MODE:
2586 DrawMode::Type mode;
2587 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2589 SetDrawMode( mode );
2594 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2596 SetSizeModeFactor( property.Get< Vector3 >() );
2600 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2602 ResizePolicy::Type type;
2603 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2605 SetResizePolicy( type, Dimension::WIDTH );
2610 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2612 ResizePolicy::Type type;
2613 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2615 SetResizePolicy( type, Dimension::HEIGHT );
2620 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2622 SizeScalePolicy::Type type;
2623 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2625 SetSizeScalePolicy( type );
2630 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2632 if( property.Get< bool >() )
2634 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2639 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2641 if( property.Get< bool >() )
2643 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2648 case Dali::Actor::Property::PADDING:
2650 Vector4 padding = property.Get< Vector4 >();
2651 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2652 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2656 case Dali::Actor::Property::MINIMUM_SIZE:
2658 Vector2 size = property.Get< Vector2 >();
2659 SetMinimumSize( size.x, Dimension::WIDTH );
2660 SetMinimumSize( size.y, Dimension::HEIGHT );
2664 case Dali::Actor::Property::MAXIMUM_SIZE:
2666 Vector2 size = property.Get< Vector2 >();
2667 SetMaximumSize( size.x, Dimension::WIDTH );
2668 SetMaximumSize( size.y, Dimension::HEIGHT );
2672 case Dali::DevelActor::Property::BATCH_PARENT:
2676 if( property.Get( value ) )
2678 if( value != mIsBatchParent )
2680 mIsBatchParent = value;
2681 SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2687 case Dali::DevelActor::Property::SIBLING_ORDER:
2691 if( property.Get( value ) )
2693 if( static_cast<unsigned int>(value) != mSiblingOrder )
2695 mSiblingOrder = value;
2698 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2705 case Dali::Actor::Property::CLIPPING_MODE:
2707 ClippingMode::Type convertedValue = mClippingMode;
2708 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2710 mClippingMode = convertedValue;
2713 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2721 // this can happen in the case of a non-animatable default property so just do nothing
2727 // TODO: This method needs to be removed
2728 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2730 switch( entry.GetType() )
2732 case Property::BOOLEAN:
2734 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2735 DALI_ASSERT_DEBUG( NULL != property );
2737 // property is being used in a separate thread; queue a message to set the property
2738 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2743 case Property::INTEGER:
2745 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2746 DALI_ASSERT_DEBUG( NULL != property );
2748 // property is being used in a separate thread; queue a message to set the property
2749 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2754 case Property::FLOAT:
2756 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2757 DALI_ASSERT_DEBUG( NULL != property );
2759 // property is being used in a separate thread; queue a message to set the property
2760 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2765 case Property::VECTOR2:
2767 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2768 DALI_ASSERT_DEBUG( NULL != property );
2770 // property is being used in a separate thread; queue a message to set the property
2771 if(entry.componentIndex == 0)
2773 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2775 else if(entry.componentIndex == 1)
2777 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2781 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2787 case Property::VECTOR3:
2789 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2790 DALI_ASSERT_DEBUG( NULL != property );
2792 // property is being used in a separate thread; queue a message to set the property
2793 if(entry.componentIndex == 0)
2795 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2797 else if(entry.componentIndex == 1)
2799 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2801 else if(entry.componentIndex == 2)
2803 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2807 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2813 case Property::VECTOR4:
2815 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2816 DALI_ASSERT_DEBUG( NULL != property );
2818 // property is being used in a separate thread; queue a message to set the property
2819 if(entry.componentIndex == 0)
2821 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2823 else if(entry.componentIndex == 1)
2825 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2827 else if(entry.componentIndex == 2)
2829 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2831 else if(entry.componentIndex == 3)
2833 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2837 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2843 case Property::ROTATION:
2845 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2846 DALI_ASSERT_DEBUG( NULL != property );
2848 // property is being used in a separate thread; queue a message to set the property
2849 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2854 case Property::MATRIX:
2856 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2857 DALI_ASSERT_DEBUG( NULL != property );
2859 // property is being used in a separate thread; queue a message to set the property
2860 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2865 case Property::MATRIX3:
2867 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2868 DALI_ASSERT_DEBUG( NULL != property );
2870 // property is being used in a separate thread; queue a message to set the property
2871 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2878 // nothing to do for other types
2883 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2885 Property::Value value;
2887 if( index >= DEFAULT_PROPERTY_COUNT )
2894 case Dali::Actor::Property::PARENT_ORIGIN:
2896 value = GetCurrentParentOrigin();
2900 case Dali::Actor::Property::PARENT_ORIGIN_X:
2902 value = GetCurrentParentOrigin().x;
2906 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2908 value = GetCurrentParentOrigin().y;
2912 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2914 value = GetCurrentParentOrigin().z;
2918 case Dali::Actor::Property::ANCHOR_POINT:
2920 value = GetCurrentAnchorPoint();
2924 case Dali::Actor::Property::ANCHOR_POINT_X:
2926 value = GetCurrentAnchorPoint().x;
2930 case Dali::Actor::Property::ANCHOR_POINT_Y:
2932 value = GetCurrentAnchorPoint().y;
2936 case Dali::Actor::Property::ANCHOR_POINT_Z:
2938 value = GetCurrentAnchorPoint().z;
2942 case Dali::Actor::Property::SIZE:
2944 value = GetTargetSize();
2948 case Dali::Actor::Property::SIZE_WIDTH:
2950 value = GetTargetSize().width;
2954 case Dali::Actor::Property::SIZE_HEIGHT:
2956 value = GetTargetSize().height;
2960 case Dali::Actor::Property::SIZE_DEPTH:
2962 value = GetTargetSize().depth;
2966 case Dali::Actor::Property::POSITION:
2968 value = GetTargetPosition();
2972 case Dali::Actor::Property::POSITION_X:
2974 value = GetTargetPosition().x;
2978 case Dali::Actor::Property::POSITION_Y:
2980 value = GetTargetPosition().y;
2984 case Dali::Actor::Property::POSITION_Z:
2986 value = GetTargetPosition().z;
2990 case Dali::Actor::Property::WORLD_POSITION:
2992 value = GetCurrentWorldPosition();
2996 case Dali::Actor::Property::WORLD_POSITION_X:
2998 value = GetCurrentWorldPosition().x;
3002 case Dali::Actor::Property::WORLD_POSITION_Y:
3004 value = GetCurrentWorldPosition().y;
3008 case Dali::Actor::Property::WORLD_POSITION_Z:
3010 value = GetCurrentWorldPosition().z;
3014 case Dali::Actor::Property::ORIENTATION:
3016 value = GetCurrentOrientation();
3020 case Dali::Actor::Property::WORLD_ORIENTATION:
3022 value = GetCurrentWorldOrientation();
3026 case Dali::Actor::Property::SCALE:
3028 value = GetCurrentScale();
3032 case Dali::Actor::Property::SCALE_X:
3034 value = GetCurrentScale().x;
3038 case Dali::Actor::Property::SCALE_Y:
3040 value = GetCurrentScale().y;
3044 case Dali::Actor::Property::SCALE_Z:
3046 value = GetCurrentScale().z;
3050 case Dali::Actor::Property::WORLD_SCALE:
3052 value = GetCurrentWorldScale();
3056 case Dali::Actor::Property::VISIBLE:
3058 value = IsVisible();
3062 case Dali::Actor::Property::COLOR:
3064 value = GetCurrentColor();
3068 case Dali::Actor::Property::COLOR_RED:
3070 value = GetCurrentColor().r;
3074 case Dali::Actor::Property::COLOR_GREEN:
3076 value = GetCurrentColor().g;
3080 case Dali::Actor::Property::COLOR_BLUE:
3082 value = GetCurrentColor().b;
3086 case Dali::Actor::Property::COLOR_ALPHA:
3088 value = GetCurrentColor().a;
3092 case Dali::Actor::Property::WORLD_COLOR:
3094 value = GetCurrentWorldColor();
3098 case Dali::Actor::Property::WORLD_MATRIX:
3100 value = GetCurrentWorldMatrix();
3104 case Dali::Actor::Property::NAME:
3110 case Dali::Actor::Property::SENSITIVE:
3112 value = IsSensitive();
3116 case Dali::Actor::Property::LEAVE_REQUIRED:
3118 value = GetLeaveRequired();
3122 case Dali::Actor::Property::INHERIT_POSITION:
3124 value = IsPositionInherited();
3128 case Dali::Actor::Property::INHERIT_ORIENTATION:
3130 value = IsOrientationInherited();
3134 case Dali::Actor::Property::INHERIT_SCALE:
3136 value = IsScaleInherited();
3140 case Dali::Actor::Property::COLOR_MODE:
3142 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3146 case Dali::Actor::Property::POSITION_INHERITANCE:
3148 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3152 case Dali::Actor::Property::DRAW_MODE:
3154 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3158 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3160 value = GetSizeModeFactor();
3164 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3166 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3170 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3172 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3176 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3178 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3182 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3184 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3188 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3190 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3194 case Dali::Actor::Property::PADDING:
3196 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3197 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3198 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3202 case Dali::Actor::Property::MINIMUM_SIZE:
3204 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3208 case Dali::Actor::Property::MAXIMUM_SIZE:
3210 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3214 case Dali::DevelActor::Property::BATCH_PARENT:
3216 value = mIsBatchParent;
3220 case Dali::DevelActor::Property::SIBLING_ORDER:
3222 value = static_cast<int>(mSiblingOrder);
3226 case Dali::Actor::Property::CLIPPING_MODE:
3228 value = mClippingMode;
3236 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3241 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3243 // This method should only return an object connected to the scene-graph
3244 return OnStage() ? mNode : NULL;
3247 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3249 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3251 const PropertyBase* property( NULL );
3253 // This method should only return a property of an object connected to the scene-graph
3259 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3261 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3262 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3264 property = animatable->GetSceneGraphProperty();
3266 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3267 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3269 CustomPropertyMetadata* custom = FindCustomProperty( index );
3270 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3272 property = custom->GetSceneGraphProperty();
3274 else if( NULL != mNode )
3278 case Dali::Actor::Property::SIZE:
3279 property = &mNode->mSize;
3282 case Dali::Actor::Property::SIZE_WIDTH:
3283 property = &mNode->mSize;
3286 case Dali::Actor::Property::SIZE_HEIGHT:
3287 property = &mNode->mSize;
3290 case Dali::Actor::Property::SIZE_DEPTH:
3291 property = &mNode->mSize;
3294 case Dali::Actor::Property::POSITION:
3295 property = &mNode->mPosition;
3298 case Dali::Actor::Property::POSITION_X:
3299 property = &mNode->mPosition;
3302 case Dali::Actor::Property::POSITION_Y:
3303 property = &mNode->mPosition;
3306 case Dali::Actor::Property::POSITION_Z:
3307 property = &mNode->mPosition;
3310 case Dali::Actor::Property::ORIENTATION:
3311 property = &mNode->mOrientation;
3314 case Dali::Actor::Property::SCALE:
3315 property = &mNode->mScale;
3318 case Dali::Actor::Property::SCALE_X:
3319 property = &mNode->mScale;
3322 case Dali::Actor::Property::SCALE_Y:
3323 property = &mNode->mScale;
3326 case Dali::Actor::Property::SCALE_Z:
3327 property = &mNode->mScale;
3330 case Dali::Actor::Property::VISIBLE:
3331 property = &mNode->mVisible;
3334 case Dali::Actor::Property::COLOR:
3335 property = &mNode->mColor;
3338 case Dali::Actor::Property::COLOR_RED:
3339 property = &mNode->mColor;
3342 case Dali::Actor::Property::COLOR_GREEN:
3343 property = &mNode->mColor;
3346 case Dali::Actor::Property::COLOR_BLUE:
3347 property = &mNode->mColor;
3350 case Dali::Actor::Property::COLOR_ALPHA:
3351 property = &mNode->mColor;
3362 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3364 const PropertyInputImpl* property( NULL );
3366 // This method should only return a property of an object connected to the scene-graph
3372 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3374 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3375 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3377 property = animatable->GetSceneGraphProperty();
3379 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3380 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3382 CustomPropertyMetadata* custom = FindCustomProperty( index );
3383 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3384 property = custom->GetSceneGraphProperty();
3386 else if( NULL != mNode )
3390 case Dali::Actor::Property::PARENT_ORIGIN:
3391 property = &mNode->mParentOrigin;
3394 case Dali::Actor::Property::PARENT_ORIGIN_X:
3395 property = &mNode->mParentOrigin;
3398 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3399 property = &mNode->mParentOrigin;
3402 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3403 property = &mNode->mParentOrigin;
3406 case Dali::Actor::Property::ANCHOR_POINT:
3407 property = &mNode->mAnchorPoint;
3410 case Dali::Actor::Property::ANCHOR_POINT_X:
3411 property = &mNode->mAnchorPoint;
3414 case Dali::Actor::Property::ANCHOR_POINT_Y:
3415 property = &mNode->mAnchorPoint;
3418 case Dali::Actor::Property::ANCHOR_POINT_Z:
3419 property = &mNode->mAnchorPoint;
3422 case Dali::Actor::Property::SIZE:
3423 property = &mNode->mSize;
3426 case Dali::Actor::Property::SIZE_WIDTH:
3427 property = &mNode->mSize;
3430 case Dali::Actor::Property::SIZE_HEIGHT:
3431 property = &mNode->mSize;
3434 case Dali::Actor::Property::SIZE_DEPTH:
3435 property = &mNode->mSize;
3438 case Dali::Actor::Property::POSITION:
3439 property = &mNode->mPosition;
3442 case Dali::Actor::Property::POSITION_X:
3443 property = &mNode->mPosition;
3446 case Dali::Actor::Property::POSITION_Y:
3447 property = &mNode->mPosition;
3450 case Dali::Actor::Property::POSITION_Z:
3451 property = &mNode->mPosition;
3454 case Dali::Actor::Property::WORLD_POSITION:
3455 property = &mNode->mWorldPosition;
3458 case Dali::Actor::Property::WORLD_POSITION_X:
3459 property = &mNode->mWorldPosition;
3462 case Dali::Actor::Property::WORLD_POSITION_Y:
3463 property = &mNode->mWorldPosition;
3466 case Dali::Actor::Property::WORLD_POSITION_Z:
3467 property = &mNode->mWorldPosition;
3470 case Dali::Actor::Property::ORIENTATION:
3471 property = &mNode->mOrientation;
3474 case Dali::Actor::Property::WORLD_ORIENTATION:
3475 property = &mNode->mWorldOrientation;
3478 case Dali::Actor::Property::SCALE:
3479 property = &mNode->mScale;
3482 case Dali::Actor::Property::SCALE_X:
3483 property = &mNode->mScale;
3486 case Dali::Actor::Property::SCALE_Y:
3487 property = &mNode->mScale;
3490 case Dali::Actor::Property::SCALE_Z:
3491 property = &mNode->mScale;
3494 case Dali::Actor::Property::WORLD_SCALE:
3495 property = &mNode->mWorldScale;
3498 case Dali::Actor::Property::VISIBLE:
3499 property = &mNode->mVisible;
3502 case Dali::Actor::Property::COLOR:
3503 property = &mNode->mColor;
3506 case Dali::Actor::Property::COLOR_RED:
3507 property = &mNode->mColor;
3510 case Dali::Actor::Property::COLOR_GREEN:
3511 property = &mNode->mColor;
3514 case Dali::Actor::Property::COLOR_BLUE:
3515 property = &mNode->mColor;
3518 case Dali::Actor::Property::COLOR_ALPHA:
3519 property = &mNode->mColor;
3522 case Dali::Actor::Property::WORLD_COLOR:
3523 property = &mNode->mWorldColor;
3526 case Dali::Actor::Property::WORLD_MATRIX:
3527 property = &mNode->mWorldMatrix;
3538 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3540 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3542 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3544 // check whether the animatable property is registered already, if not then register one.
3545 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3546 if( animatableProperty )
3548 componentIndex = animatableProperty->componentIndex;
3555 case Dali::Actor::Property::PARENT_ORIGIN_X:
3556 case Dali::Actor::Property::ANCHOR_POINT_X:
3557 case Dali::Actor::Property::SIZE_WIDTH:
3558 case Dali::Actor::Property::POSITION_X:
3559 case Dali::Actor::Property::WORLD_POSITION_X:
3560 case Dali::Actor::Property::SCALE_X:
3561 case Dali::Actor::Property::COLOR_RED:
3567 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3568 case Dali::Actor::Property::ANCHOR_POINT_Y:
3569 case Dali::Actor::Property::SIZE_HEIGHT:
3570 case Dali::Actor::Property::POSITION_Y:
3571 case Dali::Actor::Property::WORLD_POSITION_Y:
3572 case Dali::Actor::Property::SCALE_Y:
3573 case Dali::Actor::Property::COLOR_GREEN:
3579 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3580 case Dali::Actor::Property::ANCHOR_POINT_Z:
3581 case Dali::Actor::Property::SIZE_DEPTH:
3582 case Dali::Actor::Property::POSITION_Z:
3583 case Dali::Actor::Property::WORLD_POSITION_Z:
3584 case Dali::Actor::Property::SCALE_Z:
3585 case Dali::Actor::Property::COLOR_BLUE:
3591 case Dali::Actor::Property::COLOR_ALPHA:
3605 return componentIndex;
3608 void Actor::SetParent( Actor* parent )
3612 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3616 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3619 // Instruct each actor to create a corresponding node in the scene graph
3620 ConnectToStage( parent->GetHierarchyDepth() );
3623 // Resolve the name and index for the child properties if any
3624 ResolveChildProperties();
3626 else // parent being set to NULL
3628 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3632 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3635 DALI_ASSERT_ALWAYS( mNode != NULL );
3639 // Disconnect the Node & its children from the scene-graph.
3640 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3643 // Instruct each actor to discard pointers to the scene-graph
3644 DisconnectFromStage();
3649 SceneGraph::Node* Actor::CreateNode() const
3654 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3657 Actor* actor = dynamic_cast< Actor* >( object );
3661 if( 0 == actionName.compare( ACTION_SHOW ) )
3663 actor->SetVisible( true );
3666 else if( 0 == actionName.compare( ACTION_HIDE ) )
3668 actor->SetVisible( false );
3676 void Actor::EnsureRelayoutData()
3678 // Assign relayout data.
3679 if( !mRelayoutData )
3681 mRelayoutData = new RelayoutData();
3685 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3687 // Check if actor is dependent on parent
3688 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3690 if( ( dimension & ( 1 << i ) ) )
3692 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3693 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3703 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3705 // Check if actor is dependent on children
3706 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3708 if( ( dimension & ( 1 << i ) ) )
3710 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3711 switch( resizePolicy )
3713 case ResizePolicy::FIT_TO_CHILDREN:
3714 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3730 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3732 return Actor::RelayoutDependentOnChildren( dimension );
3735 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3737 // Check each possible dimension and see if it is dependent on the input one
3738 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3740 if( dimension & ( 1 << i ) )
3742 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3749 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3751 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3753 if( dimension & ( 1 << i ) )
3755 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3760 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3762 // If more than one dimension is requested, just return the first one found
3763 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3765 if( ( dimension & ( 1 << i ) ) )
3767 return mRelayoutData->negotiatedDimensions[ i ];
3771 return 0.0f; // Default
3774 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3776 EnsureRelayoutData();
3778 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3780 if( dimension & ( 1 << i ) )
3782 mRelayoutData->dimensionPadding[ i ] = padding;
3787 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3789 if ( mRelayoutData )
3791 // If more than one dimension is requested, just return the first one found
3792 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3794 if( ( dimension & ( 1 << i ) ) )
3796 return mRelayoutData->dimensionPadding[ i ];
3801 return GetDefaultDimensionPadding();
3804 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3806 EnsureRelayoutData();
3808 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3810 if( dimension & ( 1 << i ) )
3812 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3817 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3819 if ( mRelayoutData )
3821 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3823 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3833 float Actor::GetHeightForWidthBase( float width )
3835 float height = 0.0f;
3837 const Vector3 naturalSize = GetNaturalSize();
3838 if( naturalSize.width > 0.0f )
3840 height = naturalSize.height * width / naturalSize.width;
3842 else // we treat 0 as 1:1 aspect ratio
3850 float Actor::GetWidthForHeightBase( float height )
3854 const Vector3 naturalSize = GetNaturalSize();
3855 if( naturalSize.height > 0.0f )
3857 width = naturalSize.width * height / naturalSize.height;
3859 else // we treat 0 as 1:1 aspect ratio
3867 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3869 // Fill to parent, taking size mode factor into account
3870 switch( child.GetResizePolicy( dimension ) )
3872 case ResizePolicy::FILL_TO_PARENT:
3874 return GetLatestSize( dimension );
3877 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3879 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3882 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3884 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3889 return GetLatestSize( dimension );
3894 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3896 // Can be overridden in derived class
3897 return CalculateChildSizeBase( child, dimension );
3900 float Actor::GetHeightForWidth( float width )
3902 // Can be overridden in derived class
3903 return GetHeightForWidthBase( width );
3906 float Actor::GetWidthForHeight( float height )
3908 // Can be overridden in derived class
3909 return GetWidthForHeightBase( height );
3912 float Actor::GetLatestSize( Dimension::Type dimension ) const
3914 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3917 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3919 Vector2 padding = GetPadding( dimension );
3921 return GetLatestSize( dimension ) + padding.x + padding.y;
3924 float Actor::NegotiateFromParent( Dimension::Type dimension )
3926 Actor* parent = GetParent();
3929 Vector2 padding( GetPadding( dimension ) );
3930 Vector2 parentPadding( parent->GetPadding( dimension ) );
3931 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3937 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3939 float maxDimensionPoint = 0.0f;
3941 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3943 ActorPtr child = GetChildAt( i );
3945 if( !child->RelayoutDependentOnParent( dimension ) )
3947 // Calculate the min and max points that the children range across
3948 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3949 float dimensionSize = child->GetRelayoutSize( dimension );
3950 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3954 return maxDimensionPoint;
3957 float Actor::GetSize( Dimension::Type dimension ) const
3959 return GetDimensionValue( GetTargetSize(), dimension );
3962 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3964 return GetDimensionValue( GetNaturalSize(), dimension );
3967 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3969 switch( GetResizePolicy( dimension ) )
3971 case ResizePolicy::USE_NATURAL_SIZE:
3973 return GetNaturalSize( dimension );
3976 case ResizePolicy::FIXED:
3978 return GetDimensionValue( GetPreferredSize(), dimension );
3981 case ResizePolicy::USE_ASSIGNED_SIZE:
3983 return GetDimensionValue( maximumSize, dimension );
3986 case ResizePolicy::FILL_TO_PARENT:
3987 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3988 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3990 return NegotiateFromParent( dimension );
3993 case ResizePolicy::FIT_TO_CHILDREN:
3995 return NegotiateFromChildren( dimension );
3998 case ResizePolicy::DIMENSION_DEPENDENCY:
4000 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4003 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4005 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4008 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4010 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4022 return 0.0f; // Default
4025 float Actor::ClampDimension( float size, Dimension::Type dimension )
4027 const float minSize = GetMinimumSize( dimension );
4028 const float maxSize = GetMaximumSize( dimension );
4030 return std::max( minSize, std::min( size, maxSize ) );
4033 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4035 // Check if it needs to be negotiated
4036 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4038 // Check that we havn't gotten into an infinite loop
4039 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4040 bool recursionFound = false;
4041 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4043 if( *it == searchActor )
4045 recursionFound = true;
4050 if( !recursionFound )
4052 // Record the path that we have taken
4053 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4055 // Dimension dependency check
4056 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4058 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4060 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4062 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4066 // Parent dependency check
4067 Actor* parent = GetParent();
4068 if( parent && RelayoutDependentOnParent( dimension ) )
4070 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4073 // Children dependency check
4074 if( RelayoutDependentOnChildren( dimension ) )
4076 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4078 ActorPtr child = GetChildAt( i );
4080 // Only relayout child first if it is not dependent on this actor
4081 if( !child->RelayoutDependentOnParent( dimension ) )
4083 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4088 // For deriving classes
4089 OnCalculateRelayoutSize( dimension );
4091 // All dependencies checked, calculate the size and set negotiated flag
4092 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4094 SetNegotiatedDimension( newSize, dimension );
4095 SetLayoutNegotiated( true, dimension );
4097 // For deriving classes
4098 OnLayoutNegotiated( newSize, dimension );
4100 // This actor has been successfully processed, pop it off the recursion stack
4101 recursionStack.pop_back();
4105 // TODO: Break infinite loop
4106 SetLayoutNegotiated( true, dimension );
4111 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4113 // Negotiate all dimensions that require it
4114 ActorDimensionStack recursionStack;
4116 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4118 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4121 NegotiateDimension( dimension, allocatedSize, recursionStack );
4125 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4127 switch( mRelayoutData->sizeSetPolicy )
4129 case SizeScalePolicy::USE_SIZE_SET:
4134 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4136 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4137 const Vector3 naturalSize = GetNaturalSize();
4138 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4140 const float sizeRatio = size.width / size.height;
4141 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4143 if( naturalSizeRatio < sizeRatio )
4145 return Vector2( naturalSizeRatio * size.height, size.height );
4147 else if( naturalSizeRatio > sizeRatio )
4149 return Vector2( size.width, size.width / naturalSizeRatio );
4160 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4162 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4163 const Vector3 naturalSize = GetNaturalSize();
4164 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4166 const float sizeRatio = size.width / size.height;
4167 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4169 if( naturalSizeRatio < sizeRatio )
4171 return Vector2( size.width, size.width / naturalSizeRatio );
4173 else if( naturalSizeRatio > sizeRatio )
4175 return Vector2( naturalSizeRatio * size.height, size.height );
4194 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4196 // Do the set actor size
4197 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4199 // Adjust for size set policy
4200 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4202 // Lock the flag to stop recursive relayouts on set size
4203 mRelayoutData->insideRelayout = true;
4204 SetSize( negotiatedSize );
4205 mRelayoutData->insideRelayout = false;
4207 // Clear flags for all dimensions
4208 SetLayoutDirty( false );
4210 // Give deriving classes a chance to respond
4211 OnRelayout( negotiatedSize, container );
4213 if( !mOnRelayoutSignal.Empty() )
4215 Dali::Actor handle( this );
4216 mOnRelayoutSignal.Emit( handle );
4220 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4222 // Force a size negotiation for actors that has assigned size during relayout
4223 // This is required as otherwise the flags that force a relayout will not
4224 // necessarilly be set. This will occur if the actor has already been laid out.
4225 // The dirty flags are then cleared. Then if the actor is added back into the
4226 // relayout container afterwards, the dirty flags would still be clear...
4227 // causing a relayout to be skipped. Here we force any actors added to the
4228 // container to be relayed out.
4229 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4231 SetLayoutNegotiated(false, Dimension::WIDTH);
4233 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4235 SetLayoutNegotiated(false, Dimension::HEIGHT);
4238 // Do the negotiation
4239 NegotiateDimensions( allocatedSize );
4241 // Set the actor size
4242 SetNegotiatedSize( container );
4244 // Negotiate down to children
4245 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4247 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4249 ActorPtr child = GetChildAt( i );
4251 // Forces children that have already been laid out to be relayed out
4252 // if they have assigned size during relayout.
4253 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4255 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4256 child->SetLayoutDirty(true, Dimension::WIDTH);
4258 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4260 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4261 child->SetLayoutDirty(true, Dimension::HEIGHT);
4264 // Only relayout if required
4265 if( child->RelayoutRequired() )
4267 container.Add( Dali::Actor( child.Get() ), newBounds );
4272 void Actor::RelayoutRequest( Dimension::Type dimension )
4274 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4275 if( relayoutController )
4277 Dali::Actor self( this );
4278 relayoutController->RequestRelayout( self, dimension );
4282 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4286 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4290 void Actor::SetPreferredSize( const Vector2& size )
4292 EnsureRelayoutData();
4294 if( size.width > 0.0f )
4296 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4299 if( size.height > 0.0f )
4301 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4304 mRelayoutData->preferredSize = size;
4309 Vector2 Actor::GetPreferredSize() const
4311 if ( mRelayoutData )
4313 return Vector2( mRelayoutData->preferredSize );
4316 return GetDefaultPreferredSize();
4319 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4321 EnsureRelayoutData();
4323 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4325 if( dimension & ( 1 << i ) )
4327 mRelayoutData->minimumSize[ i ] = size;
4334 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4336 if ( mRelayoutData )
4338 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4340 if( dimension & ( 1 << i ) )
4342 return mRelayoutData->minimumSize[ i ];
4347 return 0.0f; // Default
4350 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4352 EnsureRelayoutData();
4354 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4356 if( dimension & ( 1 << i ) )
4358 mRelayoutData->maximumSize[ i ] = size;
4365 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4367 if ( mRelayoutData )
4369 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4371 if( dimension & ( 1 << i ) )
4373 return mRelayoutData->maximumSize[ i ];
4378 return FLT_MAX; // Default
4381 Object* Actor::GetParentObject() const
4386 } // namespace Internal