2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/common/animatable-property.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/nodes/node-declarations.h>
51 #include <dali/internal/update/animation/scene-graph-constraint.h>
52 #include <dali/internal/event/events/actor-gesture-data.h>
53 #include <dali/internal/common/message.h>
54 #include <dali/integration-api/debug.h>
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::PropertyBase;
66 unsigned int Actor::mActorCounter = 0;
70 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
71 inline const Vector3& GetDefaultSizeModeFactor()
76 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
77 inline const Vector2& GetDefaultPreferredSize()
82 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
83 inline const Vector2& GetDefaultDimensionPadding()
88 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
90 } // unnamed namespace
93 * Struct to collect relayout variables
95 struct Actor::RelayoutData
98 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
100 // Set size negotiation defaults
101 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
103 resizePolicies[ i ] = ResizePolicy::DEFAULT;
104 negotiatedDimensions[ i ] = 0.0f;
105 dimensionNegotiated[ i ] = false;
106 dimensionDirty[ i ] = false;
107 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
108 dimensionPadding[ i ] = GetDefaultDimensionPadding();
109 minimumSize[ i ] = 0.0f;
110 maximumSize[ i ] = FLT_MAX;
114 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
116 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
118 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
120 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
122 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
123 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
125 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
126 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
128 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
130 Vector2 preferredSize; ///< The preferred size of the actor
132 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
134 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
135 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
138 namespace // unnamed namespace
144 * We want to discourage the use of property strings (minimize string comparisons),
145 * particularly for the default properties.
146 * Name Type writable animatable constraint-input enum for index-checking
148 DALI_PROPERTY_TABLE_BEGIN
149 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
150 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
151 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
152 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
153 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
154 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
155 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
156 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
157 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
158 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
159 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
160 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
161 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
162 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
163 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
164 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
165 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
166 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
167 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
168 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
169 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
170 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
171 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
172 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
173 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
174 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
175 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
176 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
177 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
178 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
179 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
180 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
181 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
182 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
183 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
184 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
185 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
186 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
187 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
188 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
189 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
190 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
191 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
192 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
193 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
194 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
195 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
196 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
197 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
198 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
199 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
200 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
201 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
202 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
203 DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::DevelActor::Property::BATCH_PARENT )
204 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
205 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
209 const char* const SIGNAL_TOUCHED = "touched";
210 const char* const SIGNAL_HOVERED = "hovered";
211 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
212 const char* const SIGNAL_ON_STAGE = "onStage";
213 const char* const SIGNAL_OFF_STAGE = "offStage";
214 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
215 const char* const SIGNAL_TOUCH = "touch";
219 const char* const ACTION_SHOW = "show";
220 const char* const ACTION_HIDE = "hide";
222 BaseHandle CreateActor()
224 return Dali::Actor::New();
227 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
229 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
232 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
233 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
234 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
235 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
237 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
238 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
243 const Vector3& value;
246 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
252 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
253 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
254 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
255 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
256 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
258 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
259 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
260 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
261 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
262 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
263 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
265 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
266 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
267 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
268 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
269 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
270 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
272 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
276 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
278 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
287 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
289 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
293 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
295 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
298 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
301 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
303 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
305 size_t sizeIgnored = 0;
306 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
308 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
315 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
317 // Values are the same so just use the same table as anchor-point
318 return GetAnchorPointConstant( value, parentOrigin );
322 * @brief Extract a given dimension from a Vector2
324 * @param[in] values The values to extract from
325 * @param[in] dimension The dimension to extract
326 * @return Return the value for the dimension
328 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
332 case Dimension::WIDTH:
336 case Dimension::HEIGHT:
338 return values.height;
349 * @brief Extract a given dimension from a Vector3
351 * @param[in] values The values to extract from
352 * @param[in] dimension The dimension to extract
353 * @return Return the value for the dimension
355 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
357 return GetDimensionValue( values.GetVectorXY(), dimension );
360 unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder )
362 return depth * Dali::DevelLayer::TREE_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
365 } // unnamed namespace
367 ActorPtr Actor::New()
369 ActorPtr actor( new Actor( BASIC ) );
371 // Second-phase construction
377 const std::string& Actor::GetName() const
382 void Actor::SetName( const std::string& name )
388 // ATTENTION: string for debug purposes is not thread safe.
389 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
393 unsigned int Actor::GetId() const
398 bool Actor::OnStage() const
403 Dali::Layer Actor::GetLayer()
407 // Short-circuit for Layer derived actors
410 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
413 // Find the immediate Layer parent
414 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
416 if( parent->IsLayer() )
418 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
425 void Actor::Add( Actor& child )
427 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
428 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
432 mChildren = new ActorContainer;
435 Actor* const oldParent( child.mParent );
437 // child might already be ours
438 if( this != oldParent )
440 // if we already have parent, unparent us first
443 oldParent->Remove( child ); // This causes OnChildRemove callback
445 // Old parent may need to readjust to missing child
446 if( oldParent->RelayoutDependentOnChildren() )
448 oldParent->RelayoutRequest();
452 // Guard against Add() during previous OnChildRemove callback
455 // Do this first, since user callbacks from within SetParent() may need to remove child
456 mChildren->push_back( ActorPtr( &child ) );
458 // SetParent asserts that child can be added
459 child.SetParent( this );
461 // Notification for derived classes
464 // Only put in a relayout request if there is a suitable dependency
465 if( RelayoutDependentOnChildren() )
473 void Actor::Remove( Actor& child )
475 if( (this == &child) || (!mChildren) )
477 // no children or removing itself
483 // Find the child in mChildren, and unparent it
484 ActorIter end = mChildren->end();
485 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
487 ActorPtr actor = (*iter);
489 if( actor.Get() == &child )
491 // Keep handle for OnChildRemove notification
494 // Do this first, since user callbacks from within SetParent() may need to add the child
495 mChildren->erase( iter );
497 DALI_ASSERT_DEBUG( actor->GetParent() == this );
498 actor->SetParent( NULL );
506 // Only put in a relayout request if there is a suitable dependency
507 if( RelayoutDependentOnChildren() )
513 // Notification for derived classes
514 OnChildRemove( child );
517 void Actor::Unparent()
521 // Remove this actor from the parent. The remove will put a relayout request in for
522 // the parent if required
523 mParent->Remove( *this );
524 // mParent is now NULL!
528 unsigned int Actor::GetChildCount() const
530 return ( NULL != mChildren ) ? mChildren->size() : 0;
533 ActorPtr Actor::GetChildAt( unsigned int index ) const
535 DALI_ASSERT_ALWAYS( index < GetChildCount() );
537 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
540 ActorPtr Actor::FindChildByName( const std::string& actorName )
543 if( actorName == mName )
549 ActorIter end = mChildren->end();
550 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
552 child = (*iter)->FindChildByName( actorName );
563 ActorPtr Actor::FindChildById( const unsigned int id )
572 ActorIter end = mChildren->end();
573 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
575 child = (*iter)->FindChildById( id );
586 void Actor::SetParentOrigin( const Vector3& origin )
590 // mNode is being used in a separate thread; queue a message to set the value & base value
591 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
594 // Cache for event-thread access
597 // not allocated, check if different from default
598 if( ParentOrigin::DEFAULT != origin )
600 mParentOrigin = new Vector3( origin );
605 // check if different from current costs more than just set
606 *mParentOrigin = origin;
610 void Actor::SetParentOriginX( float x )
612 const Vector3& current = GetCurrentParentOrigin();
614 SetParentOrigin( Vector3( x, current.y, current.z ) );
617 void Actor::SetParentOriginY( float y )
619 const Vector3& current = GetCurrentParentOrigin();
621 SetParentOrigin( Vector3( current.x, y, current.z ) );
624 void Actor::SetParentOriginZ( float z )
626 const Vector3& current = GetCurrentParentOrigin();
628 SetParentOrigin( Vector3( current.x, current.y, z ) );
631 const Vector3& Actor::GetCurrentParentOrigin() const
633 // Cached for event-thread access
634 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
637 void Actor::SetAnchorPoint( const Vector3& anchor )
641 // mNode is being used in a separate thread; queue a message to set the value & base value
642 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
645 // Cache for event-thread access
648 // not allocated, check if different from default
649 if( AnchorPoint::DEFAULT != anchor )
651 mAnchorPoint = new Vector3( anchor );
656 // check if different from current costs more than just set
657 *mAnchorPoint = anchor;
661 void Actor::SetAnchorPointX( float x )
663 const Vector3& current = GetCurrentAnchorPoint();
665 SetAnchorPoint( Vector3( x, current.y, current.z ) );
668 void Actor::SetAnchorPointY( float y )
670 const Vector3& current = GetCurrentAnchorPoint();
672 SetAnchorPoint( Vector3( current.x, y, current.z ) );
675 void Actor::SetAnchorPointZ( float z )
677 const Vector3& current = GetCurrentAnchorPoint();
679 SetAnchorPoint( Vector3( current.x, current.y, z ) );
682 const Vector3& Actor::GetCurrentAnchorPoint() const
684 // Cached for event-thread access
685 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
688 void Actor::SetPosition( float x, float y )
690 SetPosition( Vector3( x, y, 0.0f ) );
693 void Actor::SetPosition( float x, float y, float z )
695 SetPosition( Vector3( x, y, z ) );
698 void Actor::SetPosition( const Vector3& position )
700 mTargetPosition = position;
704 // mNode is being used in a separate thread; queue a message to set the value & base value
705 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
709 void Actor::SetX( float x )
711 mTargetPosition.x = x;
715 // mNode is being used in a separate thread; queue a message to set the value & base value
716 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
720 void Actor::SetY( float y )
722 mTargetPosition.y = y;
726 // mNode is being used in a separate thread; queue a message to set the value & base value
727 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
731 void Actor::SetZ( float z )
733 mTargetPosition.z = z;
737 // mNode is being used in a separate thread; queue a message to set the value & base value
738 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
742 void Actor::TranslateBy( const Vector3& distance )
744 mTargetPosition += distance;
748 // mNode is being used in a separate thread; queue a message to set the value & base value
749 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
753 const Vector3& Actor::GetCurrentPosition() const
757 // mNode is being used in a separate thread; copy the value from the previous update
758 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
761 return Vector3::ZERO;
764 const Vector3& Actor::GetTargetPosition() const
766 return mTargetPosition;
769 const Vector3& Actor::GetCurrentWorldPosition() const
773 // mNode is being used in a separate thread; copy the value from the previous update
774 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
777 return Vector3::ZERO;
780 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
782 // this flag is not animatable so keep the value
783 mPositionInheritanceMode = mode;
786 // mNode is being used in a separate thread; queue a message to set the value
787 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
791 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
793 // Cached for event-thread access
794 return mPositionInheritanceMode;
797 void Actor::SetInheritPosition( bool inherit )
799 if( mInheritPosition != inherit && NULL != mNode )
801 // non animateable so keep local copy
802 mInheritPosition = inherit;
803 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
807 bool Actor::IsPositionInherited() const
809 return mInheritPosition;
812 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
814 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
815 normalizedAxis.Normalize();
817 Quaternion orientation( angle, normalizedAxis );
819 SetOrientation( orientation );
822 void Actor::SetOrientation( const Quaternion& orientation )
826 // mNode is being used in a separate thread; queue a message to set the value & base value
827 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
831 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
835 // mNode is being used in a separate thread; queue a message to set the value & base value
836 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
840 void Actor::RotateBy( const Quaternion& relativeRotation )
844 // mNode is being used in a separate thread; queue a message to set the value & base value
845 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
849 const Quaternion& Actor::GetCurrentOrientation() const
853 // mNode is being used in a separate thread; copy the value from the previous update
854 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
857 return Quaternion::IDENTITY;
860 const Quaternion& Actor::GetCurrentWorldOrientation() const
864 // mNode is being used in a separate thread; copy the value from the previous update
865 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
868 return Quaternion::IDENTITY;
871 void Actor::SetScale( float scale )
873 SetScale( Vector3( scale, scale, scale ) );
876 void Actor::SetScale( float x, float y, float z )
878 SetScale( Vector3( x, y, z ) );
881 void Actor::SetScale( const Vector3& scale )
885 // mNode is being used in a separate thread; queue a message to set the value & base value
886 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
890 void Actor::SetScaleX( float x )
894 // mNode is being used in a separate thread; queue a message to set the value & base value
895 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
899 void Actor::SetScaleY( float y )
903 // mNode is being used in a separate thread; queue a message to set the value & base value
904 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
908 void Actor::SetScaleZ( float z )
912 // mNode is being used in a separate thread; queue a message to set the value & base value
913 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
917 void Actor::ScaleBy(const Vector3& relativeScale)
921 // mNode is being used in a separate thread; queue a message to set the value & base value
922 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
926 const Vector3& Actor::GetCurrentScale() const
930 // mNode is being used in a separate thread; copy the value from the previous update
931 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
937 const Vector3& Actor::GetCurrentWorldScale() const
941 // mNode is being used in a separate thread; copy the value from the previous update
942 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
948 void Actor::SetInheritScale( bool inherit )
951 if( mInheritScale != inherit && NULL != mNode )
953 // non animateable so keep local copy
954 mInheritScale = inherit;
955 // mNode is being used in a separate thread; queue a message to set the value
956 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
960 bool Actor::IsScaleInherited() const
962 return mInheritScale;
965 Matrix Actor::GetCurrentWorldMatrix() const
969 return mNode->GetWorldMatrix(0);
972 return Matrix::IDENTITY;
975 void Actor::SetVisible( bool visible )
979 // mNode is being used in a separate thread; queue a message to set the value & base value
980 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
984 bool Actor::IsVisible() const
988 // mNode is being used in a separate thread; copy the value from the previous update
989 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
995 void Actor::SetOpacity( float opacity )
999 // mNode is being used in a separate thread; queue a message to set the value & base value
1000 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1004 float Actor::GetCurrentOpacity() const
1008 // mNode is being used in a separate thread; copy the value from the previous update
1009 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1015 ClippingMode::Type Actor::GetClippingMode() const
1017 return mClippingMode;
1020 const Vector4& Actor::GetCurrentWorldColor() const
1024 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1027 return Color::WHITE;
1030 void Actor::SetColor( const Vector4& color )
1034 // mNode is being used in a separate thread; queue a message to set the value & base value
1035 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1039 void Actor::SetColorRed( float red )
1043 // mNode is being used in a separate thread; queue a message to set the value & base value
1044 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1048 void Actor::SetColorGreen( float green )
1052 // mNode is being used in a separate thread; queue a message to set the value & base value
1053 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1057 void Actor::SetColorBlue( float blue )
1061 // mNode is being used in a separate thread; queue a message to set the value & base value
1062 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1066 const Vector4& Actor::GetCurrentColor() const
1070 // mNode is being used in a separate thread; copy the value from the previous update
1071 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1074 return Color::WHITE;
1077 void Actor::SetInheritOrientation( bool inherit )
1079 if( mInheritOrientation != inherit && NULL != mNode)
1081 // non animateable so keep local copy
1082 mInheritOrientation = inherit;
1083 // mNode is being used in a separate thread; queue a message to set the value
1084 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1088 bool Actor::IsOrientationInherited() const
1090 return mInheritOrientation;
1093 void Actor::SetSizeModeFactor( const Vector3& factor )
1095 EnsureRelayoutData();
1097 mRelayoutData->sizeModeFactor = factor;
1100 const Vector3& Actor::GetSizeModeFactor() const
1102 if ( mRelayoutData )
1104 return mRelayoutData->sizeModeFactor;
1107 return GetDefaultSizeModeFactor();
1110 void Actor::SetColorMode( ColorMode colorMode )
1112 // non animateable so keep local copy
1113 mColorMode = colorMode;
1116 // mNode is being used in a separate thread; queue a message to set the value
1117 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1121 ColorMode Actor::GetColorMode() const
1123 // we have cached copy
1127 void Actor::SetSize( float width, float height )
1129 SetSize( Vector2( width, height ) );
1132 void Actor::SetSize( float width, float height, float depth )
1134 SetSize( Vector3( width, height, depth ) );
1137 void Actor::SetSize( const Vector2& size )
1139 SetSize( Vector3( size.width, size.height, 0.f ) );
1142 void Actor::SetSizeInternal( const Vector2& size )
1144 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1147 void Actor::SetSize( const Vector3& size )
1149 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1151 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1152 SetPreferredSize( size.GetVectorXY() );
1156 SetSizeInternal( size );
1160 void Actor::SetSizeInternal( const Vector3& size )
1162 // dont allow recursive loop
1163 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1164 // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
1165 if( ( NULL != mNode )&&
1166 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1167 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1168 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1172 // mNode is being used in a separate thread; queue a message to set the value & base value
1173 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1175 // Notification for derived classes
1176 mInsideOnSizeSet = true;
1177 OnSizeSet( mTargetSize );
1178 mInsideOnSizeSet = false;
1180 // Raise a relayout request if the flag is not locked
1181 if( mRelayoutData && !mRelayoutData->insideRelayout )
1188 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1190 mTargetSize = targetSize;
1192 // Notify deriving classes
1193 OnSizeAnimation( animation, mTargetSize );
1196 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1198 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1200 mTargetSize.width = targetSize;
1202 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1204 mTargetSize.height = targetSize;
1206 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1208 mTargetSize.depth = targetSize;
1210 // Notify deriving classes
1211 OnSizeAnimation( animation, mTargetSize );
1214 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1216 mTargetPosition = targetPosition;
1219 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1221 if ( Dali::Actor::Property::POSITION_X == property )
1223 mTargetPosition.x = targetPosition;
1225 else if ( Dali::Actor::Property::POSITION_Y == property )
1227 mTargetPosition.y = targetPosition;
1229 else if ( Dali::Actor::Property::POSITION_Z == property )
1231 mTargetPosition.z = targetPosition;
1235 void Actor::SetWidth( float width )
1237 mTargetSize.width = width;
1241 // mNode is being used in a separate thread; queue a message to set the value & base value
1242 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1246 void Actor::SetHeight( float height )
1248 mTargetSize.height = height;
1252 // mNode is being used in a separate thread; queue a message to set the value & base value
1253 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1257 void Actor::SetDepth( float depth )
1259 mTargetSize.depth = depth;
1263 // mNode is being used in a separate thread; queue a message to set the value & base value
1264 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1268 const Vector3& Actor::GetTargetSize() const
1273 const Vector3& Actor::GetCurrentSize() const
1277 // mNode is being used in a separate thread; copy the value from the previous update
1278 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1281 return Vector3::ZERO;
1284 Vector3 Actor::GetNaturalSize() const
1286 // It is up to deriving classes to return the appropriate natural size
1287 return Vector3( 0.0f, 0.0f, 0.0f );
1290 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1292 EnsureRelayoutData();
1294 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1296 if( dimension & ( 1 << i ) )
1298 mRelayoutData->resizePolicies[ i ] = policy;
1302 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1304 if( dimension & Dimension::WIDTH )
1306 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1309 if( dimension & Dimension::HEIGHT )
1311 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1315 // If calling SetResizePolicy, assume we want relayout enabled
1316 SetRelayoutEnabled( true );
1318 OnSetResizePolicy( policy, dimension );
1320 // Trigger relayout on this control
1324 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1326 if ( mRelayoutData )
1328 // If more than one dimension is requested, just return the first one found
1329 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1331 if( ( dimension & ( 1 << i ) ) )
1333 return mRelayoutData->resizePolicies[ i ];
1338 return ResizePolicy::DEFAULT;
1341 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1343 EnsureRelayoutData();
1345 mRelayoutData->sizeSetPolicy = policy;
1348 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1350 if ( mRelayoutData )
1352 return mRelayoutData->sizeSetPolicy;
1355 return DEFAULT_SIZE_SCALE_POLICY;
1358 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1360 EnsureRelayoutData();
1362 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1364 if( dimension & ( 1 << i ) )
1366 mRelayoutData->dimensionDependencies[ i ] = dependency;
1371 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1373 if ( mRelayoutData )
1375 // If more than one dimension is requested, just return the first one found
1376 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1378 if( ( dimension & ( 1 << i ) ) )
1380 return mRelayoutData->dimensionDependencies[ i ];
1385 return Dimension::ALL_DIMENSIONS; // Default
1388 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1390 // If relayout data has not been allocated yet and the client is requesting
1391 // to disable it, do nothing
1392 if( mRelayoutData || relayoutEnabled )
1394 EnsureRelayoutData();
1396 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1398 mRelayoutData->relayoutEnabled = relayoutEnabled;
1402 bool Actor::IsRelayoutEnabled() const
1404 // Assume that if relayout data has not been allocated yet then
1405 // relayout is disabled
1406 return mRelayoutData && mRelayoutData->relayoutEnabled;
1409 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1411 EnsureRelayoutData();
1413 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1415 if( dimension & ( 1 << i ) )
1417 mRelayoutData->dimensionDirty[ i ] = dirty;
1422 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1424 if ( mRelayoutData )
1426 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1428 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1438 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1440 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1443 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1445 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1448 unsigned int Actor::AddRenderer( Renderer& renderer )
1452 mRenderers = new RendererContainer;
1455 unsigned int index = mRenderers->size();
1456 RendererPtr rendererPtr = RendererPtr( &renderer );
1457 mRenderers->push_back( rendererPtr );
1458 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1462 rendererPtr->Connect();
1468 unsigned int Actor::GetRendererCount() const
1470 unsigned int rendererCount(0);
1473 rendererCount = mRenderers->size();
1476 return rendererCount;
1479 RendererPtr Actor::GetRendererAt( unsigned int index )
1481 RendererPtr renderer;
1482 if( index < GetRendererCount() )
1484 renderer = ( *mRenderers )[ index ];
1490 void Actor::RemoveRenderer( Renderer& renderer )
1494 RendererIter end = mRenderers->end();
1495 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1497 if( (*iter).Get() == &renderer )
1499 mRenderers->erase( iter );
1500 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1507 void Actor::RemoveRenderer( unsigned int index )
1509 if( index < GetRendererCount() )
1511 RendererPtr renderer = ( *mRenderers )[ index ];
1512 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1513 mRenderers->erase( mRenderers->begin()+index );
1517 bool Actor::IsOverlay() const
1519 return ( DrawMode::OVERLAY_2D == mDrawMode );
1522 void Actor::SetDrawMode( DrawMode::Type drawMode )
1524 // this flag is not animatable so keep the value
1525 mDrawMode = drawMode;
1526 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1528 // mNode is being used in a separate thread; queue a message to set the value
1529 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1533 DrawMode::Type Actor::GetDrawMode() const
1538 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1540 // only valid when on-stage
1541 StagePtr stage = Stage::GetCurrent();
1542 if( stage && OnStage() )
1544 const RenderTaskList& taskList = stage->GetRenderTaskList();
1546 Vector2 converted( screenX, screenY );
1548 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1549 const int taskCount = taskList.GetTaskCount();
1550 for( int i = taskCount - 1; i >= 0; --i )
1552 Dali::RenderTask task = taskList.GetTask( i );
1553 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1555 // found a task where this conversion was ok so return
1563 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1565 bool retval = false;
1566 // only valid when on-stage
1569 CameraActor* camera = renderTask.GetCameraActor();
1573 renderTask.GetViewport( viewport );
1575 // need to translate coordinates to render tasks coordinate space
1576 Vector2 converted( screenX, screenY );
1577 if( renderTask.TranslateCoordinates( converted ) )
1579 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1586 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1588 // Early-out if mNode is NULL
1594 // Get the ModelView matrix
1596 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1598 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1599 Matrix invertedMvp( false/*don't init*/);
1600 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1601 bool success = invertedMvp.Invert();
1603 // Convert to GL coordinates
1604 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1609 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1616 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1622 if( XyPlaneIntersect( nearPos, farPos, local ) )
1624 Vector3 size = GetCurrentSize();
1625 localX = local.x + size.x * 0.5f;
1626 localY = local.y + size.y * 0.5f;
1637 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1640 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1642 Mathematical Formulation
1644 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1646 ( p - c ) dot ( p - c ) = r^2
1648 Given a ray with a point of origin 'o', and a direction vector 'd':
1650 ray(t) = o + td, t >= 0
1652 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1654 (o + td - c ) dot ( o + td - c ) = r^2
1656 To solve for t we first expand the above into a more recognisable quadratic equation form
1658 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1667 B = 2( o - c ) dot d
1668 C = ( o - c ) dot ( o - c ) - r^2
1670 which can be solved using a standard quadratic formula.
1672 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1674 Practical Simplification
1676 In a renderer, we often differentiate between world space and object space. In the object space
1677 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1678 into object space, the mathematical solution presented above can be simplified significantly.
1680 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1684 and we can find the t at which the (transformed) ray intersects the sphere by
1686 ( o + td ) dot ( o + td ) = r^2
1688 According to the reasoning above, we expand the above quadratic equation into the general form
1692 which now has coefficients:
1699 // Early out if mNode is NULL
1705 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1707 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1708 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1709 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1711 // Compute the radius is not needed, square radius it's enough.
1712 const Vector3& size( mNode->GetSize( bufferIndex ) );
1714 // Scale the sphere.
1715 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1717 const float width = size.width * scale.width;
1718 const float height = size.height * scale.height;
1720 float squareSphereRadius = 0.5f * ( width * width + height * height );
1722 float a = rayDir.Dot( rayDir ); // a
1723 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1724 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1726 return ( b2 * b2 - a * c ) >= 0.f;
1729 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1733 if( OnStage() && NULL != mNode )
1735 // Transforms the ray to the local reference system.
1736 // Calculate the inverse of Model matrix
1737 Matrix invModelMatrix( false/*don't init*/);
1739 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1740 invModelMatrix = mNode->GetWorldMatrix(0);
1741 invModelMatrix.Invert();
1743 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1744 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1746 // Test with the actor's XY plane (Normal = 0 0 1 1).
1748 float a = -rayOriginLocal.z;
1749 float b = rayDirLocal.z;
1751 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1753 // Ray travels distance * rayDirLocal to intersect with plane.
1756 const Vector3& size = mNode->GetSize( bufferIndex );
1758 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1759 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1761 // Test with the actor's geometry.
1762 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1769 void Actor::SetLeaveRequired( bool required )
1771 mLeaveRequired = required;
1774 bool Actor::GetLeaveRequired() const
1776 return mLeaveRequired;
1779 void Actor::SetKeyboardFocusable( bool focusable )
1781 mKeyboardFocusable = focusable;
1784 bool Actor::IsKeyboardFocusable() const
1786 return mKeyboardFocusable;
1789 bool Actor::GetTouchRequired() const
1791 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1794 bool Actor::GetHoverRequired() const
1796 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1799 bool Actor::GetWheelEventRequired() const
1801 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1804 bool Actor::IsHittable() const
1806 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1809 ActorGestureData& Actor::GetGestureData()
1811 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1812 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1813 if( NULL == mGestureData )
1815 mGestureData = new ActorGestureData;
1817 return *mGestureData;
1820 bool Actor::IsGestureRequred( Gesture::Type type ) const
1822 return mGestureData && mGestureData->IsGestureRequred( type );
1825 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1827 bool consumed = false;
1829 if( !mTouchSignal.Empty() )
1831 Dali::Actor handle( this );
1832 consumed = mTouchSignal.Emit( handle, touch );
1835 if( !mTouchedSignal.Empty() )
1837 Dali::Actor handle( this );
1838 consumed |= mTouchedSignal.Emit( handle, event );
1843 // Notification for derived classes
1844 consumed = OnTouchEvent( event ); // TODO
1850 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1852 bool consumed = false;
1854 if( !mHoveredSignal.Empty() )
1856 Dali::Actor handle( this );
1857 consumed = mHoveredSignal.Emit( handle, event );
1862 // Notification for derived classes
1863 consumed = OnHoverEvent( event );
1869 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1871 bool consumed = false;
1873 if( !mWheelEventSignal.Empty() )
1875 Dali::Actor handle( this );
1876 consumed = mWheelEventSignal.Emit( handle, event );
1881 // Notification for derived classes
1882 consumed = OnWheelEvent( event );
1888 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1890 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1891 return mTouchedSignal;
1894 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1896 return mTouchSignal;
1899 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1901 return mHoveredSignal;
1904 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1906 return mWheelEventSignal;
1909 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1911 return mOnStageSignal;
1914 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1916 return mOffStageSignal;
1919 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1921 return mOnRelayoutSignal;
1924 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1926 bool connected( true );
1927 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1929 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1931 actor->TouchedSignal().Connect( tracker, functor );
1933 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1935 actor->HoveredSignal().Connect( tracker, functor );
1937 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1939 actor->WheelEventSignal().Connect( tracker, functor );
1941 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1943 actor->OnStageSignal().Connect( tracker, functor );
1945 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1947 actor->OffStageSignal().Connect( tracker, functor );
1949 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1951 actor->OnRelayoutSignal().Connect( tracker, functor );
1953 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1955 actor->TouchSignal().Connect( tracker, functor );
1959 // signalName does not match any signal
1966 Actor::Actor( DerivedType derivedType )
1971 mParentOrigin( NULL ),
1972 mAnchorPoint( NULL ),
1973 mRelayoutData( NULL ),
1974 mGestureData( NULL ),
1975 mTargetSize( 0.0f, 0.0f, 0.0f ),
1977 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1980 mIsRoot( ROOT_LAYER == derivedType ),
1981 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1982 mIsOnStage( false ),
1984 mLeaveRequired( false ),
1985 mKeyboardFocusable( false ),
1986 mDerivedRequiresTouch( false ),
1987 mDerivedRequiresHover( false ),
1988 mDerivedRequiresWheelEvent( false ),
1989 mOnStageSignalled( false ),
1990 mInsideOnSizeSet( false ),
1991 mInheritPosition( true ),
1992 mInheritOrientation( true ),
1993 mInheritScale( true ),
1994 mDrawMode( DrawMode::NORMAL ),
1995 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1996 mColorMode( Node::DEFAULT_COLOR_MODE ),
1997 mClippingMode( ClippingMode::DISABLED ),
1998 mIsBatchParent( false )
2002 void Actor::Initialize()
2005 SceneGraph::Node* node = CreateNode();
2007 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2008 mNode = node; // Keep raw-pointer to Node
2012 GetEventThreadServices().RegisterObject( this );
2017 // Remove mParent pointers from children even if we're destroying core,
2018 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2021 ActorConstIter endIter = mChildren->end();
2022 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2024 (*iter)->SetParent( NULL );
2030 // Guard to allow handle destruction after Core has been destroyed
2031 if( EventThreadServices::IsCoreRunning() )
2035 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2036 mNode = NULL; // Node is about to be destroyed
2039 GetEventThreadServices().UnregisterObject( this );
2042 // Cleanup optional gesture data
2043 delete mGestureData;
2045 // Cleanup optional parent origin and anchor
2046 delete mParentOrigin;
2047 delete mAnchorPoint;
2049 // Delete optional relayout data
2052 delete mRelayoutData;
2056 void Actor::ConnectToStage( unsigned int parentDepth )
2058 // This container is used instead of walking the Actor hierarchy.
2059 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2060 ActorContainer connectionList;
2062 // This stage is atomic i.e. not interrupted by user callbacks.
2063 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2065 // Notify applications about the newly connected actors.
2066 const ActorIter endIter = connectionList.end();
2067 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2069 (*iter)->NotifyStageConnection();
2075 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2077 DALI_ASSERT_ALWAYS( !OnStage() );
2081 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2083 ConnectToSceneGraph();
2085 // Notification for internal derived classes
2086 OnStageConnectionInternal();
2088 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2089 connectionList.push_back( ActorPtr( this ) );
2091 // Recursively connect children
2094 ActorConstIter endIter = mChildren->end();
2095 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2097 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2103 * This method is called when the Actor is connected to the Stage.
2104 * The parent must have added its Node to the scene-graph.
2105 * The child must connect its Node to the parent's Node.
2106 * This is recursive; the child calls ConnectToStage() for its children.
2108 void Actor::ConnectToSceneGraph()
2110 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2114 // Reparent Node in next Update
2115 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2118 unsigned int rendererCount( GetRendererCount() );
2119 for( unsigned int i(0); i<rendererCount; ++i )
2121 GetRendererAt(i)->Connect();
2124 // Request relayout on all actors that are added to the scenegraph
2127 // Notification for Object::Observers
2131 void Actor::NotifyStageConnection()
2133 // Actors can be removed (in a callback), before the on-stage stage is reported.
2134 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2135 if( OnStage() && !mOnStageSignalled )
2137 // Notification for external (CustomActor) derived classes
2138 OnStageConnectionExternal( mDepth );
2140 if( !mOnStageSignal.Empty() )
2142 Dali::Actor handle( this );
2143 mOnStageSignal.Emit( handle );
2146 // Guard against Remove during callbacks
2149 mOnStageSignalled = true; // signal required next time Actor is removed
2154 void Actor::DisconnectFromStage()
2156 // This container is used instead of walking the Actor hierachy.
2157 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2158 ActorContainer disconnectionList;
2160 // This stage is atomic i.e. not interrupted by user callbacks
2161 RecursiveDisconnectFromStage( disconnectionList );
2163 // Notify applications about the newly disconnected actors.
2164 const ActorIter endIter = disconnectionList.end();
2165 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2167 (*iter)->NotifyStageDisconnection();
2171 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2173 DALI_ASSERT_ALWAYS( OnStage() );
2175 // Recursively disconnect children
2178 ActorConstIter endIter = mChildren->end();
2179 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2181 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2185 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2186 disconnectionList.push_back( ActorPtr( this ) );
2188 // Notification for internal derived classes
2189 OnStageDisconnectionInternal();
2191 DisconnectFromSceneGraph();
2197 * This method is called by an actor or its parent, before a node removal message is sent.
2198 * This is recursive; the child calls DisconnectFromStage() for its children.
2200 void Actor::DisconnectFromSceneGraph()
2202 // Notification for Object::Observers
2203 OnSceneObjectRemove();
2205 unsigned int rendererCount( GetRendererCount() );
2206 for( unsigned int i(0); i<rendererCount; ++i )
2208 GetRendererAt(i)->Disconnect();
2212 void Actor::NotifyStageDisconnection()
2214 // Actors can be added (in a callback), before the off-stage state is reported.
2215 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2216 // only do this step if there is a stage, i.e. Core is not being shut down
2217 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2219 // Notification for external (CustomeActor) derived classes
2220 OnStageDisconnectionExternal();
2222 if( !mOffStageSignal.Empty() )
2224 Dali::Actor handle( this );
2225 mOffStageSignal.Emit( handle );
2228 // Guard against Add during callbacks
2231 mOnStageSignalled = false; // signal required next time Actor is added
2236 bool Actor::IsNodeConnected() const
2238 bool connected( false );
2240 if( OnStage() && ( NULL != mNode ) )
2242 if( IsRoot() || mNode->GetParent() )
2251 unsigned int Actor::GetDefaultPropertyCount() const
2253 return DEFAULT_PROPERTY_COUNT;
2256 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2258 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2260 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2262 indices.PushBack( i );
2266 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2268 if( index < DEFAULT_PROPERTY_COUNT )
2270 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2276 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2278 Property::Index index = Property::INVALID_INDEX;
2280 // Look for name in default properties
2281 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2283 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2284 if( 0 == name.compare( property->name ) )
2294 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2296 if( index < DEFAULT_PROPERTY_COUNT )
2298 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2304 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2306 if( index < DEFAULT_PROPERTY_COUNT )
2308 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2314 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2316 if( index < DEFAULT_PROPERTY_COUNT )
2318 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2324 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2326 if( index < DEFAULT_PROPERTY_COUNT )
2328 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2331 // index out of range...return Property::NONE
2332 return Property::NONE;
2335 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2339 case Dali::Actor::Property::PARENT_ORIGIN:
2341 Property::Type type = property.GetType();
2342 if( type == Property::VECTOR3 )
2344 SetParentOrigin( property.Get< Vector3 >() );
2346 else if ( type == Property::STRING )
2348 std::string parentOriginString;
2349 property.Get( parentOriginString );
2350 Vector3 parentOrigin;
2351 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2353 SetParentOrigin( parentOrigin );
2359 case Dali::Actor::Property::PARENT_ORIGIN_X:
2361 SetParentOriginX( property.Get< float >() );
2365 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2367 SetParentOriginY( property.Get< float >() );
2371 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2373 SetParentOriginZ( property.Get< float >() );
2377 case Dali::Actor::Property::ANCHOR_POINT:
2379 Property::Type type = property.GetType();
2380 if( type == Property::VECTOR3 )
2382 SetAnchorPoint( property.Get< Vector3 >() );
2384 else if ( type == Property::STRING )
2386 std::string anchorPointString;
2387 property.Get( anchorPointString );
2389 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2391 SetAnchorPoint( anchor );
2397 case Dali::Actor::Property::ANCHOR_POINT_X:
2399 SetAnchorPointX( property.Get< float >() );
2403 case Dali::Actor::Property::ANCHOR_POINT_Y:
2405 SetAnchorPointY( property.Get< float >() );
2409 case Dali::Actor::Property::ANCHOR_POINT_Z:
2411 SetAnchorPointZ( property.Get< float >() );
2415 case Dali::Actor::Property::SIZE:
2417 SetSize( property.Get< Vector3 >() );
2421 case Dali::Actor::Property::SIZE_WIDTH:
2423 SetWidth( property.Get< float >() );
2427 case Dali::Actor::Property::SIZE_HEIGHT:
2429 SetHeight( property.Get< float >() );
2433 case Dali::Actor::Property::SIZE_DEPTH:
2435 SetDepth( property.Get< float >() );
2439 case Dali::Actor::Property::POSITION:
2441 SetPosition( property.Get< Vector3 >() );
2445 case Dali::Actor::Property::POSITION_X:
2447 SetX( property.Get< float >() );
2451 case Dali::Actor::Property::POSITION_Y:
2453 SetY( property.Get< float >() );
2457 case Dali::Actor::Property::POSITION_Z:
2459 SetZ( property.Get< float >() );
2463 case Dali::Actor::Property::ORIENTATION:
2465 SetOrientation( property.Get< Quaternion >() );
2469 case Dali::Actor::Property::SCALE:
2471 SetScale( property.Get< Vector3 >() );
2475 case Dali::Actor::Property::SCALE_X:
2477 SetScaleX( property.Get< float >() );
2481 case Dali::Actor::Property::SCALE_Y:
2483 SetScaleY( property.Get< float >() );
2487 case Dali::Actor::Property::SCALE_Z:
2489 SetScaleZ( property.Get< float >() );
2493 case Dali::Actor::Property::VISIBLE:
2495 SetVisible( property.Get< bool >() );
2499 case Dali::Actor::Property::COLOR:
2501 SetColor( property.Get< Vector4 >() );
2505 case Dali::Actor::Property::COLOR_RED:
2507 SetColorRed( property.Get< float >() );
2511 case Dali::Actor::Property::COLOR_GREEN:
2513 SetColorGreen( property.Get< float >() );
2517 case Dali::Actor::Property::COLOR_BLUE:
2519 SetColorBlue( property.Get< float >() );
2523 case Dali::Actor::Property::COLOR_ALPHA:
2525 SetOpacity( property.Get< float >() );
2529 case Dali::Actor::Property::NAME:
2531 SetName( property.Get< std::string >() );
2535 case Dali::Actor::Property::SENSITIVE:
2537 SetSensitive( property.Get< bool >() );
2541 case Dali::Actor::Property::LEAVE_REQUIRED:
2543 SetLeaveRequired( property.Get< bool >() );
2547 case Dali::Actor::Property::INHERIT_POSITION:
2549 SetInheritPosition( property.Get< bool >() );
2553 case Dali::Actor::Property::INHERIT_ORIENTATION:
2555 SetInheritOrientation( property.Get< bool >() );
2559 case Dali::Actor::Property::INHERIT_SCALE:
2561 SetInheritScale( property.Get< bool >() );
2565 case Dali::Actor::Property::COLOR_MODE:
2568 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2570 SetColorMode( mode );
2575 case Dali::Actor::Property::POSITION_INHERITANCE:
2577 PositionInheritanceMode mode;
2578 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2580 SetPositionInheritanceMode( mode );
2585 case Dali::Actor::Property::DRAW_MODE:
2587 DrawMode::Type mode;
2588 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2590 SetDrawMode( mode );
2595 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2597 SetSizeModeFactor( property.Get< Vector3 >() );
2601 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2603 ResizePolicy::Type type;
2604 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2606 SetResizePolicy( type, Dimension::WIDTH );
2611 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2613 ResizePolicy::Type type;
2614 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2616 SetResizePolicy( type, Dimension::HEIGHT );
2621 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2623 SizeScalePolicy::Type type;
2624 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2626 SetSizeScalePolicy( type );
2631 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2633 if( property.Get< bool >() )
2635 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2640 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2642 if( property.Get< bool >() )
2644 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2649 case Dali::Actor::Property::PADDING:
2651 Vector4 padding = property.Get< Vector4 >();
2652 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2653 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2657 case Dali::Actor::Property::MINIMUM_SIZE:
2659 Vector2 size = property.Get< Vector2 >();
2660 SetMinimumSize( size.x, Dimension::WIDTH );
2661 SetMinimumSize( size.y, Dimension::HEIGHT );
2665 case Dali::Actor::Property::MAXIMUM_SIZE:
2667 Vector2 size = property.Get< Vector2 >();
2668 SetMaximumSize( size.x, Dimension::WIDTH );
2669 SetMaximumSize( size.y, Dimension::HEIGHT );
2673 case Dali::DevelActor::Property::BATCH_PARENT:
2677 if( property.Get( value ) )
2679 if( value != mIsBatchParent )
2681 mIsBatchParent = value;
2682 SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2688 case Dali::DevelActor::Property::SIBLING_ORDER:
2692 if( property.Get( value ) )
2694 if( static_cast<unsigned int>(value) != mSiblingOrder )
2696 mSiblingOrder = value;
2699 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2706 case Dali::Actor::Property::CLIPPING_MODE:
2708 ClippingMode::Type convertedValue = mClippingMode;
2709 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2711 mClippingMode = convertedValue;
2714 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2722 // this can happen in the case of a non-animatable default property so just do nothing
2728 // TODO: This method needs to be removed
2729 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2731 switch( entry.GetType() )
2733 case Property::BOOLEAN:
2735 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2736 DALI_ASSERT_DEBUG( NULL != property );
2738 // property is being used in a separate thread; queue a message to set the property
2739 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2744 case Property::INTEGER:
2746 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2747 DALI_ASSERT_DEBUG( NULL != property );
2749 // property is being used in a separate thread; queue a message to set the property
2750 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2755 case Property::FLOAT:
2757 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2758 DALI_ASSERT_DEBUG( NULL != property );
2760 // property is being used in a separate thread; queue a message to set the property
2761 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2766 case Property::VECTOR2:
2768 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2769 DALI_ASSERT_DEBUG( NULL != property );
2771 // property is being used in a separate thread; queue a message to set the property
2772 if(entry.componentIndex == 0)
2774 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2776 else if(entry.componentIndex == 1)
2778 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2782 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2788 case Property::VECTOR3:
2790 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2791 DALI_ASSERT_DEBUG( NULL != property );
2793 // property is being used in a separate thread; queue a message to set the property
2794 if(entry.componentIndex == 0)
2796 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2798 else if(entry.componentIndex == 1)
2800 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2802 else if(entry.componentIndex == 2)
2804 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2808 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2814 case Property::VECTOR4:
2816 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2817 DALI_ASSERT_DEBUG( NULL != property );
2819 // property is being used in a separate thread; queue a message to set the property
2820 if(entry.componentIndex == 0)
2822 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2824 else if(entry.componentIndex == 1)
2826 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2828 else if(entry.componentIndex == 2)
2830 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2832 else if(entry.componentIndex == 3)
2834 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2838 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2844 case Property::ROTATION:
2846 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2847 DALI_ASSERT_DEBUG( NULL != property );
2849 // property is being used in a separate thread; queue a message to set the property
2850 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2855 case Property::MATRIX:
2857 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2858 DALI_ASSERT_DEBUG( NULL != property );
2860 // property is being used in a separate thread; queue a message to set the property
2861 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2866 case Property::MATRIX3:
2868 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2869 DALI_ASSERT_DEBUG( NULL != property );
2871 // property is being used in a separate thread; queue a message to set the property
2872 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2879 // nothing to do for other types
2884 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2886 Property::Value value;
2888 if( index >= DEFAULT_PROPERTY_COUNT )
2895 case Dali::Actor::Property::PARENT_ORIGIN:
2897 value = GetCurrentParentOrigin();
2901 case Dali::Actor::Property::PARENT_ORIGIN_X:
2903 value = GetCurrentParentOrigin().x;
2907 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2909 value = GetCurrentParentOrigin().y;
2913 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2915 value = GetCurrentParentOrigin().z;
2919 case Dali::Actor::Property::ANCHOR_POINT:
2921 value = GetCurrentAnchorPoint();
2925 case Dali::Actor::Property::ANCHOR_POINT_X:
2927 value = GetCurrentAnchorPoint().x;
2931 case Dali::Actor::Property::ANCHOR_POINT_Y:
2933 value = GetCurrentAnchorPoint().y;
2937 case Dali::Actor::Property::ANCHOR_POINT_Z:
2939 value = GetCurrentAnchorPoint().z;
2943 case Dali::Actor::Property::SIZE:
2945 value = GetTargetSize();
2949 case Dali::Actor::Property::SIZE_WIDTH:
2951 value = GetTargetSize().width;
2955 case Dali::Actor::Property::SIZE_HEIGHT:
2957 value = GetTargetSize().height;
2961 case Dali::Actor::Property::SIZE_DEPTH:
2963 value = GetTargetSize().depth;
2967 case Dali::Actor::Property::POSITION:
2969 value = GetTargetPosition();
2973 case Dali::Actor::Property::POSITION_X:
2975 value = GetTargetPosition().x;
2979 case Dali::Actor::Property::POSITION_Y:
2981 value = GetTargetPosition().y;
2985 case Dali::Actor::Property::POSITION_Z:
2987 value = GetTargetPosition().z;
2991 case Dali::Actor::Property::WORLD_POSITION:
2993 value = GetCurrentWorldPosition();
2997 case Dali::Actor::Property::WORLD_POSITION_X:
2999 value = GetCurrentWorldPosition().x;
3003 case Dali::Actor::Property::WORLD_POSITION_Y:
3005 value = GetCurrentWorldPosition().y;
3009 case Dali::Actor::Property::WORLD_POSITION_Z:
3011 value = GetCurrentWorldPosition().z;
3015 case Dali::Actor::Property::ORIENTATION:
3017 value = GetCurrentOrientation();
3021 case Dali::Actor::Property::WORLD_ORIENTATION:
3023 value = GetCurrentWorldOrientation();
3027 case Dali::Actor::Property::SCALE:
3029 value = GetCurrentScale();
3033 case Dali::Actor::Property::SCALE_X:
3035 value = GetCurrentScale().x;
3039 case Dali::Actor::Property::SCALE_Y:
3041 value = GetCurrentScale().y;
3045 case Dali::Actor::Property::SCALE_Z:
3047 value = GetCurrentScale().z;
3051 case Dali::Actor::Property::WORLD_SCALE:
3053 value = GetCurrentWorldScale();
3057 case Dali::Actor::Property::VISIBLE:
3059 value = IsVisible();
3063 case Dali::Actor::Property::COLOR:
3065 value = GetCurrentColor();
3069 case Dali::Actor::Property::COLOR_RED:
3071 value = GetCurrentColor().r;
3075 case Dali::Actor::Property::COLOR_GREEN:
3077 value = GetCurrentColor().g;
3081 case Dali::Actor::Property::COLOR_BLUE:
3083 value = GetCurrentColor().b;
3087 case Dali::Actor::Property::COLOR_ALPHA:
3089 value = GetCurrentColor().a;
3093 case Dali::Actor::Property::WORLD_COLOR:
3095 value = GetCurrentWorldColor();
3099 case Dali::Actor::Property::WORLD_MATRIX:
3101 value = GetCurrentWorldMatrix();
3105 case Dali::Actor::Property::NAME:
3111 case Dali::Actor::Property::SENSITIVE:
3113 value = IsSensitive();
3117 case Dali::Actor::Property::LEAVE_REQUIRED:
3119 value = GetLeaveRequired();
3123 case Dali::Actor::Property::INHERIT_POSITION:
3125 value = IsPositionInherited();
3129 case Dali::Actor::Property::INHERIT_ORIENTATION:
3131 value = IsOrientationInherited();
3135 case Dali::Actor::Property::INHERIT_SCALE:
3137 value = IsScaleInherited();
3141 case Dali::Actor::Property::COLOR_MODE:
3143 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3147 case Dali::Actor::Property::POSITION_INHERITANCE:
3149 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3153 case Dali::Actor::Property::DRAW_MODE:
3155 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3159 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3161 value = GetSizeModeFactor();
3165 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3167 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3171 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3173 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3177 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3179 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3183 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3185 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3189 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3191 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3195 case Dali::Actor::Property::PADDING:
3197 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3198 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3199 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3203 case Dali::Actor::Property::MINIMUM_SIZE:
3205 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3209 case Dali::Actor::Property::MAXIMUM_SIZE:
3211 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3215 case Dali::DevelActor::Property::BATCH_PARENT:
3217 value = mIsBatchParent;
3221 case Dali::DevelActor::Property::SIBLING_ORDER:
3223 value = static_cast<int>(mSiblingOrder);
3227 case Dali::Actor::Property::CLIPPING_MODE:
3229 value = mClippingMode;
3237 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3242 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3244 // This method should only return an object connected to the scene-graph
3245 return OnStage() ? mNode : NULL;
3248 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3250 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3252 const PropertyBase* property( NULL );
3254 // This method should only return a property of an object connected to the scene-graph
3260 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3262 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3263 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3265 property = animatable->GetSceneGraphProperty();
3267 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3268 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3270 CustomPropertyMetadata* custom = FindCustomProperty( index );
3271 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3273 property = custom->GetSceneGraphProperty();
3275 else if( NULL != mNode )
3279 case Dali::Actor::Property::SIZE:
3280 property = &mNode->mSize;
3283 case Dali::Actor::Property::SIZE_WIDTH:
3284 property = &mNode->mSize;
3287 case Dali::Actor::Property::SIZE_HEIGHT:
3288 property = &mNode->mSize;
3291 case Dali::Actor::Property::SIZE_DEPTH:
3292 property = &mNode->mSize;
3295 case Dali::Actor::Property::POSITION:
3296 property = &mNode->mPosition;
3299 case Dali::Actor::Property::POSITION_X:
3300 property = &mNode->mPosition;
3303 case Dali::Actor::Property::POSITION_Y:
3304 property = &mNode->mPosition;
3307 case Dali::Actor::Property::POSITION_Z:
3308 property = &mNode->mPosition;
3311 case Dali::Actor::Property::ORIENTATION:
3312 property = &mNode->mOrientation;
3315 case Dali::Actor::Property::SCALE:
3316 property = &mNode->mScale;
3319 case Dali::Actor::Property::SCALE_X:
3320 property = &mNode->mScale;
3323 case Dali::Actor::Property::SCALE_Y:
3324 property = &mNode->mScale;
3327 case Dali::Actor::Property::SCALE_Z:
3328 property = &mNode->mScale;
3331 case Dali::Actor::Property::VISIBLE:
3332 property = &mNode->mVisible;
3335 case Dali::Actor::Property::COLOR:
3336 property = &mNode->mColor;
3339 case Dali::Actor::Property::COLOR_RED:
3340 property = &mNode->mColor;
3343 case Dali::Actor::Property::COLOR_GREEN:
3344 property = &mNode->mColor;
3347 case Dali::Actor::Property::COLOR_BLUE:
3348 property = &mNode->mColor;
3351 case Dali::Actor::Property::COLOR_ALPHA:
3352 property = &mNode->mColor;
3363 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3365 const PropertyInputImpl* property( NULL );
3367 // This method should only return a property of an object connected to the scene-graph
3373 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3375 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3376 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3378 property = animatable->GetSceneGraphProperty();
3380 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3381 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3383 CustomPropertyMetadata* custom = FindCustomProperty( index );
3384 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3385 property = custom->GetSceneGraphProperty();
3387 else if( NULL != mNode )
3391 case Dali::Actor::Property::PARENT_ORIGIN:
3392 property = &mNode->mParentOrigin;
3395 case Dali::Actor::Property::PARENT_ORIGIN_X:
3396 property = &mNode->mParentOrigin;
3399 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3400 property = &mNode->mParentOrigin;
3403 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3404 property = &mNode->mParentOrigin;
3407 case Dali::Actor::Property::ANCHOR_POINT:
3408 property = &mNode->mAnchorPoint;
3411 case Dali::Actor::Property::ANCHOR_POINT_X:
3412 property = &mNode->mAnchorPoint;
3415 case Dali::Actor::Property::ANCHOR_POINT_Y:
3416 property = &mNode->mAnchorPoint;
3419 case Dali::Actor::Property::ANCHOR_POINT_Z:
3420 property = &mNode->mAnchorPoint;
3423 case Dali::Actor::Property::SIZE:
3424 property = &mNode->mSize;
3427 case Dali::Actor::Property::SIZE_WIDTH:
3428 property = &mNode->mSize;
3431 case Dali::Actor::Property::SIZE_HEIGHT:
3432 property = &mNode->mSize;
3435 case Dali::Actor::Property::SIZE_DEPTH:
3436 property = &mNode->mSize;
3439 case Dali::Actor::Property::POSITION:
3440 property = &mNode->mPosition;
3443 case Dali::Actor::Property::POSITION_X:
3444 property = &mNode->mPosition;
3447 case Dali::Actor::Property::POSITION_Y:
3448 property = &mNode->mPosition;
3451 case Dali::Actor::Property::POSITION_Z:
3452 property = &mNode->mPosition;
3455 case Dali::Actor::Property::WORLD_POSITION:
3456 property = &mNode->mWorldPosition;
3459 case Dali::Actor::Property::WORLD_POSITION_X:
3460 property = &mNode->mWorldPosition;
3463 case Dali::Actor::Property::WORLD_POSITION_Y:
3464 property = &mNode->mWorldPosition;
3467 case Dali::Actor::Property::WORLD_POSITION_Z:
3468 property = &mNode->mWorldPosition;
3471 case Dali::Actor::Property::ORIENTATION:
3472 property = &mNode->mOrientation;
3475 case Dali::Actor::Property::WORLD_ORIENTATION:
3476 property = &mNode->mWorldOrientation;
3479 case Dali::Actor::Property::SCALE:
3480 property = &mNode->mScale;
3483 case Dali::Actor::Property::SCALE_X:
3484 property = &mNode->mScale;
3487 case Dali::Actor::Property::SCALE_Y:
3488 property = &mNode->mScale;
3491 case Dali::Actor::Property::SCALE_Z:
3492 property = &mNode->mScale;
3495 case Dali::Actor::Property::WORLD_SCALE:
3496 property = &mNode->mWorldScale;
3499 case Dali::Actor::Property::VISIBLE:
3500 property = &mNode->mVisible;
3503 case Dali::Actor::Property::COLOR:
3504 property = &mNode->mColor;
3507 case Dali::Actor::Property::COLOR_RED:
3508 property = &mNode->mColor;
3511 case Dali::Actor::Property::COLOR_GREEN:
3512 property = &mNode->mColor;
3515 case Dali::Actor::Property::COLOR_BLUE:
3516 property = &mNode->mColor;
3519 case Dali::Actor::Property::COLOR_ALPHA:
3520 property = &mNode->mColor;
3523 case Dali::Actor::Property::WORLD_COLOR:
3524 property = &mNode->mWorldColor;
3527 case Dali::Actor::Property::WORLD_MATRIX:
3528 property = &mNode->mWorldMatrix;
3539 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3541 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3543 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3545 // check whether the animatable property is registered already, if not then register one.
3546 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3547 if( animatableProperty )
3549 componentIndex = animatableProperty->componentIndex;
3556 case Dali::Actor::Property::PARENT_ORIGIN_X:
3557 case Dali::Actor::Property::ANCHOR_POINT_X:
3558 case Dali::Actor::Property::SIZE_WIDTH:
3559 case Dali::Actor::Property::POSITION_X:
3560 case Dali::Actor::Property::WORLD_POSITION_X:
3561 case Dali::Actor::Property::SCALE_X:
3562 case Dali::Actor::Property::COLOR_RED:
3568 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3569 case Dali::Actor::Property::ANCHOR_POINT_Y:
3570 case Dali::Actor::Property::SIZE_HEIGHT:
3571 case Dali::Actor::Property::POSITION_Y:
3572 case Dali::Actor::Property::WORLD_POSITION_Y:
3573 case Dali::Actor::Property::SCALE_Y:
3574 case Dali::Actor::Property::COLOR_GREEN:
3580 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3581 case Dali::Actor::Property::ANCHOR_POINT_Z:
3582 case Dali::Actor::Property::SIZE_DEPTH:
3583 case Dali::Actor::Property::POSITION_Z:
3584 case Dali::Actor::Property::WORLD_POSITION_Z:
3585 case Dali::Actor::Property::SCALE_Z:
3586 case Dali::Actor::Property::COLOR_BLUE:
3592 case Dali::Actor::Property::COLOR_ALPHA:
3606 return componentIndex;
3609 void Actor::SetParent( Actor* parent )
3613 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3617 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3620 // Instruct each actor to create a corresponding node in the scene graph
3621 ConnectToStage( parent->GetHierarchyDepth() );
3624 // Resolve the name and index for the child properties if any
3625 ResolveChildProperties();
3627 else // parent being set to NULL
3629 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3633 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3636 DALI_ASSERT_ALWAYS( mNode != NULL );
3640 // Disconnect the Node & its children from the scene-graph.
3641 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3644 // Instruct each actor to discard pointers to the scene-graph
3645 DisconnectFromStage();
3650 SceneGraph::Node* Actor::CreateNode() const
3655 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3658 Actor* actor = dynamic_cast< Actor* >( object );
3662 if( 0 == actionName.compare( ACTION_SHOW ) )
3664 actor->SetVisible( true );
3667 else if( 0 == actionName.compare( ACTION_HIDE ) )
3669 actor->SetVisible( false );
3677 void Actor::EnsureRelayoutData()
3679 // Assign relayout data.
3680 if( !mRelayoutData )
3682 mRelayoutData = new RelayoutData();
3686 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3688 // Check if actor is dependent on parent
3689 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3691 if( ( dimension & ( 1 << i ) ) )
3693 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3694 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3704 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3706 // Check if actor is dependent on children
3707 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3709 if( ( dimension & ( 1 << i ) ) )
3711 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3712 switch( resizePolicy )
3714 case ResizePolicy::FIT_TO_CHILDREN:
3715 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3731 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3733 return Actor::RelayoutDependentOnChildren( dimension );
3736 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3738 // Check each possible dimension and see if it is dependent on the input one
3739 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3741 if( dimension & ( 1 << i ) )
3743 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3750 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3752 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3754 if( dimension & ( 1 << i ) )
3756 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3761 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3763 // If more than one dimension is requested, just return the first one found
3764 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3766 if( ( dimension & ( 1 << i ) ) )
3768 return mRelayoutData->negotiatedDimensions[ i ];
3772 return 0.0f; // Default
3775 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3777 EnsureRelayoutData();
3779 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3781 if( dimension & ( 1 << i ) )
3783 mRelayoutData->dimensionPadding[ i ] = padding;
3788 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3790 if ( mRelayoutData )
3792 // If more than one dimension is requested, just return the first one found
3793 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3795 if( ( dimension & ( 1 << i ) ) )
3797 return mRelayoutData->dimensionPadding[ i ];
3802 return GetDefaultDimensionPadding();
3805 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3807 EnsureRelayoutData();
3809 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3811 if( dimension & ( 1 << i ) )
3813 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3818 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3820 if ( mRelayoutData )
3822 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3824 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3834 float Actor::GetHeightForWidthBase( float width )
3836 float height = 0.0f;
3838 const Vector3 naturalSize = GetNaturalSize();
3839 if( naturalSize.width > 0.0f )
3841 height = naturalSize.height * width / naturalSize.width;
3843 else // we treat 0 as 1:1 aspect ratio
3851 float Actor::GetWidthForHeightBase( float height )
3855 const Vector3 naturalSize = GetNaturalSize();
3856 if( naturalSize.height > 0.0f )
3858 width = naturalSize.width * height / naturalSize.height;
3860 else // we treat 0 as 1:1 aspect ratio
3868 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3870 // Fill to parent, taking size mode factor into account
3871 switch( child.GetResizePolicy( dimension ) )
3873 case ResizePolicy::FILL_TO_PARENT:
3875 return GetLatestSize( dimension );
3878 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3880 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3883 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3885 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3890 return GetLatestSize( dimension );
3895 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3897 // Can be overridden in derived class
3898 return CalculateChildSizeBase( child, dimension );
3901 float Actor::GetHeightForWidth( float width )
3903 // Can be overridden in derived class
3904 return GetHeightForWidthBase( width );
3907 float Actor::GetWidthForHeight( float height )
3909 // Can be overridden in derived class
3910 return GetWidthForHeightBase( height );
3913 float Actor::GetLatestSize( Dimension::Type dimension ) const
3915 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3918 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3920 Vector2 padding = GetPadding( dimension );
3922 return GetLatestSize( dimension ) + padding.x + padding.y;
3925 float Actor::NegotiateFromParent( Dimension::Type dimension )
3927 Actor* parent = GetParent();
3930 Vector2 padding( GetPadding( dimension ) );
3931 Vector2 parentPadding( parent->GetPadding( dimension ) );
3932 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3938 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3940 float maxDimensionPoint = 0.0f;
3942 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3944 ActorPtr child = GetChildAt( i );
3946 if( !child->RelayoutDependentOnParent( dimension ) )
3948 // Calculate the min and max points that the children range across
3949 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3950 float dimensionSize = child->GetRelayoutSize( dimension );
3951 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3955 return maxDimensionPoint;
3958 float Actor::GetSize( Dimension::Type dimension ) const
3960 return GetDimensionValue( GetTargetSize(), dimension );
3963 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3965 return GetDimensionValue( GetNaturalSize(), dimension );
3968 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3970 switch( GetResizePolicy( dimension ) )
3972 case ResizePolicy::USE_NATURAL_SIZE:
3974 return GetNaturalSize( dimension );
3977 case ResizePolicy::FIXED:
3979 return GetDimensionValue( GetPreferredSize(), dimension );
3982 case ResizePolicy::USE_ASSIGNED_SIZE:
3984 return GetDimensionValue( maximumSize, dimension );
3987 case ResizePolicy::FILL_TO_PARENT:
3988 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3989 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3991 return NegotiateFromParent( dimension );
3994 case ResizePolicy::FIT_TO_CHILDREN:
3996 return NegotiateFromChildren( dimension );
3999 case ResizePolicy::DIMENSION_DEPENDENCY:
4001 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4004 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4006 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4009 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4011 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4023 return 0.0f; // Default
4026 float Actor::ClampDimension( float size, Dimension::Type dimension )
4028 const float minSize = GetMinimumSize( dimension );
4029 const float maxSize = GetMaximumSize( dimension );
4031 return std::max( minSize, std::min( size, maxSize ) );
4034 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4036 // Check if it needs to be negotiated
4037 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4039 // Check that we havn't gotten into an infinite loop
4040 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4041 bool recursionFound = false;
4042 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4044 if( *it == searchActor )
4046 recursionFound = true;
4051 if( !recursionFound )
4053 // Record the path that we have taken
4054 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4056 // Dimension dependency check
4057 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4059 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4061 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4063 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4067 // Parent dependency check
4068 Actor* parent = GetParent();
4069 if( parent && RelayoutDependentOnParent( dimension ) )
4071 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4074 // Children dependency check
4075 if( RelayoutDependentOnChildren( dimension ) )
4077 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4079 ActorPtr child = GetChildAt( i );
4081 // Only relayout child first if it is not dependent on this actor
4082 if( !child->RelayoutDependentOnParent( dimension ) )
4084 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4089 // For deriving classes
4090 OnCalculateRelayoutSize( dimension );
4092 // All dependencies checked, calculate the size and set negotiated flag
4093 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4095 SetNegotiatedDimension( newSize, dimension );
4096 SetLayoutNegotiated( true, dimension );
4098 // For deriving classes
4099 OnLayoutNegotiated( newSize, dimension );
4101 // This actor has been successfully processed, pop it off the recursion stack
4102 recursionStack.pop_back();
4106 // TODO: Break infinite loop
4107 SetLayoutNegotiated( true, dimension );
4112 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4114 // Negotiate all dimensions that require it
4115 ActorDimensionStack recursionStack;
4117 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4119 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4122 NegotiateDimension( dimension, allocatedSize, recursionStack );
4126 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4128 switch( mRelayoutData->sizeSetPolicy )
4130 case SizeScalePolicy::USE_SIZE_SET:
4135 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4137 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4138 const Vector3 naturalSize = GetNaturalSize();
4139 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4141 const float sizeRatio = size.width / size.height;
4142 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4144 if( naturalSizeRatio < sizeRatio )
4146 return Vector2( naturalSizeRatio * size.height, size.height );
4148 else if( naturalSizeRatio > sizeRatio )
4150 return Vector2( size.width, size.width / naturalSizeRatio );
4161 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4163 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4164 const Vector3 naturalSize = GetNaturalSize();
4165 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4167 const float sizeRatio = size.width / size.height;
4168 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4170 if( naturalSizeRatio < sizeRatio )
4172 return Vector2( size.width, size.width / naturalSizeRatio );
4174 else if( naturalSizeRatio > sizeRatio )
4176 return Vector2( naturalSizeRatio * size.height, size.height );
4195 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4197 // Do the set actor size
4198 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4200 // Adjust for size set policy
4201 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4203 // Lock the flag to stop recursive relayouts on set size
4204 mRelayoutData->insideRelayout = true;
4205 SetSize( negotiatedSize );
4206 mRelayoutData->insideRelayout = false;
4208 // Clear flags for all dimensions
4209 SetLayoutDirty( false );
4211 // Give deriving classes a chance to respond
4212 OnRelayout( negotiatedSize, container );
4214 if( !mOnRelayoutSignal.Empty() )
4216 Dali::Actor handle( this );
4217 mOnRelayoutSignal.Emit( handle );
4221 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4223 // Force a size negotiation for actors that has assigned size during relayout
4224 // This is required as otherwise the flags that force a relayout will not
4225 // necessarilly be set. This will occur if the actor has already been laid out.
4226 // The dirty flags are then cleared. Then if the actor is added back into the
4227 // relayout container afterwards, the dirty flags would still be clear...
4228 // causing a relayout to be skipped. Here we force any actors added to the
4229 // container to be relayed out.
4230 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4232 SetLayoutNegotiated(false, Dimension::WIDTH);
4234 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4236 SetLayoutNegotiated(false, Dimension::HEIGHT);
4239 // Do the negotiation
4240 NegotiateDimensions( allocatedSize );
4242 // Set the actor size
4243 SetNegotiatedSize( container );
4245 // Negotiate down to children
4246 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4248 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4250 ActorPtr child = GetChildAt( i );
4252 // Forces children that have already been laid out to be relayed out
4253 // if they have assigned size during relayout.
4254 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4256 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4257 child->SetLayoutDirty(true, Dimension::WIDTH);
4259 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4261 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4262 child->SetLayoutDirty(true, Dimension::HEIGHT);
4265 // Only relayout if required
4266 if( child->RelayoutRequired() )
4268 container.Add( Dali::Actor( child.Get() ), newBounds );
4273 void Actor::RelayoutRequest( Dimension::Type dimension )
4275 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4276 if( relayoutController )
4278 Dali::Actor self( this );
4279 relayoutController->RequestRelayout( self, dimension );
4283 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4287 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4291 void Actor::SetPreferredSize( const Vector2& size )
4293 EnsureRelayoutData();
4295 if( size.width > 0.0f )
4297 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4300 if( size.height > 0.0f )
4302 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4305 mRelayoutData->preferredSize = size;
4310 Vector2 Actor::GetPreferredSize() const
4312 if ( mRelayoutData )
4314 return Vector2( mRelayoutData->preferredSize );
4317 return GetDefaultPreferredSize();
4320 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4322 EnsureRelayoutData();
4324 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4326 if( dimension & ( 1 << i ) )
4328 mRelayoutData->minimumSize[ i ] = size;
4335 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4337 if ( mRelayoutData )
4339 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4341 if( dimension & ( 1 << i ) )
4343 return mRelayoutData->minimumSize[ i ];
4348 return 0.0f; // Default
4351 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4353 EnsureRelayoutData();
4355 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4357 if( dimension & ( 1 << i ) )
4359 mRelayoutData->maximumSize[ i ] = size;
4366 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4368 if ( mRelayoutData )
4370 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4372 if( dimension & ( 1 << i ) )
4374 return mRelayoutData->maximumSize[ i ];
4379 return FLT_MAX; // Default
4382 Object* Actor::GetParentObject() const
4387 } // namespace Internal