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::TREE_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
365 } // unnamed namespace
367 ActorPtr Actor::New()
369 ActorPtr actor( new Actor( BASIC ) );
371 // Second-phase construction
377 const std::string& Actor::GetName() const
382 void Actor::SetName( const std::string& name )
388 // ATTENTION: string for debug purposes is not thread safe.
389 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
393 unsigned int Actor::GetId() const
398 bool Actor::OnStage() const
403 Dali::Layer Actor::GetLayer()
407 // Short-circuit for Layer derived actors
410 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
413 // Find the immediate Layer parent
414 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
416 if( parent->IsLayer() )
418 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
425 void Actor::Add( Actor& child )
427 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
428 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
432 mChildren = new ActorContainer;
435 Actor* const oldParent( child.mParent );
437 // child might already be ours
438 if( this != oldParent )
440 // if we already have parent, unparent us first
443 oldParent->Remove( child ); // This causes OnChildRemove callback
445 // Old parent may need to readjust to missing child
446 if( oldParent->RelayoutDependentOnChildren() )
448 oldParent->RelayoutRequest();
452 // Guard against Add() during previous OnChildRemove callback
455 // Do this first, since user callbacks from within SetParent() may need to remove child
456 mChildren->push_back( ActorPtr( &child ) );
458 // SetParent asserts that child can be added
459 child.SetParent( this );
461 // Notification for derived classes
464 // Only put in a relayout request if there is a suitable dependency
465 if( RelayoutDependentOnChildren() )
473 void Actor::Remove( Actor& child )
475 if( (this == &child) || (!mChildren) )
477 // no children or removing itself
483 // Find the child in mChildren, and unparent it
484 ActorIter end = mChildren->end();
485 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
487 ActorPtr actor = (*iter);
489 if( actor.Get() == &child )
491 // Keep handle for OnChildRemove notification
494 // Do this first, since user callbacks from within SetParent() may need to add the child
495 mChildren->erase( iter );
497 DALI_ASSERT_DEBUG( actor->GetParent() == this );
498 actor->SetParent( NULL );
506 // Only put in a relayout request if there is a suitable dependency
507 if( RelayoutDependentOnChildren() )
513 // Notification for derived classes
514 OnChildRemove( child );
517 void Actor::Unparent()
521 // Remove this actor from the parent. The remove will put a relayout request in for
522 // the parent if required
523 mParent->Remove( *this );
524 // mParent is now NULL!
528 unsigned int Actor::GetChildCount() const
530 return ( NULL != mChildren ) ? mChildren->size() : 0;
533 ActorPtr Actor::GetChildAt( unsigned int index ) const
535 DALI_ASSERT_ALWAYS( index < GetChildCount() );
537 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
540 ActorPtr Actor::FindChildByName( const std::string& actorName )
543 if( actorName == mName )
549 ActorIter end = mChildren->end();
550 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
552 child = (*iter)->FindChildByName( actorName );
563 ActorPtr Actor::FindChildById( const unsigned int id )
572 ActorIter end = mChildren->end();
573 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
575 child = (*iter)->FindChildById( id );
586 void Actor::SetParentOrigin( const Vector3& origin )
590 // mNode is being used in a separate thread; queue a message to set the value & base value
591 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
594 // Cache for event-thread access
597 // not allocated, check if different from default
598 if( ParentOrigin::DEFAULT != origin )
600 mParentOrigin = new Vector3( origin );
605 // check if different from current costs more than just set
606 *mParentOrigin = origin;
610 void Actor::SetParentOriginX( float x )
612 const Vector3& current = GetCurrentParentOrigin();
614 SetParentOrigin( Vector3( x, current.y, current.z ) );
617 void Actor::SetParentOriginY( float y )
619 const Vector3& current = GetCurrentParentOrigin();
621 SetParentOrigin( Vector3( current.x, y, current.z ) );
624 void Actor::SetParentOriginZ( float z )
626 const Vector3& current = GetCurrentParentOrigin();
628 SetParentOrigin( Vector3( current.x, current.y, z ) );
631 const Vector3& Actor::GetCurrentParentOrigin() const
633 // Cached for event-thread access
634 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
637 void Actor::SetAnchorPoint( const Vector3& anchor )
641 // mNode is being used in a separate thread; queue a message to set the value & base value
642 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
645 // Cache for event-thread access
648 // not allocated, check if different from default
649 if( AnchorPoint::DEFAULT != anchor )
651 mAnchorPoint = new Vector3( anchor );
656 // check if different from current costs more than just set
657 *mAnchorPoint = anchor;
661 void Actor::SetAnchorPointX( float x )
663 const Vector3& current = GetCurrentAnchorPoint();
665 SetAnchorPoint( Vector3( x, current.y, current.z ) );
668 void Actor::SetAnchorPointY( float y )
670 const Vector3& current = GetCurrentAnchorPoint();
672 SetAnchorPoint( Vector3( current.x, y, current.z ) );
675 void Actor::SetAnchorPointZ( float z )
677 const Vector3& current = GetCurrentAnchorPoint();
679 SetAnchorPoint( Vector3( current.x, current.y, z ) );
682 const Vector3& Actor::GetCurrentAnchorPoint() const
684 // Cached for event-thread access
685 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
688 void Actor::SetPosition( float x, float y )
690 SetPosition( Vector3( x, y, 0.0f ) );
693 void Actor::SetPosition( float x, float y, float z )
695 SetPosition( Vector3( x, y, z ) );
698 void Actor::SetPosition( const Vector3& position )
700 mTargetPosition = position;
704 // mNode is being used in a separate thread; queue a message to set the value & base value
705 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
709 void Actor::SetX( float x )
711 mTargetPosition.x = x;
715 // mNode is being used in a separate thread; queue a message to set the value & base value
716 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
720 void Actor::SetY( float y )
722 mTargetPosition.y = y;
726 // mNode is being used in a separate thread; queue a message to set the value & base value
727 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
731 void Actor::SetZ( float z )
733 mTargetPosition.z = z;
737 // mNode is being used in a separate thread; queue a message to set the value & base value
738 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
742 void Actor::TranslateBy( const Vector3& distance )
744 mTargetPosition += distance;
748 // mNode is being used in a separate thread; queue a message to set the value & base value
749 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
753 const Vector3& Actor::GetCurrentPosition() const
757 // mNode is being used in a separate thread; copy the value from the previous update
758 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
761 return Vector3::ZERO;
764 const Vector3& Actor::GetTargetPosition() const
766 return mTargetPosition;
769 const Vector3& Actor::GetCurrentWorldPosition() const
773 // mNode is being used in a separate thread; copy the value from the previous update
774 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
777 return Vector3::ZERO;
780 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
782 // this flag is not animatable so keep the value
783 mPositionInheritanceMode = mode;
786 // mNode is being used in a separate thread; queue a message to set the value
787 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
791 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
793 // Cached for event-thread access
794 return mPositionInheritanceMode;
797 void Actor::SetInheritPosition( bool inherit )
799 if( mInheritPosition != inherit && NULL != mNode )
801 // non animateable so keep local copy
802 mInheritPosition = inherit;
803 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
807 bool Actor::IsPositionInherited() const
809 return mInheritPosition;
812 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
814 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
815 normalizedAxis.Normalize();
817 Quaternion orientation( angle, normalizedAxis );
819 SetOrientation( orientation );
822 void Actor::SetOrientation( const Quaternion& orientation )
826 // mNode is being used in a separate thread; queue a message to set the value & base value
827 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
831 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
835 // mNode is being used in a separate thread; queue a message to set the value & base value
836 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
840 void Actor::RotateBy( const Quaternion& relativeRotation )
844 // mNode is being used in a separate thread; queue a message to set the value & base value
845 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
849 const Quaternion& Actor::GetCurrentOrientation() const
853 // mNode is being used in a separate thread; copy the value from the previous update
854 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
857 return Quaternion::IDENTITY;
860 const Quaternion& Actor::GetCurrentWorldOrientation() const
864 // mNode is being used in a separate thread; copy the value from the previous update
865 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
868 return Quaternion::IDENTITY;
871 void Actor::SetScale( float scale )
873 SetScale( Vector3( scale, scale, scale ) );
876 void Actor::SetScale( float x, float y, float z )
878 SetScale( Vector3( x, y, z ) );
881 void Actor::SetScale( const Vector3& scale )
885 // mNode is being used in a separate thread; queue a message to set the value & base value
886 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
890 void Actor::SetScaleX( float x )
894 // mNode is being used in a separate thread; queue a message to set the value & base value
895 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
899 void Actor::SetScaleY( float y )
903 // mNode is being used in a separate thread; queue a message to set the value & base value
904 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
908 void Actor::SetScaleZ( float z )
912 // mNode is being used in a separate thread; queue a message to set the value & base value
913 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
917 void Actor::ScaleBy(const Vector3& relativeScale)
921 // mNode is being used in a separate thread; queue a message to set the value & base value
922 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
926 const Vector3& Actor::GetCurrentScale() const
930 // mNode is being used in a separate thread; copy the value from the previous update
931 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
937 const Vector3& Actor::GetCurrentWorldScale() const
941 // mNode is being used in a separate thread; copy the value from the previous update
942 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
948 void Actor::SetInheritScale( bool inherit )
951 if( mInheritScale != inherit && NULL != mNode )
953 // non animateable so keep local copy
954 mInheritScale = inherit;
955 // mNode is being used in a separate thread; queue a message to set the value
956 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
960 bool Actor::IsScaleInherited() const
962 return mInheritScale;
965 Matrix Actor::GetCurrentWorldMatrix() const
969 return mNode->GetWorldMatrix(0);
972 return Matrix::IDENTITY;
975 void Actor::SetVisible( bool visible )
979 // mNode is being used in a separate thread; queue a message to set the value & base value
980 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
984 bool Actor::IsVisible() const
988 // mNode is being used in a separate thread; copy the value from the previous update
989 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
995 void Actor::SetOpacity( float opacity )
999 // mNode is being used in a separate thread; queue a message to set the value & base value
1000 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1004 float Actor::GetCurrentOpacity() const
1008 // mNode is being used in a separate thread; copy the value from the previous update
1009 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1015 ClippingMode::Type Actor::GetClippingMode() const
1017 return mClippingMode;
1020 const Vector4& Actor::GetCurrentWorldColor() const
1024 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1027 return Color::WHITE;
1030 void Actor::SetColor( const Vector4& color )
1034 // mNode is being used in a separate thread; queue a message to set the value & base value
1035 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1039 void Actor::SetColorRed( float red )
1043 // mNode is being used in a separate thread; queue a message to set the value & base value
1044 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1048 void Actor::SetColorGreen( float green )
1052 // mNode is being used in a separate thread; queue a message to set the value & base value
1053 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1057 void Actor::SetColorBlue( float blue )
1061 // mNode is being used in a separate thread; queue a message to set the value & base value
1062 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1066 const Vector4& Actor::GetCurrentColor() const
1070 // mNode is being used in a separate thread; copy the value from the previous update
1071 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1074 return Color::WHITE;
1077 void Actor::SetInheritOrientation( bool inherit )
1079 if( mInheritOrientation != inherit && NULL != mNode)
1081 // non animateable so keep local copy
1082 mInheritOrientation = inherit;
1083 // mNode is being used in a separate thread; queue a message to set the value
1084 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1088 bool Actor::IsOrientationInherited() const
1090 return mInheritOrientation;
1093 void Actor::SetSizeModeFactor( const Vector3& factor )
1095 EnsureRelayoutData();
1097 mRelayoutData->sizeModeFactor = factor;
1100 const Vector3& Actor::GetSizeModeFactor() const
1102 if ( mRelayoutData )
1104 return mRelayoutData->sizeModeFactor;
1107 return GetDefaultSizeModeFactor();
1110 void Actor::SetColorMode( ColorMode colorMode )
1112 // non animateable so keep local copy
1113 mColorMode = colorMode;
1116 // mNode is being used in a separate thread; queue a message to set the value
1117 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1121 ColorMode Actor::GetColorMode() const
1123 // we have cached copy
1127 void Actor::SetSize( float width, float height )
1129 SetSize( Vector2( width, height ) );
1132 void Actor::SetSize( float width, float height, float depth )
1134 SetSize( Vector3( width, height, depth ) );
1137 void Actor::SetSize( const Vector2& size )
1139 SetSize( Vector3( size.width, size.height, 0.f ) );
1142 void Actor::SetSizeInternal( const Vector2& size )
1144 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1147 void Actor::SetSize( const Vector3& size )
1149 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1151 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1152 SetPreferredSize( size.GetVectorXY() );
1156 SetSizeInternal( size );
1160 void Actor::SetSizeInternal( const Vector3& size )
1162 // dont allow recursive loop
1163 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1164 // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
1165 if( ( NULL != mNode )&&
1166 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1167 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1168 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1172 // mNode is being used in a separate thread; queue a message to set the value & base value
1173 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1175 // Notification for derived classes
1176 mInsideOnSizeSet = true;
1177 OnSizeSet( mTargetSize );
1178 mInsideOnSizeSet = false;
1180 // Raise a relayout request if the flag is not locked
1181 if( mRelayoutData && !mRelayoutData->insideRelayout )
1188 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1190 mTargetSize = targetSize;
1192 // Notify deriving classes
1193 OnSizeAnimation( animation, mTargetSize );
1196 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1198 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1200 mTargetSize.width = targetSize;
1202 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1204 mTargetSize.height = targetSize;
1206 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1208 mTargetSize.depth = targetSize;
1210 // Notify deriving classes
1211 OnSizeAnimation( animation, mTargetSize );
1214 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1216 mTargetPosition = targetPosition;
1219 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1221 if ( Dali::Actor::Property::POSITION_X == property )
1223 mTargetPosition.x = targetPosition;
1225 else if ( Dali::Actor::Property::POSITION_Y == property )
1227 mTargetPosition.y = targetPosition;
1229 else if ( Dali::Actor::Property::POSITION_Z == property )
1231 mTargetPosition.z = targetPosition;
1235 void Actor::SetWidth( float width )
1237 mTargetSize.width = width;
1241 // mNode is being used in a separate thread; queue a message to set the value & base value
1242 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1246 void Actor::SetHeight( float height )
1248 mTargetSize.height = height;
1252 // mNode is being used in a separate thread; queue a message to set the value & base value
1253 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1257 void Actor::SetDepth( float depth )
1259 mTargetSize.depth = depth;
1263 // mNode is being used in a separate thread; queue a message to set the value & base value
1264 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1268 const Vector3& Actor::GetTargetSize() const
1273 const Vector3& Actor::GetCurrentSize() const
1277 // mNode is being used in a separate thread; copy the value from the previous update
1278 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1281 return Vector3::ZERO;
1284 Vector3 Actor::GetNaturalSize() const
1286 // It is up to deriving classes to return the appropriate natural size
1287 return Vector3( 0.0f, 0.0f, 0.0f );
1290 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1292 EnsureRelayoutData();
1294 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1296 if( dimension & ( 1 << i ) )
1298 mRelayoutData->resizePolicies[ i ] = policy;
1302 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1304 if( dimension & Dimension::WIDTH )
1306 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1309 if( dimension & Dimension::HEIGHT )
1311 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1315 // If calling SetResizePolicy, assume we want relayout enabled
1316 SetRelayoutEnabled( true );
1318 OnSetResizePolicy( policy, dimension );
1320 // Trigger relayout on this control
1324 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1326 if ( mRelayoutData )
1328 // If more than one dimension is requested, just return the first one found
1329 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1331 if( ( dimension & ( 1 << i ) ) )
1333 return mRelayoutData->resizePolicies[ i ];
1338 return ResizePolicy::DEFAULT;
1341 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1343 EnsureRelayoutData();
1345 mRelayoutData->sizeSetPolicy = policy;
1348 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1350 if ( mRelayoutData )
1352 return mRelayoutData->sizeSetPolicy;
1355 return DEFAULT_SIZE_SCALE_POLICY;
1358 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1360 EnsureRelayoutData();
1362 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1364 if( dimension & ( 1 << i ) )
1366 mRelayoutData->dimensionDependencies[ i ] = dependency;
1371 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1373 if ( mRelayoutData )
1375 // If more than one dimension is requested, just return the first one found
1376 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1378 if( ( dimension & ( 1 << i ) ) )
1380 return mRelayoutData->dimensionDependencies[ i ];
1385 return Dimension::ALL_DIMENSIONS; // Default
1388 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1390 // If relayout data has not been allocated yet and the client is requesting
1391 // to disable it, do nothing
1392 if( mRelayoutData || relayoutEnabled )
1394 EnsureRelayoutData();
1396 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1398 mRelayoutData->relayoutEnabled = relayoutEnabled;
1402 bool Actor::IsRelayoutEnabled() const
1404 // Assume that if relayout data has not been allocated yet then
1405 // relayout is disabled
1406 return mRelayoutData && mRelayoutData->relayoutEnabled;
1409 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1411 EnsureRelayoutData();
1413 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1415 if( dimension & ( 1 << i ) )
1417 mRelayoutData->dimensionDirty[ i ] = dirty;
1422 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1424 if ( mRelayoutData )
1426 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1428 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1438 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1440 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1443 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1445 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1448 unsigned int Actor::AddRenderer( Renderer& renderer )
1452 mRenderers = new RendererContainer;
1455 unsigned int index = mRenderers->size();
1456 RendererPtr rendererPtr = RendererPtr( &renderer );
1457 mRenderers->push_back( rendererPtr );
1458 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1462 unsigned int Actor::GetRendererCount() const
1464 unsigned int rendererCount(0);
1467 rendererCount = mRenderers->size();
1470 return rendererCount;
1473 RendererPtr Actor::GetRendererAt( unsigned int index )
1475 RendererPtr renderer;
1476 if( index < GetRendererCount() )
1478 renderer = ( *mRenderers )[ index ];
1484 void Actor::RemoveRenderer( Renderer& renderer )
1488 RendererIter end = mRenderers->end();
1489 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1491 if( (*iter).Get() == &renderer )
1493 mRenderers->erase( iter );
1494 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1501 void Actor::RemoveRenderer( unsigned int index )
1503 if( index < GetRendererCount() )
1505 RendererPtr renderer = ( *mRenderers )[ index ];
1506 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1507 mRenderers->erase( mRenderers->begin()+index );
1511 bool Actor::IsOverlay() const
1513 return ( DrawMode::OVERLAY_2D == mDrawMode );
1516 void Actor::SetDrawMode( DrawMode::Type drawMode )
1518 // this flag is not animatable so keep the value
1519 mDrawMode = drawMode;
1520 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1522 // mNode is being used in a separate thread; queue a message to set the value
1523 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1527 DrawMode::Type Actor::GetDrawMode() const
1532 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1534 // only valid when on-stage
1535 StagePtr stage = Stage::GetCurrent();
1536 if( stage && OnStage() )
1538 const RenderTaskList& taskList = stage->GetRenderTaskList();
1540 Vector2 converted( screenX, screenY );
1542 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1543 const int taskCount = taskList.GetTaskCount();
1544 for( int i = taskCount - 1; i >= 0; --i )
1546 Dali::RenderTask task = taskList.GetTask( i );
1547 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1549 // found a task where this conversion was ok so return
1557 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1559 bool retval = false;
1560 // only valid when on-stage
1563 CameraActor* camera = renderTask.GetCameraActor();
1567 renderTask.GetViewport( viewport );
1569 // need to translate coordinates to render tasks coordinate space
1570 Vector2 converted( screenX, screenY );
1571 if( renderTask.TranslateCoordinates( converted ) )
1573 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1580 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1582 // Early-out if mNode is NULL
1588 // Get the ModelView matrix
1590 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1592 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1593 Matrix invertedMvp( false/*don't init*/);
1594 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1595 bool success = invertedMvp.Invert();
1597 // Convert to GL coordinates
1598 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1603 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1610 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1616 if( XyPlaneIntersect( nearPos, farPos, local ) )
1618 Vector3 size = GetCurrentSize();
1619 localX = local.x + size.x * 0.5f;
1620 localY = local.y + size.y * 0.5f;
1631 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1634 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1636 Mathematical Formulation
1638 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1640 ( p - c ) dot ( p - c ) = r^2
1642 Given a ray with a point of origin 'o', and a direction vector 'd':
1644 ray(t) = o + td, t >= 0
1646 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1648 (o + td - c ) dot ( o + td - c ) = r^2
1650 To solve for t we first expand the above into a more recognisable quadratic equation form
1652 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1661 B = 2( o - c ) dot d
1662 C = ( o - c ) dot ( o - c ) - r^2
1664 which can be solved using a standard quadratic formula.
1666 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1668 Practical Simplification
1670 In a renderer, we often differentiate between world space and object space. In the object space
1671 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1672 into object space, the mathematical solution presented above can be simplified significantly.
1674 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1678 and we can find the t at which the (transformed) ray intersects the sphere by
1680 ( o + td ) dot ( o + td ) = r^2
1682 According to the reasoning above, we expand the above quadratic equation into the general form
1686 which now has coefficients:
1693 // Early out if mNode is NULL
1699 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1701 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1702 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1703 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1705 // Compute the radius is not needed, square radius it's enough.
1706 const Vector3& size( mNode->GetSize( bufferIndex ) );
1708 // Scale the sphere.
1709 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1711 const float width = size.width * scale.width;
1712 const float height = size.height * scale.height;
1714 float squareSphereRadius = 0.5f * ( width * width + height * height );
1716 float a = rayDir.Dot( rayDir ); // a
1717 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1718 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1720 return ( b2 * b2 - a * c ) >= 0.f;
1723 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1727 if( OnStage() && NULL != mNode )
1729 // Transforms the ray to the local reference system.
1730 // Calculate the inverse of Model matrix
1731 Matrix invModelMatrix( false/*don't init*/);
1733 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1734 invModelMatrix = mNode->GetWorldMatrix(0);
1735 invModelMatrix.Invert();
1737 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1738 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1740 // Test with the actor's XY plane (Normal = 0 0 1 1).
1742 float a = -rayOriginLocal.z;
1743 float b = rayDirLocal.z;
1745 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1747 // Ray travels distance * rayDirLocal to intersect with plane.
1750 const Vector3& size = mNode->GetSize( bufferIndex );
1752 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1753 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1755 // Test with the actor's geometry.
1756 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1763 void Actor::SetLeaveRequired( bool required )
1765 mLeaveRequired = required;
1768 bool Actor::GetLeaveRequired() const
1770 return mLeaveRequired;
1773 void Actor::SetKeyboardFocusable( bool focusable )
1775 mKeyboardFocusable = focusable;
1778 bool Actor::IsKeyboardFocusable() const
1780 return mKeyboardFocusable;
1783 bool Actor::GetTouchRequired() const
1785 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1788 bool Actor::GetHoverRequired() const
1790 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1793 bool Actor::GetWheelEventRequired() const
1795 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1798 bool Actor::IsHittable() const
1800 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1803 ActorGestureData& Actor::GetGestureData()
1805 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1806 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1807 if( NULL == mGestureData )
1809 mGestureData = new ActorGestureData;
1811 return *mGestureData;
1814 bool Actor::IsGestureRequred( Gesture::Type type ) const
1816 return mGestureData && mGestureData->IsGestureRequred( type );
1819 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1821 bool consumed = false;
1823 if( !mTouchSignal.Empty() )
1825 Dali::Actor handle( this );
1826 consumed = mTouchSignal.Emit( handle, touch );
1829 if( !mTouchedSignal.Empty() )
1831 Dali::Actor handle( this );
1832 consumed |= mTouchedSignal.Emit( handle, event );
1837 // Notification for derived classes
1838 consumed = OnTouchEvent( event ); // TODO
1844 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1846 bool consumed = false;
1848 if( !mHoveredSignal.Empty() )
1850 Dali::Actor handle( this );
1851 consumed = mHoveredSignal.Emit( handle, event );
1856 // Notification for derived classes
1857 consumed = OnHoverEvent( event );
1863 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1865 bool consumed = false;
1867 if( !mWheelEventSignal.Empty() )
1869 Dali::Actor handle( this );
1870 consumed = mWheelEventSignal.Emit( handle, event );
1875 // Notification for derived classes
1876 consumed = OnWheelEvent( event );
1882 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1884 return mTouchedSignal;
1887 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1889 return mTouchSignal;
1892 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1894 return mHoveredSignal;
1897 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1899 return mWheelEventSignal;
1902 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1904 return mOnStageSignal;
1907 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1909 return mOffStageSignal;
1912 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1914 return mOnRelayoutSignal;
1917 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1919 bool connected( true );
1920 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1922 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1924 actor->TouchedSignal().Connect( tracker, functor );
1926 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1928 actor->HoveredSignal().Connect( tracker, functor );
1930 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1932 actor->WheelEventSignal().Connect( tracker, functor );
1934 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1936 actor->OnStageSignal().Connect( tracker, functor );
1938 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1940 actor->OffStageSignal().Connect( tracker, functor );
1942 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1944 actor->OnRelayoutSignal().Connect( tracker, functor );
1946 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1948 actor->TouchSignal().Connect( tracker, functor );
1952 // signalName does not match any signal
1959 Actor::Actor( DerivedType derivedType )
1964 mParentOrigin( NULL ),
1965 mAnchorPoint( NULL ),
1966 mRelayoutData( NULL ),
1967 mGestureData( NULL ),
1968 mTargetSize( 0.0f, 0.0f, 0.0f ),
1970 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1973 mIsRoot( ROOT_LAYER == derivedType ),
1974 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1975 mIsOnStage( false ),
1977 mLeaveRequired( false ),
1978 mKeyboardFocusable( false ),
1979 mDerivedRequiresTouch( false ),
1980 mDerivedRequiresHover( false ),
1981 mDerivedRequiresWheelEvent( false ),
1982 mOnStageSignalled( false ),
1983 mInsideOnSizeSet( false ),
1984 mInheritPosition( true ),
1985 mInheritOrientation( true ),
1986 mInheritScale( true ),
1987 mDrawMode( DrawMode::NORMAL ),
1988 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1989 mColorMode( Node::DEFAULT_COLOR_MODE ),
1990 mClippingMode( ClippingMode::DISABLED ),
1991 mIsBatchParent( false )
1995 void Actor::Initialize()
1998 SceneGraph::Node* node = CreateNode();
2000 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2001 mNode = node; // Keep raw-pointer to Node
2005 GetEventThreadServices().RegisterObject( this );
2010 // Remove mParent pointers from children even if we're destroying core,
2011 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2014 ActorConstIter endIter = mChildren->end();
2015 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2017 (*iter)->SetParent( NULL );
2023 // Guard to allow handle destruction after Core has been destroyed
2024 if( EventThreadServices::IsCoreRunning() )
2028 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2029 mNode = NULL; // Node is about to be destroyed
2032 GetEventThreadServices().UnregisterObject( this );
2035 // Cleanup optional gesture data
2036 delete mGestureData;
2038 // Cleanup optional parent origin and anchor
2039 delete mParentOrigin;
2040 delete mAnchorPoint;
2042 // Delete optional relayout data
2045 delete mRelayoutData;
2049 void Actor::ConnectToStage( unsigned int parentDepth )
2051 // This container is used instead of walking the Actor hierarchy.
2052 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2053 ActorContainer connectionList;
2055 // This stage is atomic i.e. not interrupted by user callbacks.
2056 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2058 // Notify applications about the newly connected actors.
2059 const ActorIter endIter = connectionList.end();
2060 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2062 (*iter)->NotifyStageConnection();
2068 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2070 DALI_ASSERT_ALWAYS( !OnStage() );
2074 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2076 ConnectToSceneGraph();
2078 // Notification for internal derived classes
2079 OnStageConnectionInternal();
2081 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2082 connectionList.push_back( ActorPtr( this ) );
2084 // Recursively connect children
2087 ActorConstIter endIter = mChildren->end();
2088 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2090 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2096 * This method is called when the Actor is connected to the Stage.
2097 * The parent must have added its Node to the scene-graph.
2098 * The child must connect its Node to the parent's Node.
2099 * This is recursive; the child calls ConnectToStage() for its children.
2101 void Actor::ConnectToSceneGraph()
2103 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2107 // Reparent Node in next Update
2108 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2111 // Request relayout on all actors that are added to the scenegraph
2114 // Notification for Object::Observers
2118 void Actor::NotifyStageConnection()
2120 // Actors can be removed (in a callback), before the on-stage stage is reported.
2121 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2122 if( OnStage() && !mOnStageSignalled )
2124 // Notification for external (CustomActor) derived classes
2125 OnStageConnectionExternal( mDepth );
2127 if( !mOnStageSignal.Empty() )
2129 Dali::Actor handle( this );
2130 mOnStageSignal.Emit( handle );
2133 // Guard against Remove during callbacks
2136 mOnStageSignalled = true; // signal required next time Actor is removed
2141 void Actor::DisconnectFromStage()
2143 // This container is used instead of walking the Actor hierachy.
2144 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2145 ActorContainer disconnectionList;
2147 // This stage is atomic i.e. not interrupted by user callbacks
2148 RecursiveDisconnectFromStage( disconnectionList );
2150 // Notify applications about the newly disconnected actors.
2151 const ActorIter endIter = disconnectionList.end();
2152 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2154 (*iter)->NotifyStageDisconnection();
2158 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2160 DALI_ASSERT_ALWAYS( OnStage() );
2162 // Recursively disconnect children
2165 ActorConstIter endIter = mChildren->end();
2166 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2168 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2172 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2173 disconnectionList.push_back( ActorPtr( this ) );
2175 // Notification for internal derived classes
2176 OnStageDisconnectionInternal();
2178 DisconnectFromSceneGraph();
2184 * This method is called by an actor or its parent, before a node removal message is sent.
2185 * This is recursive; the child calls DisconnectFromStage() for its children.
2187 void Actor::DisconnectFromSceneGraph()
2189 // Notification for Object::Observers
2190 OnSceneObjectRemove();
2193 void Actor::NotifyStageDisconnection()
2195 // Actors can be added (in a callback), before the off-stage state is reported.
2196 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2197 // only do this step if there is a stage, i.e. Core is not being shut down
2198 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2200 // Notification for external (CustomeActor) derived classes
2201 OnStageDisconnectionExternal();
2203 if( !mOffStageSignal.Empty() )
2205 Dali::Actor handle( this );
2206 mOffStageSignal.Emit( handle );
2209 // Guard against Add during callbacks
2212 mOnStageSignalled = false; // signal required next time Actor is added
2217 bool Actor::IsNodeConnected() const
2219 bool connected( false );
2221 if( OnStage() && ( NULL != mNode ) )
2223 if( IsRoot() || mNode->GetParent() )
2232 unsigned int Actor::GetDefaultPropertyCount() const
2234 return DEFAULT_PROPERTY_COUNT;
2237 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2239 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2241 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2243 indices.PushBack( i );
2247 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2249 if( index < DEFAULT_PROPERTY_COUNT )
2251 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2257 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2259 Property::Index index = Property::INVALID_INDEX;
2261 // Look for name in default properties
2262 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2264 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2265 if( 0 == name.compare( property->name ) )
2275 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2277 if( index < DEFAULT_PROPERTY_COUNT )
2279 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2285 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2287 if( index < DEFAULT_PROPERTY_COUNT )
2289 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2295 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2297 if( index < DEFAULT_PROPERTY_COUNT )
2299 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2305 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2307 if( index < DEFAULT_PROPERTY_COUNT )
2309 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2312 // index out of range...return Property::NONE
2313 return Property::NONE;
2316 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2320 case Dali::Actor::Property::PARENT_ORIGIN:
2322 Property::Type type = property.GetType();
2323 if( type == Property::VECTOR3 )
2325 SetParentOrigin( property.Get< Vector3 >() );
2327 else if ( type == Property::STRING )
2329 std::string parentOriginString;
2330 property.Get( parentOriginString );
2331 Vector3 parentOrigin;
2332 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2334 SetParentOrigin( parentOrigin );
2340 case Dali::Actor::Property::PARENT_ORIGIN_X:
2342 SetParentOriginX( property.Get< float >() );
2346 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2348 SetParentOriginY( property.Get< float >() );
2352 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2354 SetParentOriginZ( property.Get< float >() );
2358 case Dali::Actor::Property::ANCHOR_POINT:
2360 Property::Type type = property.GetType();
2361 if( type == Property::VECTOR3 )
2363 SetAnchorPoint( property.Get< Vector3 >() );
2365 else if ( type == Property::STRING )
2367 std::string anchorPointString;
2368 property.Get( anchorPointString );
2370 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2372 SetAnchorPoint( anchor );
2378 case Dali::Actor::Property::ANCHOR_POINT_X:
2380 SetAnchorPointX( property.Get< float >() );
2384 case Dali::Actor::Property::ANCHOR_POINT_Y:
2386 SetAnchorPointY( property.Get< float >() );
2390 case Dali::Actor::Property::ANCHOR_POINT_Z:
2392 SetAnchorPointZ( property.Get< float >() );
2396 case Dali::Actor::Property::SIZE:
2398 SetSize( property.Get< Vector3 >() );
2402 case Dali::Actor::Property::SIZE_WIDTH:
2404 SetWidth( property.Get< float >() );
2408 case Dali::Actor::Property::SIZE_HEIGHT:
2410 SetHeight( property.Get< float >() );
2414 case Dali::Actor::Property::SIZE_DEPTH:
2416 SetDepth( property.Get< float >() );
2420 case Dali::Actor::Property::POSITION:
2422 SetPosition( property.Get< Vector3 >() );
2426 case Dali::Actor::Property::POSITION_X:
2428 SetX( property.Get< float >() );
2432 case Dali::Actor::Property::POSITION_Y:
2434 SetY( property.Get< float >() );
2438 case Dali::Actor::Property::POSITION_Z:
2440 SetZ( property.Get< float >() );
2444 case Dali::Actor::Property::ORIENTATION:
2446 SetOrientation( property.Get< Quaternion >() );
2450 case Dali::Actor::Property::SCALE:
2452 SetScale( property.Get< Vector3 >() );
2456 case Dali::Actor::Property::SCALE_X:
2458 SetScaleX( property.Get< float >() );
2462 case Dali::Actor::Property::SCALE_Y:
2464 SetScaleY( property.Get< float >() );
2468 case Dali::Actor::Property::SCALE_Z:
2470 SetScaleZ( property.Get< float >() );
2474 case Dali::Actor::Property::VISIBLE:
2476 SetVisible( property.Get< bool >() );
2480 case Dali::Actor::Property::COLOR:
2482 SetColor( property.Get< Vector4 >() );
2486 case Dali::Actor::Property::COLOR_RED:
2488 SetColorRed( property.Get< float >() );
2492 case Dali::Actor::Property::COLOR_GREEN:
2494 SetColorGreen( property.Get< float >() );
2498 case Dali::Actor::Property::COLOR_BLUE:
2500 SetColorBlue( property.Get< float >() );
2504 case Dali::Actor::Property::COLOR_ALPHA:
2506 SetOpacity( property.Get< float >() );
2510 case Dali::Actor::Property::NAME:
2512 SetName( property.Get< std::string >() );
2516 case Dali::Actor::Property::SENSITIVE:
2518 SetSensitive( property.Get< bool >() );
2522 case Dali::Actor::Property::LEAVE_REQUIRED:
2524 SetLeaveRequired( property.Get< bool >() );
2528 case Dali::Actor::Property::INHERIT_POSITION:
2530 SetInheritPosition( property.Get< bool >() );
2534 case Dali::Actor::Property::INHERIT_ORIENTATION:
2536 SetInheritOrientation( property.Get< bool >() );
2540 case Dali::Actor::Property::INHERIT_SCALE:
2542 SetInheritScale( property.Get< bool >() );
2546 case Dali::Actor::Property::COLOR_MODE:
2548 ColorMode mode = mColorMode;
2549 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2551 SetColorMode( mode );
2556 case Dali::Actor::Property::POSITION_INHERITANCE:
2558 PositionInheritanceMode mode = mPositionInheritanceMode;
2559 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2561 SetPositionInheritanceMode( mode );
2566 case Dali::Actor::Property::DRAW_MODE:
2568 DrawMode::Type mode = mDrawMode;
2569 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2571 SetDrawMode( mode );
2576 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2578 SetSizeModeFactor( property.Get< Vector3 >() );
2582 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2584 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2585 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2587 SetResizePolicy( type, Dimension::WIDTH );
2592 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2594 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2595 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2597 SetResizePolicy( type, Dimension::HEIGHT );
2602 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2604 SizeScalePolicy::Type type;
2605 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2607 SetSizeScalePolicy( type );
2612 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2614 if( property.Get< bool >() )
2616 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2621 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2623 if( property.Get< bool >() )
2625 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2630 case Dali::Actor::Property::PADDING:
2632 Vector4 padding = property.Get< Vector4 >();
2633 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2634 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2638 case Dali::Actor::Property::MINIMUM_SIZE:
2640 Vector2 size = property.Get< Vector2 >();
2641 SetMinimumSize( size.x, Dimension::WIDTH );
2642 SetMinimumSize( size.y, Dimension::HEIGHT );
2646 case Dali::Actor::Property::MAXIMUM_SIZE:
2648 Vector2 size = property.Get< Vector2 >();
2649 SetMaximumSize( size.x, Dimension::WIDTH );
2650 SetMaximumSize( size.y, Dimension::HEIGHT );
2654 case Dali::DevelActor::Property::BATCH_PARENT:
2658 if( property.Get( value ) )
2660 if( value != mIsBatchParent )
2662 mIsBatchParent = value;
2663 SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2669 case Dali::DevelActor::Property::SIBLING_ORDER:
2673 if( property.Get( value ) )
2675 if( static_cast<unsigned int>(value) != mSiblingOrder )
2677 mSiblingOrder = value;
2680 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2687 case Dali::Actor::Property::CLIPPING_MODE:
2689 ClippingMode::Type convertedValue = mClippingMode;
2690 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2692 mClippingMode = convertedValue;
2695 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2703 // this can happen in the case of a non-animatable default property so just do nothing
2709 // TODO: This method needs to be removed
2710 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2712 switch( entry.GetType() )
2714 case Property::BOOLEAN:
2716 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2717 DALI_ASSERT_DEBUG( NULL != property );
2719 // property is being used in a separate thread; queue a message to set the property
2720 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2725 case Property::INTEGER:
2727 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2728 DALI_ASSERT_DEBUG( NULL != property );
2730 // property is being used in a separate thread; queue a message to set the property
2731 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2736 case Property::FLOAT:
2738 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2739 DALI_ASSERT_DEBUG( NULL != property );
2741 // property is being used in a separate thread; queue a message to set the property
2742 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2747 case Property::VECTOR2:
2749 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2750 DALI_ASSERT_DEBUG( NULL != property );
2752 // property is being used in a separate thread; queue a message to set the property
2753 if(entry.componentIndex == 0)
2755 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2757 else if(entry.componentIndex == 1)
2759 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2763 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2769 case Property::VECTOR3:
2771 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2772 DALI_ASSERT_DEBUG( NULL != property );
2774 // property is being used in a separate thread; queue a message to set the property
2775 if(entry.componentIndex == 0)
2777 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2779 else if(entry.componentIndex == 1)
2781 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2783 else if(entry.componentIndex == 2)
2785 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2789 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2795 case Property::VECTOR4:
2797 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2798 DALI_ASSERT_DEBUG( NULL != property );
2800 // property is being used in a separate thread; queue a message to set the property
2801 if(entry.componentIndex == 0)
2803 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2805 else if(entry.componentIndex == 1)
2807 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2809 else if(entry.componentIndex == 2)
2811 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2813 else if(entry.componentIndex == 3)
2815 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2819 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2825 case Property::ROTATION:
2827 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2828 DALI_ASSERT_DEBUG( NULL != property );
2830 // property is being used in a separate thread; queue a message to set the property
2831 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2836 case Property::MATRIX:
2838 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2839 DALI_ASSERT_DEBUG( NULL != property );
2841 // property is being used in a separate thread; queue a message to set the property
2842 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2847 case Property::MATRIX3:
2849 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2850 DALI_ASSERT_DEBUG( NULL != property );
2852 // property is being used in a separate thread; queue a message to set the property
2853 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2860 // nothing to do for other types
2865 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2867 Property::Value value;
2869 if( index >= DEFAULT_PROPERTY_COUNT )
2876 case Dali::Actor::Property::PARENT_ORIGIN:
2878 value = GetCurrentParentOrigin();
2882 case Dali::Actor::Property::PARENT_ORIGIN_X:
2884 value = GetCurrentParentOrigin().x;
2888 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2890 value = GetCurrentParentOrigin().y;
2894 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2896 value = GetCurrentParentOrigin().z;
2900 case Dali::Actor::Property::ANCHOR_POINT:
2902 value = GetCurrentAnchorPoint();
2906 case Dali::Actor::Property::ANCHOR_POINT_X:
2908 value = GetCurrentAnchorPoint().x;
2912 case Dali::Actor::Property::ANCHOR_POINT_Y:
2914 value = GetCurrentAnchorPoint().y;
2918 case Dali::Actor::Property::ANCHOR_POINT_Z:
2920 value = GetCurrentAnchorPoint().z;
2924 case Dali::Actor::Property::SIZE:
2926 value = GetTargetSize();
2930 case Dali::Actor::Property::SIZE_WIDTH:
2932 value = GetTargetSize().width;
2936 case Dali::Actor::Property::SIZE_HEIGHT:
2938 value = GetTargetSize().height;
2942 case Dali::Actor::Property::SIZE_DEPTH:
2944 value = GetTargetSize().depth;
2948 case Dali::Actor::Property::POSITION:
2950 value = GetTargetPosition();
2954 case Dali::Actor::Property::POSITION_X:
2956 value = GetTargetPosition().x;
2960 case Dali::Actor::Property::POSITION_Y:
2962 value = GetTargetPosition().y;
2966 case Dali::Actor::Property::POSITION_Z:
2968 value = GetTargetPosition().z;
2972 case Dali::Actor::Property::WORLD_POSITION:
2974 value = GetCurrentWorldPosition();
2978 case Dali::Actor::Property::WORLD_POSITION_X:
2980 value = GetCurrentWorldPosition().x;
2984 case Dali::Actor::Property::WORLD_POSITION_Y:
2986 value = GetCurrentWorldPosition().y;
2990 case Dali::Actor::Property::WORLD_POSITION_Z:
2992 value = GetCurrentWorldPosition().z;
2996 case Dali::Actor::Property::ORIENTATION:
2998 value = GetCurrentOrientation();
3002 case Dali::Actor::Property::WORLD_ORIENTATION:
3004 value = GetCurrentWorldOrientation();
3008 case Dali::Actor::Property::SCALE:
3010 value = GetCurrentScale();
3014 case Dali::Actor::Property::SCALE_X:
3016 value = GetCurrentScale().x;
3020 case Dali::Actor::Property::SCALE_Y:
3022 value = GetCurrentScale().y;
3026 case Dali::Actor::Property::SCALE_Z:
3028 value = GetCurrentScale().z;
3032 case Dali::Actor::Property::WORLD_SCALE:
3034 value = GetCurrentWorldScale();
3038 case Dali::Actor::Property::VISIBLE:
3040 value = IsVisible();
3044 case Dali::Actor::Property::COLOR:
3046 value = GetCurrentColor();
3050 case Dali::Actor::Property::COLOR_RED:
3052 value = GetCurrentColor().r;
3056 case Dali::Actor::Property::COLOR_GREEN:
3058 value = GetCurrentColor().g;
3062 case Dali::Actor::Property::COLOR_BLUE:
3064 value = GetCurrentColor().b;
3068 case Dali::Actor::Property::COLOR_ALPHA:
3070 value = GetCurrentColor().a;
3074 case Dali::Actor::Property::WORLD_COLOR:
3076 value = GetCurrentWorldColor();
3080 case Dali::Actor::Property::WORLD_MATRIX:
3082 value = GetCurrentWorldMatrix();
3086 case Dali::Actor::Property::NAME:
3092 case Dali::Actor::Property::SENSITIVE:
3094 value = IsSensitive();
3098 case Dali::Actor::Property::LEAVE_REQUIRED:
3100 value = GetLeaveRequired();
3104 case Dali::Actor::Property::INHERIT_POSITION:
3106 value = IsPositionInherited();
3110 case Dali::Actor::Property::INHERIT_ORIENTATION:
3112 value = IsOrientationInherited();
3116 case Dali::Actor::Property::INHERIT_SCALE:
3118 value = IsScaleInherited();
3122 case Dali::Actor::Property::COLOR_MODE:
3124 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3128 case Dali::Actor::Property::POSITION_INHERITANCE:
3130 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3134 case Dali::Actor::Property::DRAW_MODE:
3136 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3140 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3142 value = GetSizeModeFactor();
3146 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3148 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3152 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3154 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3158 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3160 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3164 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3166 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3170 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3172 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3176 case Dali::Actor::Property::PADDING:
3178 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3179 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3180 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3184 case Dali::Actor::Property::MINIMUM_SIZE:
3186 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3190 case Dali::Actor::Property::MAXIMUM_SIZE:
3192 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3196 case Dali::DevelActor::Property::BATCH_PARENT:
3198 value = mIsBatchParent;
3202 case Dali::DevelActor::Property::SIBLING_ORDER:
3204 value = static_cast<int>(mSiblingOrder);
3208 case Dali::Actor::Property::CLIPPING_MODE:
3210 value = mClippingMode;
3218 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3223 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3225 // This method should only return an object connected to the scene-graph
3226 return OnStage() ? mNode : NULL;
3229 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3231 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3233 const PropertyBase* property( NULL );
3235 // This method should only return a property of an object connected to the scene-graph
3241 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3243 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3244 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3246 property = animatable->GetSceneGraphProperty();
3248 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3249 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3251 CustomPropertyMetadata* custom = FindCustomProperty( index );
3252 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3254 property = custom->GetSceneGraphProperty();
3256 else if( NULL != mNode )
3260 case Dali::Actor::Property::SIZE:
3261 property = &mNode->mSize;
3264 case Dali::Actor::Property::SIZE_WIDTH:
3265 property = &mNode->mSize;
3268 case Dali::Actor::Property::SIZE_HEIGHT:
3269 property = &mNode->mSize;
3272 case Dali::Actor::Property::SIZE_DEPTH:
3273 property = &mNode->mSize;
3276 case Dali::Actor::Property::POSITION:
3277 property = &mNode->mPosition;
3280 case Dali::Actor::Property::POSITION_X:
3281 property = &mNode->mPosition;
3284 case Dali::Actor::Property::POSITION_Y:
3285 property = &mNode->mPosition;
3288 case Dali::Actor::Property::POSITION_Z:
3289 property = &mNode->mPosition;
3292 case Dali::Actor::Property::ORIENTATION:
3293 property = &mNode->mOrientation;
3296 case Dali::Actor::Property::SCALE:
3297 property = &mNode->mScale;
3300 case Dali::Actor::Property::SCALE_X:
3301 property = &mNode->mScale;
3304 case Dali::Actor::Property::SCALE_Y:
3305 property = &mNode->mScale;
3308 case Dali::Actor::Property::SCALE_Z:
3309 property = &mNode->mScale;
3312 case Dali::Actor::Property::VISIBLE:
3313 property = &mNode->mVisible;
3316 case Dali::Actor::Property::COLOR:
3317 property = &mNode->mColor;
3320 case Dali::Actor::Property::COLOR_RED:
3321 property = &mNode->mColor;
3324 case Dali::Actor::Property::COLOR_GREEN:
3325 property = &mNode->mColor;
3328 case Dali::Actor::Property::COLOR_BLUE:
3329 property = &mNode->mColor;
3332 case Dali::Actor::Property::COLOR_ALPHA:
3333 property = &mNode->mColor;
3344 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3346 const PropertyInputImpl* property( NULL );
3348 // This method should only return a property of an object connected to the scene-graph
3354 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3356 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3357 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3359 property = animatable->GetSceneGraphProperty();
3361 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3362 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3364 CustomPropertyMetadata* custom = FindCustomProperty( index );
3365 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3366 property = custom->GetSceneGraphProperty();
3368 else if( NULL != mNode )
3372 case Dali::Actor::Property::PARENT_ORIGIN:
3373 property = &mNode->mParentOrigin;
3376 case Dali::Actor::Property::PARENT_ORIGIN_X:
3377 property = &mNode->mParentOrigin;
3380 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3381 property = &mNode->mParentOrigin;
3384 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3385 property = &mNode->mParentOrigin;
3388 case Dali::Actor::Property::ANCHOR_POINT:
3389 property = &mNode->mAnchorPoint;
3392 case Dali::Actor::Property::ANCHOR_POINT_X:
3393 property = &mNode->mAnchorPoint;
3396 case Dali::Actor::Property::ANCHOR_POINT_Y:
3397 property = &mNode->mAnchorPoint;
3400 case Dali::Actor::Property::ANCHOR_POINT_Z:
3401 property = &mNode->mAnchorPoint;
3404 case Dali::Actor::Property::SIZE:
3405 property = &mNode->mSize;
3408 case Dali::Actor::Property::SIZE_WIDTH:
3409 property = &mNode->mSize;
3412 case Dali::Actor::Property::SIZE_HEIGHT:
3413 property = &mNode->mSize;
3416 case Dali::Actor::Property::SIZE_DEPTH:
3417 property = &mNode->mSize;
3420 case Dali::Actor::Property::POSITION:
3421 property = &mNode->mPosition;
3424 case Dali::Actor::Property::POSITION_X:
3425 property = &mNode->mPosition;
3428 case Dali::Actor::Property::POSITION_Y:
3429 property = &mNode->mPosition;
3432 case Dali::Actor::Property::POSITION_Z:
3433 property = &mNode->mPosition;
3436 case Dali::Actor::Property::WORLD_POSITION:
3437 property = &mNode->mWorldPosition;
3440 case Dali::Actor::Property::WORLD_POSITION_X:
3441 property = &mNode->mWorldPosition;
3444 case Dali::Actor::Property::WORLD_POSITION_Y:
3445 property = &mNode->mWorldPosition;
3448 case Dali::Actor::Property::WORLD_POSITION_Z:
3449 property = &mNode->mWorldPosition;
3452 case Dali::Actor::Property::ORIENTATION:
3453 property = &mNode->mOrientation;
3456 case Dali::Actor::Property::WORLD_ORIENTATION:
3457 property = &mNode->mWorldOrientation;
3460 case Dali::Actor::Property::SCALE:
3461 property = &mNode->mScale;
3464 case Dali::Actor::Property::SCALE_X:
3465 property = &mNode->mScale;
3468 case Dali::Actor::Property::SCALE_Y:
3469 property = &mNode->mScale;
3472 case Dali::Actor::Property::SCALE_Z:
3473 property = &mNode->mScale;
3476 case Dali::Actor::Property::WORLD_SCALE:
3477 property = &mNode->mWorldScale;
3480 case Dali::Actor::Property::VISIBLE:
3481 property = &mNode->mVisible;
3484 case Dali::Actor::Property::COLOR:
3485 property = &mNode->mColor;
3488 case Dali::Actor::Property::COLOR_RED:
3489 property = &mNode->mColor;
3492 case Dali::Actor::Property::COLOR_GREEN:
3493 property = &mNode->mColor;
3496 case Dali::Actor::Property::COLOR_BLUE:
3497 property = &mNode->mColor;
3500 case Dali::Actor::Property::COLOR_ALPHA:
3501 property = &mNode->mColor;
3504 case Dali::Actor::Property::WORLD_COLOR:
3505 property = &mNode->mWorldColor;
3508 case Dali::Actor::Property::WORLD_MATRIX:
3509 property = &mNode->mWorldMatrix;
3520 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3522 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3524 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3526 // check whether the animatable property is registered already, if not then register one.
3527 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3528 if( animatableProperty )
3530 componentIndex = animatableProperty->componentIndex;
3537 case Dali::Actor::Property::PARENT_ORIGIN_X:
3538 case Dali::Actor::Property::ANCHOR_POINT_X:
3539 case Dali::Actor::Property::SIZE_WIDTH:
3540 case Dali::Actor::Property::POSITION_X:
3541 case Dali::Actor::Property::WORLD_POSITION_X:
3542 case Dali::Actor::Property::SCALE_X:
3543 case Dali::Actor::Property::COLOR_RED:
3549 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3550 case Dali::Actor::Property::ANCHOR_POINT_Y:
3551 case Dali::Actor::Property::SIZE_HEIGHT:
3552 case Dali::Actor::Property::POSITION_Y:
3553 case Dali::Actor::Property::WORLD_POSITION_Y:
3554 case Dali::Actor::Property::SCALE_Y:
3555 case Dali::Actor::Property::COLOR_GREEN:
3561 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3562 case Dali::Actor::Property::ANCHOR_POINT_Z:
3563 case Dali::Actor::Property::SIZE_DEPTH:
3564 case Dali::Actor::Property::POSITION_Z:
3565 case Dali::Actor::Property::WORLD_POSITION_Z:
3566 case Dali::Actor::Property::SCALE_Z:
3567 case Dali::Actor::Property::COLOR_BLUE:
3573 case Dali::Actor::Property::COLOR_ALPHA:
3587 return componentIndex;
3590 void Actor::SetParent( Actor* parent )
3594 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3598 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3601 // Instruct each actor to create a corresponding node in the scene graph
3602 ConnectToStage( parent->GetHierarchyDepth() );
3605 // Resolve the name and index for the child properties if any
3606 ResolveChildProperties();
3608 else // parent being set to NULL
3610 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3614 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3617 DALI_ASSERT_ALWAYS( mNode != NULL );
3621 // Disconnect the Node & its children from the scene-graph.
3622 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3625 // Instruct each actor to discard pointers to the scene-graph
3626 DisconnectFromStage();
3631 SceneGraph::Node* Actor::CreateNode() const
3636 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3639 Actor* actor = dynamic_cast< Actor* >( object );
3643 if( 0 == actionName.compare( ACTION_SHOW ) )
3645 actor->SetVisible( true );
3648 else if( 0 == actionName.compare( ACTION_HIDE ) )
3650 actor->SetVisible( false );
3658 void Actor::EnsureRelayoutData()
3660 // Assign relayout data.
3661 if( !mRelayoutData )
3663 mRelayoutData = new RelayoutData();
3667 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3669 // Check if actor is dependent on parent
3670 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3672 if( ( dimension & ( 1 << i ) ) )
3674 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3675 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3685 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3687 // Check if actor is dependent on children
3688 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3690 if( ( dimension & ( 1 << i ) ) )
3692 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3693 switch( resizePolicy )
3695 case ResizePolicy::FIT_TO_CHILDREN:
3696 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3712 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3714 return Actor::RelayoutDependentOnChildren( dimension );
3717 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3719 // Check each possible dimension and see if it is dependent on the input one
3720 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3722 if( dimension & ( 1 << i ) )
3724 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3731 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3733 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3735 if( dimension & ( 1 << i ) )
3737 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3742 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3744 // If more than one dimension is requested, just return the first one found
3745 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3747 if( ( dimension & ( 1 << i ) ) )
3749 return mRelayoutData->negotiatedDimensions[ i ];
3753 return 0.0f; // Default
3756 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3758 EnsureRelayoutData();
3760 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3762 if( dimension & ( 1 << i ) )
3764 mRelayoutData->dimensionPadding[ i ] = padding;
3769 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3771 if ( mRelayoutData )
3773 // If more than one dimension is requested, just return the first one found
3774 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3776 if( ( dimension & ( 1 << i ) ) )
3778 return mRelayoutData->dimensionPadding[ i ];
3783 return GetDefaultDimensionPadding();
3786 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3788 EnsureRelayoutData();
3790 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3792 if( dimension & ( 1 << i ) )
3794 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3799 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3801 if ( mRelayoutData )
3803 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3805 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3815 float Actor::GetHeightForWidthBase( float width )
3817 float height = 0.0f;
3819 const Vector3 naturalSize = GetNaturalSize();
3820 if( naturalSize.width > 0.0f )
3822 height = naturalSize.height * width / naturalSize.width;
3824 else // we treat 0 as 1:1 aspect ratio
3832 float Actor::GetWidthForHeightBase( float height )
3836 const Vector3 naturalSize = GetNaturalSize();
3837 if( naturalSize.height > 0.0f )
3839 width = naturalSize.width * height / naturalSize.height;
3841 else // we treat 0 as 1:1 aspect ratio
3849 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3851 // Fill to parent, taking size mode factor into account
3852 switch( child.GetResizePolicy( dimension ) )
3854 case ResizePolicy::FILL_TO_PARENT:
3856 return GetLatestSize( dimension );
3859 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3861 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3864 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3866 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3871 return GetLatestSize( dimension );
3876 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3878 // Can be overridden in derived class
3879 return CalculateChildSizeBase( child, dimension );
3882 float Actor::GetHeightForWidth( float width )
3884 // Can be overridden in derived class
3885 return GetHeightForWidthBase( width );
3888 float Actor::GetWidthForHeight( float height )
3890 // Can be overridden in derived class
3891 return GetWidthForHeightBase( height );
3894 float Actor::GetLatestSize( Dimension::Type dimension ) const
3896 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3899 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3901 Vector2 padding = GetPadding( dimension );
3903 return GetLatestSize( dimension ) + padding.x + padding.y;
3906 float Actor::NegotiateFromParent( Dimension::Type dimension )
3908 Actor* parent = GetParent();
3911 Vector2 padding( GetPadding( dimension ) );
3912 Vector2 parentPadding( parent->GetPadding( dimension ) );
3913 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3919 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3921 float maxDimensionPoint = 0.0f;
3923 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3925 ActorPtr child = GetChildAt( i );
3927 if( !child->RelayoutDependentOnParent( dimension ) )
3929 // Calculate the min and max points that the children range across
3930 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3931 float dimensionSize = child->GetRelayoutSize( dimension );
3932 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3936 return maxDimensionPoint;
3939 float Actor::GetSize( Dimension::Type dimension ) const
3941 return GetDimensionValue( GetTargetSize(), dimension );
3944 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3946 return GetDimensionValue( GetNaturalSize(), dimension );
3949 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3951 switch( GetResizePolicy( dimension ) )
3953 case ResizePolicy::USE_NATURAL_SIZE:
3955 return GetNaturalSize( dimension );
3958 case ResizePolicy::FIXED:
3960 return GetDimensionValue( GetPreferredSize(), dimension );
3963 case ResizePolicy::USE_ASSIGNED_SIZE:
3965 return GetDimensionValue( maximumSize, dimension );
3968 case ResizePolicy::FILL_TO_PARENT:
3969 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3970 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3972 return NegotiateFromParent( dimension );
3975 case ResizePolicy::FIT_TO_CHILDREN:
3977 return NegotiateFromChildren( dimension );
3980 case ResizePolicy::DIMENSION_DEPENDENCY:
3982 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3985 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3987 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3990 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3992 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4004 return 0.0f; // Default
4007 float Actor::ClampDimension( float size, Dimension::Type dimension )
4009 const float minSize = GetMinimumSize( dimension );
4010 const float maxSize = GetMaximumSize( dimension );
4012 return std::max( minSize, std::min( size, maxSize ) );
4015 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4017 // Check if it needs to be negotiated
4018 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4020 // Check that we havn't gotten into an infinite loop
4021 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4022 bool recursionFound = false;
4023 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4025 if( *it == searchActor )
4027 recursionFound = true;
4032 if( !recursionFound )
4034 // Record the path that we have taken
4035 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4037 // Dimension dependency check
4038 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4040 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4042 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4044 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4048 // Parent dependency check
4049 Actor* parent = GetParent();
4050 if( parent && RelayoutDependentOnParent( dimension ) )
4052 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4055 // Children dependency check
4056 if( RelayoutDependentOnChildren( dimension ) )
4058 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4060 ActorPtr child = GetChildAt( i );
4062 // Only relayout child first if it is not dependent on this actor
4063 if( !child->RelayoutDependentOnParent( dimension ) )
4065 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4070 // For deriving classes
4071 OnCalculateRelayoutSize( dimension );
4073 // All dependencies checked, calculate the size and set negotiated flag
4074 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4076 SetNegotiatedDimension( newSize, dimension );
4077 SetLayoutNegotiated( true, dimension );
4079 // For deriving classes
4080 OnLayoutNegotiated( newSize, dimension );
4082 // This actor has been successfully processed, pop it off the recursion stack
4083 recursionStack.pop_back();
4087 // TODO: Break infinite loop
4088 SetLayoutNegotiated( true, dimension );
4093 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4095 // Negotiate all dimensions that require it
4096 ActorDimensionStack recursionStack;
4098 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4100 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4103 NegotiateDimension( dimension, allocatedSize, recursionStack );
4107 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4109 switch( mRelayoutData->sizeSetPolicy )
4111 case SizeScalePolicy::USE_SIZE_SET:
4116 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4118 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4119 const Vector3 naturalSize = GetNaturalSize();
4120 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4122 const float sizeRatio = size.width / size.height;
4123 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4125 if( naturalSizeRatio < sizeRatio )
4127 return Vector2( naturalSizeRatio * size.height, size.height );
4129 else if( naturalSizeRatio > sizeRatio )
4131 return Vector2( size.width, size.width / naturalSizeRatio );
4142 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4144 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4145 const Vector3 naturalSize = GetNaturalSize();
4146 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4148 const float sizeRatio = size.width / size.height;
4149 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4151 if( naturalSizeRatio < sizeRatio )
4153 return Vector2( size.width, size.width / naturalSizeRatio );
4155 else if( naturalSizeRatio > sizeRatio )
4157 return Vector2( naturalSizeRatio * size.height, size.height );
4176 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4178 // Do the set actor size
4179 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4181 // Adjust for size set policy
4182 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4184 // Lock the flag to stop recursive relayouts on set size
4185 mRelayoutData->insideRelayout = true;
4186 SetSize( negotiatedSize );
4187 mRelayoutData->insideRelayout = false;
4189 // Clear flags for all dimensions
4190 SetLayoutDirty( false );
4192 // Give deriving classes a chance to respond
4193 OnRelayout( negotiatedSize, container );
4195 if( !mOnRelayoutSignal.Empty() )
4197 Dali::Actor handle( this );
4198 mOnRelayoutSignal.Emit( handle );
4202 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4204 // Force a size negotiation for actors that has assigned size during relayout
4205 // This is required as otherwise the flags that force a relayout will not
4206 // necessarilly be set. This will occur if the actor has already been laid out.
4207 // The dirty flags are then cleared. Then if the actor is added back into the
4208 // relayout container afterwards, the dirty flags would still be clear...
4209 // causing a relayout to be skipped. Here we force any actors added to the
4210 // container to be relayed out.
4211 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4213 SetLayoutNegotiated(false, Dimension::WIDTH);
4215 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4217 SetLayoutNegotiated(false, Dimension::HEIGHT);
4220 // Do the negotiation
4221 NegotiateDimensions( allocatedSize );
4223 // Set the actor size
4224 SetNegotiatedSize( container );
4226 // Negotiate down to children
4227 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4229 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4231 ActorPtr child = GetChildAt( i );
4233 // Forces children that have already been laid out to be relayed out
4234 // if they have assigned size during relayout.
4235 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4237 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4238 child->SetLayoutDirty(true, Dimension::WIDTH);
4240 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4242 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4243 child->SetLayoutDirty(true, Dimension::HEIGHT);
4246 // Only relayout if required
4247 if( child->RelayoutRequired() )
4249 container.Add( Dali::Actor( child.Get() ), newBounds );
4254 void Actor::RelayoutRequest( Dimension::Type dimension )
4256 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4257 if( relayoutController )
4259 Dali::Actor self( this );
4260 relayoutController->RequestRelayout( self, dimension );
4264 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4268 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4272 void Actor::SetPreferredSize( const Vector2& size )
4274 EnsureRelayoutData();
4276 if( size.width > 0.0f )
4278 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4281 if( size.height > 0.0f )
4283 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4286 mRelayoutData->preferredSize = size;
4291 Vector2 Actor::GetPreferredSize() const
4293 if ( mRelayoutData )
4295 return Vector2( mRelayoutData->preferredSize );
4298 return GetDefaultPreferredSize();
4301 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4303 EnsureRelayoutData();
4305 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4307 if( dimension & ( 1 << i ) )
4309 mRelayoutData->minimumSize[ i ] = size;
4316 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4318 if ( mRelayoutData )
4320 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4322 if( dimension & ( 1 << i ) )
4324 return mRelayoutData->minimumSize[ i ];
4329 return 0.0f; // Default
4332 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4334 EnsureRelayoutData();
4336 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4338 if( dimension & ( 1 << i ) )
4340 mRelayoutData->maximumSize[ i ] = size;
4347 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4349 if ( mRelayoutData )
4351 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4353 if( dimension & ( 1 << i ) )
4355 return mRelayoutData->maximumSize[ i ];
4360 return FLT_MAX; // Default
4363 Object* Actor::GetParentObject() const
4368 } // namespace Internal