2 * Copyright (c) 2017 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::ACTOR_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 unsigned int Actor::GetSortingDepth()
1022 return GetDepthIndex( mDepth, mSiblingOrder );
1025 const Vector4& Actor::GetCurrentWorldColor() const
1029 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1032 return Color::WHITE;
1035 void Actor::SetColor( const Vector4& color )
1039 // mNode is being used in a separate thread; queue a message to set the value & base value
1040 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1044 void Actor::SetColorRed( float red )
1048 // mNode is being used in a separate thread; queue a message to set the value & base value
1049 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1053 void Actor::SetColorGreen( float green )
1057 // mNode is being used in a separate thread; queue a message to set the value & base value
1058 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1062 void Actor::SetColorBlue( float blue )
1066 // mNode is being used in a separate thread; queue a message to set the value & base value
1067 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1071 const Vector4& Actor::GetCurrentColor() const
1075 // mNode is being used in a separate thread; copy the value from the previous update
1076 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1079 return Color::WHITE;
1082 void Actor::SetInheritOrientation( bool inherit )
1084 if( mInheritOrientation != inherit && NULL != mNode)
1086 // non animateable so keep local copy
1087 mInheritOrientation = inherit;
1088 // mNode is being used in a separate thread; queue a message to set the value
1089 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1093 bool Actor::IsOrientationInherited() const
1095 return mInheritOrientation;
1098 void Actor::SetSizeModeFactor( const Vector3& factor )
1100 EnsureRelayoutData();
1102 mRelayoutData->sizeModeFactor = factor;
1105 const Vector3& Actor::GetSizeModeFactor() const
1107 if ( mRelayoutData )
1109 return mRelayoutData->sizeModeFactor;
1112 return GetDefaultSizeModeFactor();
1115 void Actor::SetColorMode( ColorMode colorMode )
1117 // non animateable so keep local copy
1118 mColorMode = colorMode;
1121 // mNode is being used in a separate thread; queue a message to set the value
1122 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1126 ColorMode Actor::GetColorMode() const
1128 // we have cached copy
1132 void Actor::SetSize( float width, float height )
1134 SetSize( Vector2( width, height ) );
1137 void Actor::SetSize( float width, float height, float depth )
1139 SetSize( Vector3( width, height, depth ) );
1142 void Actor::SetSize( const Vector2& size )
1144 SetSize( Vector3( size.width, size.height, 0.f ) );
1147 void Actor::SetSizeInternal( const Vector2& size )
1149 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1152 void Actor::SetSize( const Vector3& size )
1154 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1156 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1157 SetPreferredSize( size.GetVectorXY() );
1161 SetSizeInternal( size );
1165 void Actor::SetSizeInternal( const Vector3& size )
1167 // dont allow recursive loop
1168 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1169 // 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
1170 if( ( NULL != mNode )&&
1171 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1172 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1173 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1177 // mNode is being used in a separate thread; queue a message to set the value & base value
1178 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1180 // Notification for derived classes
1181 mInsideOnSizeSet = true;
1182 OnSizeSet( mTargetSize );
1183 mInsideOnSizeSet = false;
1185 // Raise a relayout request if the flag is not locked
1186 if( mRelayoutData && !mRelayoutData->insideRelayout )
1193 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1195 mTargetSize = targetSize;
1197 // Notify deriving classes
1198 OnSizeAnimation( animation, mTargetSize );
1201 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1203 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1205 mTargetSize.width = targetSize;
1207 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1209 mTargetSize.height = targetSize;
1211 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1213 mTargetSize.depth = targetSize;
1215 // Notify deriving classes
1216 OnSizeAnimation( animation, mTargetSize );
1219 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1221 mTargetPosition = targetPosition;
1224 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1226 if ( Dali::Actor::Property::POSITION_X == property )
1228 mTargetPosition.x = targetPosition;
1230 else if ( Dali::Actor::Property::POSITION_Y == property )
1232 mTargetPosition.y = targetPosition;
1234 else if ( Dali::Actor::Property::POSITION_Z == property )
1236 mTargetPosition.z = targetPosition;
1240 void Actor::SetWidth( float width )
1242 mTargetSize.width = width;
1246 // mNode is being used in a separate thread; queue a message to set the value & base value
1247 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1251 void Actor::SetHeight( float height )
1253 mTargetSize.height = height;
1257 // mNode is being used in a separate thread; queue a message to set the value & base value
1258 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1262 void Actor::SetDepth( float depth )
1264 mTargetSize.depth = depth;
1268 // mNode is being used in a separate thread; queue a message to set the value & base value
1269 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1273 const Vector3& Actor::GetTargetSize() const
1278 const Vector3& Actor::GetCurrentSize() const
1282 // mNode is being used in a separate thread; copy the value from the previous update
1283 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1286 return Vector3::ZERO;
1289 Vector3 Actor::GetNaturalSize() const
1291 // It is up to deriving classes to return the appropriate natural size
1292 return Vector3( 0.0f, 0.0f, 0.0f );
1295 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1297 EnsureRelayoutData();
1299 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1301 if( dimension & ( 1 << i ) )
1303 mRelayoutData->resizePolicies[ i ] = policy;
1307 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1309 if( dimension & Dimension::WIDTH )
1311 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1314 if( dimension & Dimension::HEIGHT )
1316 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1320 // If calling SetResizePolicy, assume we want relayout enabled
1321 SetRelayoutEnabled( true );
1323 OnSetResizePolicy( policy, dimension );
1325 // Trigger relayout on this control
1329 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1331 if ( mRelayoutData )
1333 // If more than one dimension is requested, just return the first one found
1334 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1336 if( ( dimension & ( 1 << i ) ) )
1338 return mRelayoutData->resizePolicies[ i ];
1343 return ResizePolicy::DEFAULT;
1346 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1348 EnsureRelayoutData();
1350 mRelayoutData->sizeSetPolicy = policy;
1353 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1355 if ( mRelayoutData )
1357 return mRelayoutData->sizeSetPolicy;
1360 return DEFAULT_SIZE_SCALE_POLICY;
1363 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1365 EnsureRelayoutData();
1367 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1369 if( dimension & ( 1 << i ) )
1371 mRelayoutData->dimensionDependencies[ i ] = dependency;
1376 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1378 if ( mRelayoutData )
1380 // If more than one dimension is requested, just return the first one found
1381 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1383 if( ( dimension & ( 1 << i ) ) )
1385 return mRelayoutData->dimensionDependencies[ i ];
1390 return Dimension::ALL_DIMENSIONS; // Default
1393 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1395 // If relayout data has not been allocated yet and the client is requesting
1396 // to disable it, do nothing
1397 if( mRelayoutData || relayoutEnabled )
1399 EnsureRelayoutData();
1401 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1403 mRelayoutData->relayoutEnabled = relayoutEnabled;
1407 bool Actor::IsRelayoutEnabled() const
1409 // Assume that if relayout data has not been allocated yet then
1410 // relayout is disabled
1411 return mRelayoutData && mRelayoutData->relayoutEnabled;
1414 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1416 EnsureRelayoutData();
1418 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1420 if( dimension & ( 1 << i ) )
1422 mRelayoutData->dimensionDirty[ i ] = dirty;
1427 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1429 if ( mRelayoutData )
1431 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1433 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1443 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1445 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1448 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1450 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1453 unsigned int Actor::AddRenderer( Renderer& renderer )
1457 mRenderers = new RendererContainer;
1460 unsigned int index = mRenderers->size();
1461 RendererPtr rendererPtr = RendererPtr( &renderer );
1462 mRenderers->push_back( rendererPtr );
1463 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1467 unsigned int Actor::GetRendererCount() const
1469 unsigned int rendererCount(0);
1472 rendererCount = mRenderers->size();
1475 return rendererCount;
1478 RendererPtr Actor::GetRendererAt( unsigned int index )
1480 RendererPtr renderer;
1481 if( index < GetRendererCount() )
1483 renderer = ( *mRenderers )[ index ];
1489 void Actor::RemoveRenderer( Renderer& renderer )
1493 RendererIter end = mRenderers->end();
1494 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1496 if( (*iter).Get() == &renderer )
1498 mRenderers->erase( iter );
1499 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1506 void Actor::RemoveRenderer( unsigned int index )
1508 if( index < GetRendererCount() )
1510 RendererPtr renderer = ( *mRenderers )[ index ];
1511 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1512 mRenderers->erase( mRenderers->begin()+index );
1516 bool Actor::IsOverlay() const
1518 return ( DrawMode::OVERLAY_2D == mDrawMode );
1521 void Actor::SetDrawMode( DrawMode::Type drawMode )
1523 // this flag is not animatable so keep the value
1524 mDrawMode = drawMode;
1525 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1527 // mNode is being used in a separate thread; queue a message to set the value
1528 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1532 DrawMode::Type Actor::GetDrawMode() const
1537 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1539 // only valid when on-stage
1540 StagePtr stage = Stage::GetCurrent();
1541 if( stage && OnStage() )
1543 const RenderTaskList& taskList = stage->GetRenderTaskList();
1545 Vector2 converted( screenX, screenY );
1547 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1548 const int taskCount = taskList.GetTaskCount();
1549 for( int i = taskCount - 1; i >= 0; --i )
1551 Dali::RenderTask task = taskList.GetTask( i );
1552 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1554 // found a task where this conversion was ok so return
1562 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1564 bool retval = false;
1565 // only valid when on-stage
1568 CameraActor* camera = renderTask.GetCameraActor();
1572 renderTask.GetViewport( viewport );
1574 // need to translate coordinates to render tasks coordinate space
1575 Vector2 converted( screenX, screenY );
1576 if( renderTask.TranslateCoordinates( converted ) )
1578 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1585 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1587 // Early-out if mNode is NULL
1593 // Get the ModelView matrix
1595 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1597 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1598 Matrix invertedMvp( false/*don't init*/);
1599 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1600 bool success = invertedMvp.Invert();
1602 // Convert to GL coordinates
1603 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1608 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1615 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1621 if( XyPlaneIntersect( nearPos, farPos, local ) )
1623 Vector3 size = GetCurrentSize();
1624 localX = local.x + size.x * 0.5f;
1625 localY = local.y + size.y * 0.5f;
1636 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1639 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1641 Mathematical Formulation
1643 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1645 ( p - c ) dot ( p - c ) = r^2
1647 Given a ray with a point of origin 'o', and a direction vector 'd':
1649 ray(t) = o + td, t >= 0
1651 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1653 (o + td - c ) dot ( o + td - c ) = r^2
1655 To solve for t we first expand the above into a more recognisable quadratic equation form
1657 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1666 B = 2( o - c ) dot d
1667 C = ( o - c ) dot ( o - c ) - r^2
1669 which can be solved using a standard quadratic formula.
1671 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1673 Practical Simplification
1675 In a renderer, we often differentiate between world space and object space. In the object space
1676 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1677 into object space, the mathematical solution presented above can be simplified significantly.
1679 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1683 and we can find the t at which the (transformed) ray intersects the sphere by
1685 ( o + td ) dot ( o + td ) = r^2
1687 According to the reasoning above, we expand the above quadratic equation into the general form
1691 which now has coefficients:
1698 // Early out if mNode is NULL
1704 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1706 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1707 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1708 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1710 // Compute the radius is not needed, square radius it's enough.
1711 const Vector3& size( mNode->GetSize( bufferIndex ) );
1713 // Scale the sphere.
1714 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1716 const float width = size.width * scale.width;
1717 const float height = size.height * scale.height;
1719 float squareSphereRadius = 0.5f * ( width * width + height * height );
1721 float a = rayDir.Dot( rayDir ); // a
1722 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1723 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1725 return ( b2 * b2 - a * c ) >= 0.f;
1728 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1732 if( OnStage() && NULL != mNode )
1734 // Transforms the ray to the local reference system.
1735 // Calculate the inverse of Model matrix
1736 Matrix invModelMatrix( false/*don't init*/);
1738 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1739 invModelMatrix = mNode->GetWorldMatrix(0);
1740 invModelMatrix.Invert();
1742 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1743 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1745 // Test with the actor's XY plane (Normal = 0 0 1 1).
1747 float a = -rayOriginLocal.z;
1748 float b = rayDirLocal.z;
1750 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1752 // Ray travels distance * rayDirLocal to intersect with plane.
1755 const Vector3& size = mNode->GetSize( bufferIndex );
1757 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1758 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1760 // Test with the actor's geometry.
1761 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1768 void Actor::SetLeaveRequired( bool required )
1770 mLeaveRequired = required;
1773 bool Actor::GetLeaveRequired() const
1775 return mLeaveRequired;
1778 void Actor::SetKeyboardFocusable( bool focusable )
1780 mKeyboardFocusable = focusable;
1783 bool Actor::IsKeyboardFocusable() const
1785 return mKeyboardFocusable;
1788 bool Actor::GetTouchRequired() const
1790 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1793 bool Actor::GetHoverRequired() const
1795 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1798 bool Actor::GetWheelEventRequired() const
1800 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1803 bool Actor::IsHittable() const
1805 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1808 ActorGestureData& Actor::GetGestureData()
1810 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1811 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1812 if( NULL == mGestureData )
1814 mGestureData = new ActorGestureData;
1816 return *mGestureData;
1819 bool Actor::IsGestureRequred( Gesture::Type type ) const
1821 return mGestureData && mGestureData->IsGestureRequred( type );
1824 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1826 bool consumed = false;
1828 if( !mTouchSignal.Empty() )
1830 Dali::Actor handle( this );
1831 consumed = mTouchSignal.Emit( handle, touch );
1834 if( !mTouchedSignal.Empty() )
1836 Dali::Actor handle( this );
1837 consumed |= mTouchedSignal.Emit( handle, event );
1842 // Notification for derived classes
1843 consumed = OnTouchEvent( event ); // TODO
1849 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1851 bool consumed = false;
1853 if( !mHoveredSignal.Empty() )
1855 Dali::Actor handle( this );
1856 consumed = mHoveredSignal.Emit( handle, event );
1861 // Notification for derived classes
1862 consumed = OnHoverEvent( event );
1868 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1870 bool consumed = false;
1872 if( !mWheelEventSignal.Empty() )
1874 Dali::Actor handle( this );
1875 consumed = mWheelEventSignal.Emit( handle, event );
1880 // Notification for derived classes
1881 consumed = OnWheelEvent( event );
1887 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1889 return mTouchedSignal;
1892 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1894 return mTouchSignal;
1897 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1899 return mHoveredSignal;
1902 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1904 return mWheelEventSignal;
1907 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1909 return mOnStageSignal;
1912 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1914 return mOffStageSignal;
1917 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1919 return mOnRelayoutSignal;
1922 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1924 bool connected( true );
1925 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1927 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1929 actor->TouchedSignal().Connect( tracker, functor );
1931 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1933 actor->HoveredSignal().Connect( tracker, functor );
1935 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1937 actor->WheelEventSignal().Connect( tracker, functor );
1939 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1941 actor->OnStageSignal().Connect( tracker, functor );
1943 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1945 actor->OffStageSignal().Connect( tracker, functor );
1947 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1949 actor->OnRelayoutSignal().Connect( tracker, functor );
1951 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1953 actor->TouchSignal().Connect( tracker, functor );
1957 // signalName does not match any signal
1964 Actor::Actor( DerivedType derivedType )
1969 mParentOrigin( NULL ),
1970 mAnchorPoint( NULL ),
1971 mRelayoutData( NULL ),
1972 mGestureData( NULL ),
1973 mTargetSize( 0.0f, 0.0f, 0.0f ),
1975 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1978 mIsRoot( ROOT_LAYER == derivedType ),
1979 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1980 mIsOnStage( false ),
1982 mLeaveRequired( false ),
1983 mKeyboardFocusable( false ),
1984 mDerivedRequiresTouch( false ),
1985 mDerivedRequiresHover( false ),
1986 mDerivedRequiresWheelEvent( false ),
1987 mOnStageSignalled( false ),
1988 mInsideOnSizeSet( false ),
1989 mInheritPosition( true ),
1990 mInheritOrientation( true ),
1991 mInheritScale( true ),
1992 mDrawMode( DrawMode::NORMAL ),
1993 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1994 mColorMode( Node::DEFAULT_COLOR_MODE ),
1995 mClippingMode( ClippingMode::DISABLED ),
1996 mIsBatchParent( false )
2000 void Actor::Initialize()
2003 SceneGraph::Node* node = CreateNode();
2005 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2006 mNode = node; // Keep raw-pointer to Node
2010 GetEventThreadServices().RegisterObject( this );
2015 // Remove mParent pointers from children even if we're destroying core,
2016 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2019 ActorConstIter endIter = mChildren->end();
2020 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2022 (*iter)->SetParent( NULL );
2028 // Guard to allow handle destruction after Core has been destroyed
2029 if( EventThreadServices::IsCoreRunning() )
2033 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2034 mNode = NULL; // Node is about to be destroyed
2037 GetEventThreadServices().UnregisterObject( this );
2040 // Cleanup optional gesture data
2041 delete mGestureData;
2043 // Cleanup optional parent origin and anchor
2044 delete mParentOrigin;
2045 delete mAnchorPoint;
2047 // Delete optional relayout data
2050 delete mRelayoutData;
2054 void Actor::ConnectToStage( unsigned int parentDepth )
2056 // This container is used instead of walking the Actor hierarchy.
2057 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2058 ActorContainer connectionList;
2060 // This stage is atomic i.e. not interrupted by user callbacks.
2061 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2063 // Notify applications about the newly connected actors.
2064 const ActorIter endIter = connectionList.end();
2065 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2067 (*iter)->NotifyStageConnection();
2073 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2075 DALI_ASSERT_ALWAYS( !OnStage() );
2079 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2081 ConnectToSceneGraph();
2083 // Notification for internal derived classes
2084 OnStageConnectionInternal();
2086 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2087 connectionList.push_back( ActorPtr( this ) );
2089 // Recursively connect children
2092 ActorConstIter endIter = mChildren->end();
2093 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2095 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2101 * This method is called when the Actor is connected to the Stage.
2102 * The parent must have added its Node to the scene-graph.
2103 * The child must connect its Node to the parent's Node.
2104 * This is recursive; the child calls ConnectToStage() for its children.
2106 void Actor::ConnectToSceneGraph()
2108 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2112 // Reparent Node in next Update
2113 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2116 // Request relayout on all actors that are added to the scenegraph
2119 // Notification for Object::Observers
2123 void Actor::NotifyStageConnection()
2125 // Actors can be removed (in a callback), before the on-stage stage is reported.
2126 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2127 if( OnStage() && !mOnStageSignalled )
2129 // Notification for external (CustomActor) derived classes
2130 OnStageConnectionExternal( mDepth );
2132 if( !mOnStageSignal.Empty() )
2134 Dali::Actor handle( this );
2135 mOnStageSignal.Emit( handle );
2138 // Guard against Remove during callbacks
2141 mOnStageSignalled = true; // signal required next time Actor is removed
2146 void Actor::DisconnectFromStage()
2148 // This container is used instead of walking the Actor hierachy.
2149 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2150 ActorContainer disconnectionList;
2152 // This stage is atomic i.e. not interrupted by user callbacks
2153 RecursiveDisconnectFromStage( disconnectionList );
2155 // Notify applications about the newly disconnected actors.
2156 const ActorIter endIter = disconnectionList.end();
2157 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2159 (*iter)->NotifyStageDisconnection();
2163 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2165 DALI_ASSERT_ALWAYS( OnStage() );
2167 // Recursively disconnect children
2170 ActorConstIter endIter = mChildren->end();
2171 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2173 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2177 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2178 disconnectionList.push_back( ActorPtr( this ) );
2180 // Notification for internal derived classes
2181 OnStageDisconnectionInternal();
2183 DisconnectFromSceneGraph();
2189 * This method is called by an actor or its parent, before a node removal message is sent.
2190 * This is recursive; the child calls DisconnectFromStage() for its children.
2192 void Actor::DisconnectFromSceneGraph()
2194 // Notification for Object::Observers
2195 OnSceneObjectRemove();
2198 void Actor::NotifyStageDisconnection()
2200 // Actors can be added (in a callback), before the off-stage state is reported.
2201 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2202 // only do this step if there is a stage, i.e. Core is not being shut down
2203 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2205 // Notification for external (CustomeActor) derived classes
2206 OnStageDisconnectionExternal();
2208 if( !mOffStageSignal.Empty() )
2210 Dali::Actor handle( this );
2211 mOffStageSignal.Emit( handle );
2214 // Guard against Add during callbacks
2217 mOnStageSignalled = false; // signal required next time Actor is added
2222 bool Actor::IsNodeConnected() const
2224 bool connected( false );
2226 if( OnStage() && ( NULL != mNode ) )
2228 if( IsRoot() || mNode->GetParent() )
2237 unsigned int Actor::GetDefaultPropertyCount() const
2239 return DEFAULT_PROPERTY_COUNT;
2242 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2244 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2246 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2248 indices.PushBack( i );
2252 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2254 if( index < DEFAULT_PROPERTY_COUNT )
2256 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2262 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2264 Property::Index index = Property::INVALID_INDEX;
2266 // Look for name in default properties
2267 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2269 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2270 if( 0 == name.compare( property->name ) )
2280 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2282 if( index < DEFAULT_PROPERTY_COUNT )
2284 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2290 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2292 if( index < DEFAULT_PROPERTY_COUNT )
2294 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2300 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2302 if( index < DEFAULT_PROPERTY_COUNT )
2304 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2310 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2312 if( index < DEFAULT_PROPERTY_COUNT )
2314 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2317 // index out of range...return Property::NONE
2318 return Property::NONE;
2321 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2325 case Dali::Actor::Property::PARENT_ORIGIN:
2327 Property::Type type = property.GetType();
2328 if( type == Property::VECTOR3 )
2330 SetParentOrigin( property.Get< Vector3 >() );
2332 else if ( type == Property::STRING )
2334 std::string parentOriginString;
2335 property.Get( parentOriginString );
2336 Vector3 parentOrigin;
2337 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2339 SetParentOrigin( parentOrigin );
2345 case Dali::Actor::Property::PARENT_ORIGIN_X:
2347 SetParentOriginX( property.Get< float >() );
2351 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2353 SetParentOriginY( property.Get< float >() );
2357 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2359 SetParentOriginZ( property.Get< float >() );
2363 case Dali::Actor::Property::ANCHOR_POINT:
2365 Property::Type type = property.GetType();
2366 if( type == Property::VECTOR3 )
2368 SetAnchorPoint( property.Get< Vector3 >() );
2370 else if ( type == Property::STRING )
2372 std::string anchorPointString;
2373 property.Get( anchorPointString );
2375 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2377 SetAnchorPoint( anchor );
2383 case Dali::Actor::Property::ANCHOR_POINT_X:
2385 SetAnchorPointX( property.Get< float >() );
2389 case Dali::Actor::Property::ANCHOR_POINT_Y:
2391 SetAnchorPointY( property.Get< float >() );
2395 case Dali::Actor::Property::ANCHOR_POINT_Z:
2397 SetAnchorPointZ( property.Get< float >() );
2401 case Dali::Actor::Property::SIZE:
2403 SetSize( property.Get< Vector3 >() );
2407 case Dali::Actor::Property::SIZE_WIDTH:
2409 SetWidth( property.Get< float >() );
2413 case Dali::Actor::Property::SIZE_HEIGHT:
2415 SetHeight( property.Get< float >() );
2419 case Dali::Actor::Property::SIZE_DEPTH:
2421 SetDepth( property.Get< float >() );
2425 case Dali::Actor::Property::POSITION:
2427 SetPosition( property.Get< Vector3 >() );
2431 case Dali::Actor::Property::POSITION_X:
2433 SetX( property.Get< float >() );
2437 case Dali::Actor::Property::POSITION_Y:
2439 SetY( property.Get< float >() );
2443 case Dali::Actor::Property::POSITION_Z:
2445 SetZ( property.Get< float >() );
2449 case Dali::Actor::Property::ORIENTATION:
2451 SetOrientation( property.Get< Quaternion >() );
2455 case Dali::Actor::Property::SCALE:
2457 SetScale( property.Get< Vector3 >() );
2461 case Dali::Actor::Property::SCALE_X:
2463 SetScaleX( property.Get< float >() );
2467 case Dali::Actor::Property::SCALE_Y:
2469 SetScaleY( property.Get< float >() );
2473 case Dali::Actor::Property::SCALE_Z:
2475 SetScaleZ( property.Get< float >() );
2479 case Dali::Actor::Property::VISIBLE:
2481 SetVisible( property.Get< bool >() );
2485 case Dali::Actor::Property::COLOR:
2487 SetColor( property.Get< Vector4 >() );
2491 case Dali::Actor::Property::COLOR_RED:
2493 SetColorRed( property.Get< float >() );
2497 case Dali::Actor::Property::COLOR_GREEN:
2499 SetColorGreen( property.Get< float >() );
2503 case Dali::Actor::Property::COLOR_BLUE:
2505 SetColorBlue( property.Get< float >() );
2509 case Dali::Actor::Property::COLOR_ALPHA:
2511 SetOpacity( property.Get< float >() );
2515 case Dali::Actor::Property::NAME:
2517 SetName( property.Get< std::string >() );
2521 case Dali::Actor::Property::SENSITIVE:
2523 SetSensitive( property.Get< bool >() );
2527 case Dali::Actor::Property::LEAVE_REQUIRED:
2529 SetLeaveRequired( property.Get< bool >() );
2533 case Dali::Actor::Property::INHERIT_POSITION:
2535 SetInheritPosition( property.Get< bool >() );
2539 case Dali::Actor::Property::INHERIT_ORIENTATION:
2541 SetInheritOrientation( property.Get< bool >() );
2545 case Dali::Actor::Property::INHERIT_SCALE:
2547 SetInheritScale( property.Get< bool >() );
2551 case Dali::Actor::Property::COLOR_MODE:
2553 ColorMode mode = mColorMode;
2554 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2556 SetColorMode( mode );
2561 case Dali::Actor::Property::POSITION_INHERITANCE:
2563 PositionInheritanceMode mode = mPositionInheritanceMode;
2564 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2566 SetPositionInheritanceMode( mode );
2571 case Dali::Actor::Property::DRAW_MODE:
2573 DrawMode::Type mode = mDrawMode;
2574 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2576 SetDrawMode( mode );
2581 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2583 SetSizeModeFactor( property.Get< Vector3 >() );
2587 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2589 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2590 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2592 SetResizePolicy( type, Dimension::WIDTH );
2597 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2599 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2600 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2602 SetResizePolicy( type, Dimension::HEIGHT );
2607 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2609 SizeScalePolicy::Type type;
2610 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2612 SetSizeScalePolicy( type );
2617 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2619 if( property.Get< bool >() )
2621 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2626 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2628 if( property.Get< bool >() )
2630 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2635 case Dali::Actor::Property::PADDING:
2637 Vector4 padding = property.Get< Vector4 >();
2638 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2639 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2643 case Dali::Actor::Property::MINIMUM_SIZE:
2645 Vector2 size = property.Get< Vector2 >();
2646 SetMinimumSize( size.x, Dimension::WIDTH );
2647 SetMinimumSize( size.y, Dimension::HEIGHT );
2651 case Dali::Actor::Property::MAXIMUM_SIZE:
2653 Vector2 size = property.Get< Vector2 >();
2654 SetMaximumSize( size.x, Dimension::WIDTH );
2655 SetMaximumSize( size.y, Dimension::HEIGHT );
2659 case Dali::DevelActor::Property::BATCH_PARENT:
2663 if( property.Get( value ) )
2665 if( value != mIsBatchParent )
2667 mIsBatchParent = value;
2668 SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2674 case Dali::DevelActor::Property::SIBLING_ORDER:
2678 if( property.Get( value ) )
2680 if( static_cast<unsigned int>(value) != mSiblingOrder )
2682 mSiblingOrder = value;
2685 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2692 case Dali::Actor::Property::CLIPPING_MODE:
2694 ClippingMode::Type convertedValue = mClippingMode;
2695 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2697 mClippingMode = convertedValue;
2700 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2708 // this can happen in the case of a non-animatable default property so just do nothing
2714 // TODO: This method needs to be removed
2715 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2717 switch( entry.GetType() )
2719 case Property::BOOLEAN:
2721 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2722 DALI_ASSERT_DEBUG( NULL != property );
2724 // property is being used in a separate thread; queue a message to set the property
2725 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2730 case Property::INTEGER:
2732 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2733 DALI_ASSERT_DEBUG( NULL != property );
2735 // property is being used in a separate thread; queue a message to set the property
2736 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2741 case Property::FLOAT:
2743 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2744 DALI_ASSERT_DEBUG( NULL != property );
2746 // property is being used in a separate thread; queue a message to set the property
2747 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2752 case Property::VECTOR2:
2754 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2755 DALI_ASSERT_DEBUG( NULL != property );
2757 // property is being used in a separate thread; queue a message to set the property
2758 if(entry.componentIndex == 0)
2760 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2762 else if(entry.componentIndex == 1)
2764 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2768 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2774 case Property::VECTOR3:
2776 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2777 DALI_ASSERT_DEBUG( NULL != property );
2779 // property is being used in a separate thread; queue a message to set the property
2780 if(entry.componentIndex == 0)
2782 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2784 else if(entry.componentIndex == 1)
2786 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2788 else if(entry.componentIndex == 2)
2790 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2794 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2800 case Property::VECTOR4:
2802 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2803 DALI_ASSERT_DEBUG( NULL != property );
2805 // property is being used in a separate thread; queue a message to set the property
2806 if(entry.componentIndex == 0)
2808 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2810 else if(entry.componentIndex == 1)
2812 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2814 else if(entry.componentIndex == 2)
2816 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2818 else if(entry.componentIndex == 3)
2820 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2824 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2830 case Property::ROTATION:
2832 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2833 DALI_ASSERT_DEBUG( NULL != property );
2835 // property is being used in a separate thread; queue a message to set the property
2836 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2841 case Property::MATRIX:
2843 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2844 DALI_ASSERT_DEBUG( NULL != property );
2846 // property is being used in a separate thread; queue a message to set the property
2847 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2852 case Property::MATRIX3:
2854 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2855 DALI_ASSERT_DEBUG( NULL != property );
2857 // property is being used in a separate thread; queue a message to set the property
2858 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2865 // nothing to do for other types
2870 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2872 Property::Value value;
2874 if( index >= DEFAULT_PROPERTY_COUNT )
2881 case Dali::Actor::Property::PARENT_ORIGIN:
2883 value = GetCurrentParentOrigin();
2887 case Dali::Actor::Property::PARENT_ORIGIN_X:
2889 value = GetCurrentParentOrigin().x;
2893 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2895 value = GetCurrentParentOrigin().y;
2899 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2901 value = GetCurrentParentOrigin().z;
2905 case Dali::Actor::Property::ANCHOR_POINT:
2907 value = GetCurrentAnchorPoint();
2911 case Dali::Actor::Property::ANCHOR_POINT_X:
2913 value = GetCurrentAnchorPoint().x;
2917 case Dali::Actor::Property::ANCHOR_POINT_Y:
2919 value = GetCurrentAnchorPoint().y;
2923 case Dali::Actor::Property::ANCHOR_POINT_Z:
2925 value = GetCurrentAnchorPoint().z;
2929 case Dali::Actor::Property::SIZE:
2931 value = GetTargetSize();
2935 case Dali::Actor::Property::SIZE_WIDTH:
2937 value = GetTargetSize().width;
2941 case Dali::Actor::Property::SIZE_HEIGHT:
2943 value = GetTargetSize().height;
2947 case Dali::Actor::Property::SIZE_DEPTH:
2949 value = GetTargetSize().depth;
2953 case Dali::Actor::Property::POSITION:
2955 value = GetTargetPosition();
2959 case Dali::Actor::Property::POSITION_X:
2961 value = GetTargetPosition().x;
2965 case Dali::Actor::Property::POSITION_Y:
2967 value = GetTargetPosition().y;
2971 case Dali::Actor::Property::POSITION_Z:
2973 value = GetTargetPosition().z;
2977 case Dali::Actor::Property::WORLD_POSITION:
2979 value = GetCurrentWorldPosition();
2983 case Dali::Actor::Property::WORLD_POSITION_X:
2985 value = GetCurrentWorldPosition().x;
2989 case Dali::Actor::Property::WORLD_POSITION_Y:
2991 value = GetCurrentWorldPosition().y;
2995 case Dali::Actor::Property::WORLD_POSITION_Z:
2997 value = GetCurrentWorldPosition().z;
3001 case Dali::Actor::Property::ORIENTATION:
3003 value = GetCurrentOrientation();
3007 case Dali::Actor::Property::WORLD_ORIENTATION:
3009 value = GetCurrentWorldOrientation();
3013 case Dali::Actor::Property::SCALE:
3015 value = GetCurrentScale();
3019 case Dali::Actor::Property::SCALE_X:
3021 value = GetCurrentScale().x;
3025 case Dali::Actor::Property::SCALE_Y:
3027 value = GetCurrentScale().y;
3031 case Dali::Actor::Property::SCALE_Z:
3033 value = GetCurrentScale().z;
3037 case Dali::Actor::Property::WORLD_SCALE:
3039 value = GetCurrentWorldScale();
3043 case Dali::Actor::Property::VISIBLE:
3045 value = IsVisible();
3049 case Dali::Actor::Property::COLOR:
3051 value = GetCurrentColor();
3055 case Dali::Actor::Property::COLOR_RED:
3057 value = GetCurrentColor().r;
3061 case Dali::Actor::Property::COLOR_GREEN:
3063 value = GetCurrentColor().g;
3067 case Dali::Actor::Property::COLOR_BLUE:
3069 value = GetCurrentColor().b;
3073 case Dali::Actor::Property::COLOR_ALPHA:
3075 value = GetCurrentColor().a;
3079 case Dali::Actor::Property::WORLD_COLOR:
3081 value = GetCurrentWorldColor();
3085 case Dali::Actor::Property::WORLD_MATRIX:
3087 value = GetCurrentWorldMatrix();
3091 case Dali::Actor::Property::NAME:
3097 case Dali::Actor::Property::SENSITIVE:
3099 value = IsSensitive();
3103 case Dali::Actor::Property::LEAVE_REQUIRED:
3105 value = GetLeaveRequired();
3109 case Dali::Actor::Property::INHERIT_POSITION:
3111 value = IsPositionInherited();
3115 case Dali::Actor::Property::INHERIT_ORIENTATION:
3117 value = IsOrientationInherited();
3121 case Dali::Actor::Property::INHERIT_SCALE:
3123 value = IsScaleInherited();
3127 case Dali::Actor::Property::COLOR_MODE:
3129 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3133 case Dali::Actor::Property::POSITION_INHERITANCE:
3135 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3139 case Dali::Actor::Property::DRAW_MODE:
3141 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3145 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3147 value = GetSizeModeFactor();
3151 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3153 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3157 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3159 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3163 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3165 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3169 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3171 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3175 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3177 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3181 case Dali::Actor::Property::PADDING:
3183 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3184 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3185 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3189 case Dali::Actor::Property::MINIMUM_SIZE:
3191 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3195 case Dali::Actor::Property::MAXIMUM_SIZE:
3197 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3201 case Dali::DevelActor::Property::BATCH_PARENT:
3203 value = mIsBatchParent;
3207 case Dali::DevelActor::Property::SIBLING_ORDER:
3209 value = static_cast<int>(mSiblingOrder);
3213 case Dali::Actor::Property::CLIPPING_MODE:
3215 value = mClippingMode;
3223 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3228 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3230 // This method should only return an object connected to the scene-graph
3231 return OnStage() ? mNode : NULL;
3234 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3236 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3238 const PropertyBase* property( NULL );
3240 // This method should only return a property of an object connected to the scene-graph
3246 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3248 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3249 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3251 property = animatable->GetSceneGraphProperty();
3253 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3254 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3256 CustomPropertyMetadata* custom = FindCustomProperty( index );
3257 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3259 property = custom->GetSceneGraphProperty();
3261 else if( NULL != mNode )
3265 case Dali::Actor::Property::SIZE:
3266 property = &mNode->mSize;
3269 case Dali::Actor::Property::SIZE_WIDTH:
3270 property = &mNode->mSize;
3273 case Dali::Actor::Property::SIZE_HEIGHT:
3274 property = &mNode->mSize;
3277 case Dali::Actor::Property::SIZE_DEPTH:
3278 property = &mNode->mSize;
3281 case Dali::Actor::Property::POSITION:
3282 property = &mNode->mPosition;
3285 case Dali::Actor::Property::POSITION_X:
3286 property = &mNode->mPosition;
3289 case Dali::Actor::Property::POSITION_Y:
3290 property = &mNode->mPosition;
3293 case Dali::Actor::Property::POSITION_Z:
3294 property = &mNode->mPosition;
3297 case Dali::Actor::Property::ORIENTATION:
3298 property = &mNode->mOrientation;
3301 case Dali::Actor::Property::SCALE:
3302 property = &mNode->mScale;
3305 case Dali::Actor::Property::SCALE_X:
3306 property = &mNode->mScale;
3309 case Dali::Actor::Property::SCALE_Y:
3310 property = &mNode->mScale;
3313 case Dali::Actor::Property::SCALE_Z:
3314 property = &mNode->mScale;
3317 case Dali::Actor::Property::VISIBLE:
3318 property = &mNode->mVisible;
3321 case Dali::Actor::Property::COLOR:
3322 property = &mNode->mColor;
3325 case Dali::Actor::Property::COLOR_RED:
3326 property = &mNode->mColor;
3329 case Dali::Actor::Property::COLOR_GREEN:
3330 property = &mNode->mColor;
3333 case Dali::Actor::Property::COLOR_BLUE:
3334 property = &mNode->mColor;
3337 case Dali::Actor::Property::COLOR_ALPHA:
3338 property = &mNode->mColor;
3349 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3351 const PropertyInputImpl* property( NULL );
3353 // This method should only return a property of an object connected to the scene-graph
3359 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3361 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3362 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3364 property = animatable->GetSceneGraphProperty();
3366 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3367 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3369 CustomPropertyMetadata* custom = FindCustomProperty( index );
3370 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3371 property = custom->GetSceneGraphProperty();
3373 else if( NULL != mNode )
3377 case Dali::Actor::Property::PARENT_ORIGIN:
3378 property = &mNode->mParentOrigin;
3381 case Dali::Actor::Property::PARENT_ORIGIN_X:
3382 property = &mNode->mParentOrigin;
3385 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3386 property = &mNode->mParentOrigin;
3389 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3390 property = &mNode->mParentOrigin;
3393 case Dali::Actor::Property::ANCHOR_POINT:
3394 property = &mNode->mAnchorPoint;
3397 case Dali::Actor::Property::ANCHOR_POINT_X:
3398 property = &mNode->mAnchorPoint;
3401 case Dali::Actor::Property::ANCHOR_POINT_Y:
3402 property = &mNode->mAnchorPoint;
3405 case Dali::Actor::Property::ANCHOR_POINT_Z:
3406 property = &mNode->mAnchorPoint;
3409 case Dali::Actor::Property::SIZE:
3410 property = &mNode->mSize;
3413 case Dali::Actor::Property::SIZE_WIDTH:
3414 property = &mNode->mSize;
3417 case Dali::Actor::Property::SIZE_HEIGHT:
3418 property = &mNode->mSize;
3421 case Dali::Actor::Property::SIZE_DEPTH:
3422 property = &mNode->mSize;
3425 case Dali::Actor::Property::POSITION:
3426 property = &mNode->mPosition;
3429 case Dali::Actor::Property::POSITION_X:
3430 property = &mNode->mPosition;
3433 case Dali::Actor::Property::POSITION_Y:
3434 property = &mNode->mPosition;
3437 case Dali::Actor::Property::POSITION_Z:
3438 property = &mNode->mPosition;
3441 case Dali::Actor::Property::WORLD_POSITION:
3442 property = &mNode->mWorldPosition;
3445 case Dali::Actor::Property::WORLD_POSITION_X:
3446 property = &mNode->mWorldPosition;
3449 case Dali::Actor::Property::WORLD_POSITION_Y:
3450 property = &mNode->mWorldPosition;
3453 case Dali::Actor::Property::WORLD_POSITION_Z:
3454 property = &mNode->mWorldPosition;
3457 case Dali::Actor::Property::ORIENTATION:
3458 property = &mNode->mOrientation;
3461 case Dali::Actor::Property::WORLD_ORIENTATION:
3462 property = &mNode->mWorldOrientation;
3465 case Dali::Actor::Property::SCALE:
3466 property = &mNode->mScale;
3469 case Dali::Actor::Property::SCALE_X:
3470 property = &mNode->mScale;
3473 case Dali::Actor::Property::SCALE_Y:
3474 property = &mNode->mScale;
3477 case Dali::Actor::Property::SCALE_Z:
3478 property = &mNode->mScale;
3481 case Dali::Actor::Property::WORLD_SCALE:
3482 property = &mNode->mWorldScale;
3485 case Dali::Actor::Property::VISIBLE:
3486 property = &mNode->mVisible;
3489 case Dali::Actor::Property::COLOR:
3490 property = &mNode->mColor;
3493 case Dali::Actor::Property::COLOR_RED:
3494 property = &mNode->mColor;
3497 case Dali::Actor::Property::COLOR_GREEN:
3498 property = &mNode->mColor;
3501 case Dali::Actor::Property::COLOR_BLUE:
3502 property = &mNode->mColor;
3505 case Dali::Actor::Property::COLOR_ALPHA:
3506 property = &mNode->mColor;
3509 case Dali::Actor::Property::WORLD_COLOR:
3510 property = &mNode->mWorldColor;
3513 case Dali::Actor::Property::WORLD_MATRIX:
3514 property = &mNode->mWorldMatrix;
3525 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3527 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3529 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3531 // check whether the animatable property is registered already, if not then register one.
3532 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3533 if( animatableProperty )
3535 componentIndex = animatableProperty->componentIndex;
3542 case Dali::Actor::Property::PARENT_ORIGIN_X:
3543 case Dali::Actor::Property::ANCHOR_POINT_X:
3544 case Dali::Actor::Property::SIZE_WIDTH:
3545 case Dali::Actor::Property::POSITION_X:
3546 case Dali::Actor::Property::WORLD_POSITION_X:
3547 case Dali::Actor::Property::SCALE_X:
3548 case Dali::Actor::Property::COLOR_RED:
3554 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3555 case Dali::Actor::Property::ANCHOR_POINT_Y:
3556 case Dali::Actor::Property::SIZE_HEIGHT:
3557 case Dali::Actor::Property::POSITION_Y:
3558 case Dali::Actor::Property::WORLD_POSITION_Y:
3559 case Dali::Actor::Property::SCALE_Y:
3560 case Dali::Actor::Property::COLOR_GREEN:
3566 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3567 case Dali::Actor::Property::ANCHOR_POINT_Z:
3568 case Dali::Actor::Property::SIZE_DEPTH:
3569 case Dali::Actor::Property::POSITION_Z:
3570 case Dali::Actor::Property::WORLD_POSITION_Z:
3571 case Dali::Actor::Property::SCALE_Z:
3572 case Dali::Actor::Property::COLOR_BLUE:
3578 case Dali::Actor::Property::COLOR_ALPHA:
3592 return componentIndex;
3595 void Actor::SetParent( Actor* parent )
3599 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3603 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3606 // Instruct each actor to create a corresponding node in the scene graph
3607 ConnectToStage( parent->GetHierarchyDepth() );
3610 // Resolve the name and index for the child properties if any
3611 ResolveChildProperties();
3613 else // parent being set to NULL
3615 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3619 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3622 DALI_ASSERT_ALWAYS( mNode != NULL );
3626 // Disconnect the Node & its children from the scene-graph.
3627 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3630 // Instruct each actor to discard pointers to the scene-graph
3631 DisconnectFromStage();
3636 SceneGraph::Node* Actor::CreateNode() const
3641 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3644 Actor* actor = dynamic_cast< Actor* >( object );
3648 if( 0 == actionName.compare( ACTION_SHOW ) )
3650 actor->SetVisible( true );
3653 else if( 0 == actionName.compare( ACTION_HIDE ) )
3655 actor->SetVisible( false );
3663 void Actor::EnsureRelayoutData()
3665 // Assign relayout data.
3666 if( !mRelayoutData )
3668 mRelayoutData = new RelayoutData();
3672 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3674 // Check if actor is dependent on parent
3675 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3677 if( ( dimension & ( 1 << i ) ) )
3679 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3680 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3690 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3692 // Check if actor is dependent on children
3693 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3695 if( ( dimension & ( 1 << i ) ) )
3697 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3698 switch( resizePolicy )
3700 case ResizePolicy::FIT_TO_CHILDREN:
3701 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3717 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3719 return Actor::RelayoutDependentOnChildren( dimension );
3722 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3724 // Check each possible dimension and see if it is dependent on the input one
3725 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3727 if( dimension & ( 1 << i ) )
3729 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3736 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3738 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3740 if( dimension & ( 1 << i ) )
3742 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3747 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3749 // If more than one dimension is requested, just return the first one found
3750 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3752 if( ( dimension & ( 1 << i ) ) )
3754 return mRelayoutData->negotiatedDimensions[ i ];
3758 return 0.0f; // Default
3761 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3763 EnsureRelayoutData();
3765 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3767 if( dimension & ( 1 << i ) )
3769 mRelayoutData->dimensionPadding[ i ] = padding;
3774 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3776 if ( mRelayoutData )
3778 // If more than one dimension is requested, just return the first one found
3779 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3781 if( ( dimension & ( 1 << i ) ) )
3783 return mRelayoutData->dimensionPadding[ i ];
3788 return GetDefaultDimensionPadding();
3791 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3793 EnsureRelayoutData();
3795 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3797 if( dimension & ( 1 << i ) )
3799 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3804 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3806 if ( mRelayoutData )
3808 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3810 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3820 float Actor::GetHeightForWidthBase( float width )
3822 float height = 0.0f;
3824 const Vector3 naturalSize = GetNaturalSize();
3825 if( naturalSize.width > 0.0f )
3827 height = naturalSize.height * width / naturalSize.width;
3829 else // we treat 0 as 1:1 aspect ratio
3837 float Actor::GetWidthForHeightBase( float height )
3841 const Vector3 naturalSize = GetNaturalSize();
3842 if( naturalSize.height > 0.0f )
3844 width = naturalSize.width * height / naturalSize.height;
3846 else // we treat 0 as 1:1 aspect ratio
3854 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3856 // Fill to parent, taking size mode factor into account
3857 switch( child.GetResizePolicy( dimension ) )
3859 case ResizePolicy::FILL_TO_PARENT:
3861 return GetLatestSize( dimension );
3864 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3866 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3869 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3871 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3876 return GetLatestSize( dimension );
3881 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3883 // Can be overridden in derived class
3884 return CalculateChildSizeBase( child, dimension );
3887 float Actor::GetHeightForWidth( float width )
3889 // Can be overridden in derived class
3890 return GetHeightForWidthBase( width );
3893 float Actor::GetWidthForHeight( float height )
3895 // Can be overridden in derived class
3896 return GetWidthForHeightBase( height );
3899 float Actor::GetLatestSize( Dimension::Type dimension ) const
3901 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3904 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3906 Vector2 padding = GetPadding( dimension );
3908 return GetLatestSize( dimension ) + padding.x + padding.y;
3911 float Actor::NegotiateFromParent( Dimension::Type dimension )
3913 Actor* parent = GetParent();
3916 Vector2 padding( GetPadding( dimension ) );
3917 Vector2 parentPadding( parent->GetPadding( dimension ) );
3918 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3924 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3926 float maxDimensionPoint = 0.0f;
3928 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3930 ActorPtr child = GetChildAt( i );
3932 if( !child->RelayoutDependentOnParent( dimension ) )
3934 // Calculate the min and max points that the children range across
3935 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3936 float dimensionSize = child->GetRelayoutSize( dimension );
3937 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3941 return maxDimensionPoint;
3944 float Actor::GetSize( Dimension::Type dimension ) const
3946 return GetDimensionValue( GetTargetSize(), dimension );
3949 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3951 return GetDimensionValue( GetNaturalSize(), dimension );
3954 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3956 switch( GetResizePolicy( dimension ) )
3958 case ResizePolicy::USE_NATURAL_SIZE:
3960 return GetNaturalSize( dimension );
3963 case ResizePolicy::FIXED:
3965 return GetDimensionValue( GetPreferredSize(), dimension );
3968 case ResizePolicy::USE_ASSIGNED_SIZE:
3970 return GetDimensionValue( maximumSize, dimension );
3973 case ResizePolicy::FILL_TO_PARENT:
3974 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3975 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3977 return NegotiateFromParent( dimension );
3980 case ResizePolicy::FIT_TO_CHILDREN:
3982 return NegotiateFromChildren( dimension );
3985 case ResizePolicy::DIMENSION_DEPENDENCY:
3987 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3990 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3992 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3995 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3997 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4009 return 0.0f; // Default
4012 float Actor::ClampDimension( float size, Dimension::Type dimension )
4014 const float minSize = GetMinimumSize( dimension );
4015 const float maxSize = GetMaximumSize( dimension );
4017 return std::max( minSize, std::min( size, maxSize ) );
4020 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4022 // Check if it needs to be negotiated
4023 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4025 // Check that we havn't gotten into an infinite loop
4026 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4027 bool recursionFound = false;
4028 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4030 if( *it == searchActor )
4032 recursionFound = true;
4037 if( !recursionFound )
4039 // Record the path that we have taken
4040 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4042 // Dimension dependency check
4043 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4045 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4047 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4049 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4053 // Parent dependency check
4054 Actor* parent = GetParent();
4055 if( parent && RelayoutDependentOnParent( dimension ) )
4057 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4060 // Children dependency check
4061 if( RelayoutDependentOnChildren( dimension ) )
4063 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4065 ActorPtr child = GetChildAt( i );
4067 // Only relayout child first if it is not dependent on this actor
4068 if( !child->RelayoutDependentOnParent( dimension ) )
4070 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4075 // For deriving classes
4076 OnCalculateRelayoutSize( dimension );
4078 // All dependencies checked, calculate the size and set negotiated flag
4079 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4081 SetNegotiatedDimension( newSize, dimension );
4082 SetLayoutNegotiated( true, dimension );
4084 // For deriving classes
4085 OnLayoutNegotiated( newSize, dimension );
4087 // This actor has been successfully processed, pop it off the recursion stack
4088 recursionStack.pop_back();
4092 // TODO: Break infinite loop
4093 SetLayoutNegotiated( true, dimension );
4098 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4100 // Negotiate all dimensions that require it
4101 ActorDimensionStack recursionStack;
4103 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4105 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4108 NegotiateDimension( dimension, allocatedSize, recursionStack );
4112 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4114 switch( mRelayoutData->sizeSetPolicy )
4116 case SizeScalePolicy::USE_SIZE_SET:
4121 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4123 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4124 const Vector3 naturalSize = GetNaturalSize();
4125 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4127 const float sizeRatio = size.width / size.height;
4128 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4130 if( naturalSizeRatio < sizeRatio )
4132 return Vector2( naturalSizeRatio * size.height, size.height );
4134 else if( naturalSizeRatio > sizeRatio )
4136 return Vector2( size.width, size.width / naturalSizeRatio );
4147 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4149 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4150 const Vector3 naturalSize = GetNaturalSize();
4151 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4153 const float sizeRatio = size.width / size.height;
4154 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4156 if( naturalSizeRatio < sizeRatio )
4158 return Vector2( size.width, size.width / naturalSizeRatio );
4160 else if( naturalSizeRatio > sizeRatio )
4162 return Vector2( naturalSizeRatio * size.height, size.height );
4181 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4183 // Do the set actor size
4184 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4186 // Adjust for size set policy
4187 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4189 // Lock the flag to stop recursive relayouts on set size
4190 mRelayoutData->insideRelayout = true;
4191 SetSize( negotiatedSize );
4192 mRelayoutData->insideRelayout = false;
4194 // Clear flags for all dimensions
4195 SetLayoutDirty( false );
4197 // Give deriving classes a chance to respond
4198 OnRelayout( negotiatedSize, container );
4200 if( !mOnRelayoutSignal.Empty() )
4202 Dali::Actor handle( this );
4203 mOnRelayoutSignal.Emit( handle );
4207 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4209 // Force a size negotiation for actors that has assigned size during relayout
4210 // This is required as otherwise the flags that force a relayout will not
4211 // necessarilly be set. This will occur if the actor has already been laid out.
4212 // The dirty flags are then cleared. Then if the actor is added back into the
4213 // relayout container afterwards, the dirty flags would still be clear...
4214 // causing a relayout to be skipped. Here we force any actors added to the
4215 // container to be relayed out.
4216 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4218 SetLayoutNegotiated(false, Dimension::WIDTH);
4220 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4222 SetLayoutNegotiated(false, Dimension::HEIGHT);
4225 // Do the negotiation
4226 NegotiateDimensions( allocatedSize );
4228 // Set the actor size
4229 SetNegotiatedSize( container );
4231 // Negotiate down to children
4232 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4234 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4236 ActorPtr child = GetChildAt( i );
4238 // Forces children that have already been laid out to be relayed out
4239 // if they have assigned size during relayout.
4240 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4242 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4243 child->SetLayoutDirty(true, Dimension::WIDTH);
4245 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4247 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4248 child->SetLayoutDirty(true, Dimension::HEIGHT);
4251 // Only relayout if required
4252 if( child->RelayoutRequired() )
4254 container.Add( Dali::Actor( child.Get() ), newBounds );
4259 void Actor::RelayoutRequest( Dimension::Type dimension )
4261 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4262 if( relayoutController )
4264 Dali::Actor self( this );
4265 relayoutController->RequestRelayout( self, dimension );
4269 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4273 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4277 void Actor::SetPreferredSize( const Vector2& size )
4279 EnsureRelayoutData();
4281 if( size.width > 0.0f )
4283 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4286 if( size.height > 0.0f )
4288 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4291 mRelayoutData->preferredSize = size;
4296 Vector2 Actor::GetPreferredSize() const
4298 if ( mRelayoutData )
4300 return Vector2( mRelayoutData->preferredSize );
4303 return GetDefaultPreferredSize();
4306 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4308 EnsureRelayoutData();
4310 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4312 if( dimension & ( 1 << i ) )
4314 mRelayoutData->minimumSize[ i ] = size;
4321 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4323 if ( mRelayoutData )
4325 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4327 if( dimension & ( 1 << i ) )
4329 return mRelayoutData->minimumSize[ i ];
4334 return 0.0f; // Default
4337 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4339 EnsureRelayoutData();
4341 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4343 if( dimension & ( 1 << i ) )
4345 mRelayoutData->maximumSize[ i ] = size;
4352 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4354 if ( mRelayoutData )
4356 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4358 if( dimension & ( 1 << i ) )
4360 return mRelayoutData->maximumSize[ i ];
4365 return FLT_MAX; // Default
4368 Object* Actor::GetParentObject() const
4373 } // namespace Internal