2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/common/animatable-property.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/nodes/node-declarations.h>
51 #include <dali/internal/update/animation/scene-graph-constraint.h>
52 #include <dali/internal/event/events/actor-gesture-data.h>
53 #include <dali/internal/common/message.h>
54 #include <dali/integration-api/debug.h>
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::PropertyBase;
66 unsigned int Actor::mActorCounter = 0;
70 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
71 inline const Vector3& GetDefaultSizeModeFactor()
76 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
77 inline const Vector2& GetDefaultPreferredSize()
82 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
83 inline const Vector2& GetDefaultDimensionPadding()
88 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
90 } // unnamed namespace
93 * Struct to collect relayout variables
95 struct Actor::RelayoutData
98 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
100 // Set size negotiation defaults
101 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
103 resizePolicies[ i ] = ResizePolicy::DEFAULT;
104 negotiatedDimensions[ i ] = 0.0f;
105 dimensionNegotiated[ i ] = false;
106 dimensionDirty[ i ] = false;
107 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
108 dimensionPadding[ i ] = GetDefaultDimensionPadding();
109 minimumSize[ i ] = 0.0f;
110 maximumSize[ i ] = FLT_MAX;
114 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
116 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
118 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
120 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
122 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
123 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
125 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
126 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
128 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
130 Vector2 preferredSize; ///< The preferred size of the actor
132 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
134 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
135 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
138 namespace // unnamed namespace
144 * We want to discourage the use of property strings (minimize string comparisons),
145 * particularly for the default properties.
146 * Name Type writable animatable constraint-input enum for index-checking
148 DALI_PROPERTY_TABLE_BEGIN
149 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
150 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
151 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
152 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
153 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
154 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
155 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
156 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
157 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
158 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
159 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
160 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
161 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
162 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
163 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
164 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
165 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
166 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
167 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
168 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
169 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
170 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
171 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
172 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
173 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
174 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
175 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
176 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
177 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
178 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
179 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
180 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
181 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
182 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
183 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
184 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
185 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
186 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
187 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
188 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
189 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
190 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
191 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
192 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
193 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
194 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
195 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
196 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
197 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
198 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
199 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
200 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
201 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
202 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
203 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
204 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
205 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
209 const char* const SIGNAL_TOUCHED = "touched";
210 const char* const SIGNAL_HOVERED = "hovered";
211 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
212 const char* const SIGNAL_ON_STAGE = "onStage";
213 const char* const SIGNAL_OFF_STAGE = "offStage";
214 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
215 const char* const SIGNAL_TOUCH = "touch";
219 const char* const ACTION_SHOW = "show";
220 const char* const ACTION_HIDE = "hide";
222 BaseHandle CreateActor()
224 return Dali::Actor::New();
227 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
229 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
232 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
233 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
234 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
235 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
237 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
238 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
243 const Vector3& value;
246 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
252 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
253 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
254 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
255 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
256 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
258 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
259 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
260 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
261 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
262 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
263 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
265 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
266 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
267 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
268 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
269 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
270 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
272 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
276 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
278 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
287 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
289 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
293 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
295 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
298 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
301 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
303 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
305 size_t sizeIgnored = 0;
306 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
308 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
315 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
317 // Values are the same so just use the same table as anchor-point
318 return GetAnchorPointConstant( value, parentOrigin );
322 * @brief Extract a given dimension from a Vector2
324 * @param[in] values The values to extract from
325 * @param[in] dimension The dimension to extract
326 * @return Return the value for the dimension
328 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
332 case Dimension::WIDTH:
336 case Dimension::HEIGHT:
338 return values.height;
349 * @brief Extract a given dimension from a Vector3
351 * @param[in] values The values to extract from
352 * @param[in] dimension The dimension to extract
353 * @return Return the value for the dimension
355 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
357 return GetDimensionValue( values.GetVectorXY(), dimension );
360 unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder )
362 return depth * Dali::DevelLayer::ACTOR_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
365 } // unnamed namespace
367 ActorPtr Actor::New()
369 ActorPtr actor( new Actor( BASIC ) );
371 // Second-phase construction
377 const std::string& Actor::GetName() const
382 void Actor::SetName( const std::string& name )
388 // ATTENTION: string for debug purposes is not thread safe.
389 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
393 unsigned int Actor::GetId() const
398 bool Actor::OnStage() const
403 Dali::Layer Actor::GetLayer()
407 // Short-circuit for Layer derived actors
410 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
413 // Find the immediate Layer parent
414 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
416 if( parent->IsLayer() )
418 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
425 void Actor::Add( Actor& child )
427 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
428 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
432 mChildren = new ActorContainer;
435 Actor* const oldParent( child.mParent );
437 // child might already be ours
438 if( this != oldParent )
440 // if we already have parent, unparent us first
443 oldParent->Remove( child ); // This causes OnChildRemove callback
445 // Old parent may need to readjust to missing child
446 if( oldParent->RelayoutDependentOnChildren() )
448 oldParent->RelayoutRequest();
452 // Guard against Add() during previous OnChildRemove callback
455 // Do this first, since user callbacks from within SetParent() may need to remove child
456 mChildren->push_back( ActorPtr( &child ) );
458 // SetParent asserts that child can be added
459 child.SetParent( this );
461 // Notification for derived classes
464 // Only put in a relayout request if there is a suitable dependency
465 if( RelayoutDependentOnChildren() )
473 void Actor::Remove( Actor& child )
475 if( (this == &child) || (!mChildren) )
477 // no children or removing itself
483 // Find the child in mChildren, and unparent it
484 ActorIter end = mChildren->end();
485 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
487 ActorPtr actor = (*iter);
489 if( actor.Get() == &child )
491 // Keep handle for OnChildRemove notification
494 // Do this first, since user callbacks from within SetParent() may need to add the child
495 mChildren->erase( iter );
497 DALI_ASSERT_DEBUG( actor->GetParent() == this );
498 actor->SetParent( NULL );
506 // Only put in a relayout request if there is a suitable dependency
507 if( RelayoutDependentOnChildren() )
513 // Notification for derived classes
514 OnChildRemove( child );
517 void Actor::Unparent()
521 // Remove this actor from the parent. The remove will put a relayout request in for
522 // the parent if required
523 mParent->Remove( *this );
524 // mParent is now NULL!
528 unsigned int Actor::GetChildCount() const
530 return ( NULL != mChildren ) ? mChildren->size() : 0;
533 ActorPtr Actor::GetChildAt( unsigned int index ) const
535 DALI_ASSERT_ALWAYS( index < GetChildCount() );
537 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
540 ActorPtr Actor::FindChildByName( const std::string& actorName )
543 if( actorName == mName )
549 ActorIter end = mChildren->end();
550 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
552 child = (*iter)->FindChildByName( actorName );
563 ActorPtr Actor::FindChildById( const unsigned int id )
572 ActorIter end = mChildren->end();
573 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
575 child = (*iter)->FindChildById( id );
586 void Actor::SetParentOrigin( const Vector3& origin )
590 // mNode is being used in a separate thread; queue a message to set the value & base value
591 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
594 // Cache for event-thread access
597 // not allocated, check if different from default
598 if( ParentOrigin::DEFAULT != origin )
600 mParentOrigin = new Vector3( origin );
605 // check if different from current costs more than just set
606 *mParentOrigin = origin;
610 void Actor::SetParentOriginX( float x )
612 const Vector3& current = GetCurrentParentOrigin();
614 SetParentOrigin( Vector3( x, current.y, current.z ) );
617 void Actor::SetParentOriginY( float y )
619 const Vector3& current = GetCurrentParentOrigin();
621 SetParentOrigin( Vector3( current.x, y, current.z ) );
624 void Actor::SetParentOriginZ( float z )
626 const Vector3& current = GetCurrentParentOrigin();
628 SetParentOrigin( Vector3( current.x, current.y, z ) );
631 const Vector3& Actor::GetCurrentParentOrigin() const
633 // Cached for event-thread access
634 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
637 void Actor::SetAnchorPoint( const Vector3& anchor )
641 // mNode is being used in a separate thread; queue a message to set the value & base value
642 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
645 // Cache for event-thread access
648 // not allocated, check if different from default
649 if( AnchorPoint::DEFAULT != anchor )
651 mAnchorPoint = new Vector3( anchor );
656 // check if different from current costs more than just set
657 *mAnchorPoint = anchor;
661 void Actor::SetAnchorPointX( float x )
663 const Vector3& current = GetCurrentAnchorPoint();
665 SetAnchorPoint( Vector3( x, current.y, current.z ) );
668 void Actor::SetAnchorPointY( float y )
670 const Vector3& current = GetCurrentAnchorPoint();
672 SetAnchorPoint( Vector3( current.x, y, current.z ) );
675 void Actor::SetAnchorPointZ( float z )
677 const Vector3& current = GetCurrentAnchorPoint();
679 SetAnchorPoint( Vector3( current.x, current.y, z ) );
682 const Vector3& Actor::GetCurrentAnchorPoint() const
684 // Cached for event-thread access
685 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
688 void Actor::SetPosition( float x, float y )
690 SetPosition( Vector3( x, y, 0.0f ) );
693 void Actor::SetPosition( float x, float y, float z )
695 SetPosition( Vector3( x, y, z ) );
698 void Actor::SetPosition( const Vector3& position )
700 mTargetPosition = position;
704 // mNode is being used in a separate thread; queue a message to set the value & base value
705 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
709 void Actor::SetX( float x )
711 mTargetPosition.x = x;
715 // mNode is being used in a separate thread; queue a message to set the value & base value
716 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
720 void Actor::SetY( float y )
722 mTargetPosition.y = y;
726 // mNode is being used in a separate thread; queue a message to set the value & base value
727 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
731 void Actor::SetZ( float z )
733 mTargetPosition.z = z;
737 // mNode is being used in a separate thread; queue a message to set the value & base value
738 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
742 void Actor::TranslateBy( const Vector3& distance )
744 mTargetPosition += distance;
748 // mNode is being used in a separate thread; queue a message to set the value & base value
749 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
753 const Vector3& Actor::GetCurrentPosition() const
757 // mNode is being used in a separate thread; copy the value from the previous update
758 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
761 return Vector3::ZERO;
764 const Vector3& Actor::GetTargetPosition() const
766 return mTargetPosition;
769 const Vector3& Actor::GetCurrentWorldPosition() const
773 // mNode is being used in a separate thread; copy the value from the previous update
774 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
777 return Vector3::ZERO;
780 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
782 // this flag is not animatable so keep the value
783 mPositionInheritanceMode = mode;
786 // mNode is being used in a separate thread; queue a message to set the value
787 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
791 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
793 // Cached for event-thread access
794 return mPositionInheritanceMode;
797 void Actor::SetInheritPosition( bool inherit )
799 if( mInheritPosition != inherit && NULL != mNode )
801 // non animateable so keep local copy
802 mInheritPosition = inherit;
803 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
807 bool Actor::IsPositionInherited() const
809 return mInheritPosition;
812 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
814 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
815 normalizedAxis.Normalize();
817 Quaternion orientation( angle, normalizedAxis );
819 SetOrientation( orientation );
822 void Actor::SetOrientation( const Quaternion& orientation )
826 // mNode is being used in a separate thread; queue a message to set the value & base value
827 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
831 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
835 // mNode is being used in a separate thread; queue a message to set the value & base value
836 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
840 void Actor::RotateBy( const Quaternion& relativeRotation )
844 // mNode is being used in a separate thread; queue a message to set the value & base value
845 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
849 const Quaternion& Actor::GetCurrentOrientation() const
853 // mNode is being used in a separate thread; copy the value from the previous update
854 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
857 return Quaternion::IDENTITY;
860 const Quaternion& Actor::GetCurrentWorldOrientation() const
864 // mNode is being used in a separate thread; copy the value from the previous update
865 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
868 return Quaternion::IDENTITY;
871 void Actor::SetScale( float scale )
873 SetScale( Vector3( scale, scale, scale ) );
876 void Actor::SetScale( float x, float y, float z )
878 SetScale( Vector3( x, y, z ) );
881 void Actor::SetScale( const Vector3& scale )
885 // mNode is being used in a separate thread; queue a message to set the value & base value
886 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
890 void Actor::SetScaleX( float x )
894 // mNode is being used in a separate thread; queue a message to set the value & base value
895 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
899 void Actor::SetScaleY( float y )
903 // mNode is being used in a separate thread; queue a message to set the value & base value
904 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
908 void Actor::SetScaleZ( float z )
912 // mNode is being used in a separate thread; queue a message to set the value & base value
913 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
917 void Actor::ScaleBy(const Vector3& relativeScale)
921 // mNode is being used in a separate thread; queue a message to set the value & base value
922 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
926 const Vector3& Actor::GetCurrentScale() const
930 // mNode is being used in a separate thread; copy the value from the previous update
931 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
937 const Vector3& Actor::GetCurrentWorldScale() const
941 // mNode is being used in a separate thread; copy the value from the previous update
942 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
948 void Actor::SetInheritScale( bool inherit )
951 if( mInheritScale != inherit && NULL != mNode )
953 // non animateable so keep local copy
954 mInheritScale = inherit;
955 // mNode is being used in a separate thread; queue a message to set the value
956 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
960 bool Actor::IsScaleInherited() const
962 return mInheritScale;
965 Matrix Actor::GetCurrentWorldMatrix() const
969 return mNode->GetWorldMatrix(0);
972 return Matrix::IDENTITY;
975 void Actor::SetVisible( bool visible )
979 // mNode is being used in a separate thread; queue a message to set the value & base value
980 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
984 bool Actor::IsVisible() const
988 // mNode is being used in a separate thread; copy the value from the previous update
989 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
995 void Actor::SetOpacity( float opacity )
999 // mNode is being used in a separate thread; queue a message to set the value & base value
1000 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1004 float Actor::GetCurrentOpacity() const
1008 // mNode is being used in a separate thread; copy the value from the previous update
1009 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1015 ClippingMode::Type Actor::GetClippingMode() const
1017 return mClippingMode;
1020 unsigned int Actor::GetSortingDepth()
1022 return GetDepthIndex( mDepth, mSiblingOrder );
1025 const Vector4& Actor::GetCurrentWorldColor() const
1029 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1032 return Color::WHITE;
1035 void Actor::SetColor( const Vector4& color )
1039 // mNode is being used in a separate thread; queue a message to set the value & base value
1040 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1044 void Actor::SetColorRed( float red )
1048 // mNode is being used in a separate thread; queue a message to set the value & base value
1049 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1053 void Actor::SetColorGreen( float green )
1057 // mNode is being used in a separate thread; queue a message to set the value & base value
1058 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1062 void Actor::SetColorBlue( float blue )
1066 // mNode is being used in a separate thread; queue a message to set the value & base value
1067 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1071 const Vector4& Actor::GetCurrentColor() const
1075 // mNode is being used in a separate thread; copy the value from the previous update
1076 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1079 return Color::WHITE;
1082 void Actor::SetInheritOrientation( bool inherit )
1084 if( mInheritOrientation != inherit && NULL != mNode)
1086 // non animateable so keep local copy
1087 mInheritOrientation = inherit;
1088 // mNode is being used in a separate thread; queue a message to set the value
1089 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1093 bool Actor::IsOrientationInherited() const
1095 return mInheritOrientation;
1098 void Actor::SetSizeModeFactor( const Vector3& factor )
1100 EnsureRelayoutData();
1102 mRelayoutData->sizeModeFactor = factor;
1105 const Vector3& Actor::GetSizeModeFactor() const
1107 if ( mRelayoutData )
1109 return mRelayoutData->sizeModeFactor;
1112 return GetDefaultSizeModeFactor();
1115 void Actor::SetColorMode( ColorMode colorMode )
1117 // non animateable so keep local copy
1118 mColorMode = colorMode;
1121 // mNode is being used in a separate thread; queue a message to set the value
1122 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1126 ColorMode Actor::GetColorMode() const
1128 // we have cached copy
1132 void Actor::SetSize( float width, float height )
1134 SetSize( Vector2( width, height ) );
1137 void Actor::SetSize( float width, float height, float depth )
1139 SetSize( Vector3( width, height, depth ) );
1142 void Actor::SetSize( const Vector2& size )
1144 SetSize( Vector3( size.width, size.height, 0.f ) );
1147 void Actor::SetSizeInternal( const Vector2& size )
1149 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1152 void Actor::SetSize( const Vector3& size )
1154 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1156 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1157 SetPreferredSize( size.GetVectorXY() );
1161 SetSizeInternal( size );
1165 void Actor::SetSizeInternal( const Vector3& size )
1167 // dont allow recursive loop
1168 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1169 // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
1170 if( ( NULL != mNode )&&
1171 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1172 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1173 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1177 // mNode is being used in a separate thread; queue a message to set the value & base value
1178 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1180 // Notification for derived classes
1181 mInsideOnSizeSet = true;
1182 OnSizeSet( mTargetSize );
1183 mInsideOnSizeSet = false;
1185 // Raise a relayout request if the flag is not locked
1186 if( mRelayoutData && !mRelayoutData->insideRelayout )
1193 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1195 mTargetSize = targetSize;
1197 // Notify deriving classes
1198 OnSizeAnimation( animation, mTargetSize );
1201 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1203 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1205 mTargetSize.width = targetSize;
1207 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1209 mTargetSize.height = targetSize;
1211 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1213 mTargetSize.depth = targetSize;
1215 // Notify deriving classes
1216 OnSizeAnimation( animation, mTargetSize );
1219 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1221 mTargetPosition = targetPosition;
1224 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1226 if ( Dali::Actor::Property::POSITION_X == property )
1228 mTargetPosition.x = targetPosition;
1230 else if ( Dali::Actor::Property::POSITION_Y == property )
1232 mTargetPosition.y = targetPosition;
1234 else if ( Dali::Actor::Property::POSITION_Z == property )
1236 mTargetPosition.z = targetPosition;
1240 void Actor::SetWidth( float width )
1242 mTargetSize.width = width;
1246 // mNode is being used in a separate thread; queue a message to set the value & base value
1247 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1251 void Actor::SetHeight( float height )
1253 mTargetSize.height = height;
1257 // mNode is being used in a separate thread; queue a message to set the value & base value
1258 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1262 void Actor::SetDepth( float depth )
1264 mTargetSize.depth = depth;
1268 // mNode is being used in a separate thread; queue a message to set the value & base value
1269 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1273 const Vector3& Actor::GetTargetSize() const
1278 const Vector3& Actor::GetCurrentSize() const
1282 // mNode is being used in a separate thread; copy the value from the previous update
1283 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1286 return Vector3::ZERO;
1289 Vector3 Actor::GetNaturalSize() const
1291 // It is up to deriving classes to return the appropriate natural size
1292 return Vector3( 0.0f, 0.0f, 0.0f );
1295 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1297 EnsureRelayoutData();
1299 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1300 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1302 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1304 if( dimension & ( 1 << i ) )
1306 mRelayoutData->resizePolicies[ i ] = policy;
1310 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1312 if( dimension & Dimension::WIDTH )
1314 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1317 if( dimension & Dimension::HEIGHT )
1319 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1323 // If calling SetResizePolicy, assume we want relayout enabled
1324 SetRelayoutEnabled( true );
1326 // If the resize policy is set to be FIXED, the preferred size
1327 // should be overrided by the target size. Otherwise the target
1328 // size should be overrided by the preferred size.
1330 if( dimension & Dimension::WIDTH )
1332 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1334 mRelayoutData->preferredSize.width = mTargetSize.width;
1336 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1338 mTargetSize.width = mRelayoutData->preferredSize.width;
1342 if( dimension & Dimension::HEIGHT )
1344 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1346 mRelayoutData->preferredSize.height = mTargetSize.height;
1348 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1350 mTargetSize.height = mRelayoutData->preferredSize.height;
1354 OnSetResizePolicy( policy, dimension );
1356 // Trigger relayout on this control
1360 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1362 if ( mRelayoutData )
1364 // If more than one dimension is requested, just return the first one found
1365 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1367 if( ( dimension & ( 1 << i ) ) )
1369 return mRelayoutData->resizePolicies[ i ];
1374 return ResizePolicy::DEFAULT;
1377 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1379 EnsureRelayoutData();
1381 mRelayoutData->sizeSetPolicy = policy;
1384 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1386 if ( mRelayoutData )
1388 return mRelayoutData->sizeSetPolicy;
1391 return DEFAULT_SIZE_SCALE_POLICY;
1394 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1396 EnsureRelayoutData();
1398 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1400 if( dimension & ( 1 << i ) )
1402 mRelayoutData->dimensionDependencies[ i ] = dependency;
1407 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1409 if ( mRelayoutData )
1411 // If more than one dimension is requested, just return the first one found
1412 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1414 if( ( dimension & ( 1 << i ) ) )
1416 return mRelayoutData->dimensionDependencies[ i ];
1421 return Dimension::ALL_DIMENSIONS; // Default
1424 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1426 // If relayout data has not been allocated yet and the client is requesting
1427 // to disable it, do nothing
1428 if( mRelayoutData || relayoutEnabled )
1430 EnsureRelayoutData();
1432 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1434 mRelayoutData->relayoutEnabled = relayoutEnabled;
1438 bool Actor::IsRelayoutEnabled() const
1440 // Assume that if relayout data has not been allocated yet then
1441 // relayout is disabled
1442 return mRelayoutData && mRelayoutData->relayoutEnabled;
1445 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1447 EnsureRelayoutData();
1449 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1451 if( dimension & ( 1 << i ) )
1453 mRelayoutData->dimensionDirty[ i ] = dirty;
1458 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1460 if ( mRelayoutData )
1462 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1464 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1474 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1476 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1479 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1481 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1484 unsigned int Actor::AddRenderer( Renderer& renderer )
1488 mRenderers = new RendererContainer;
1491 unsigned int index = mRenderers->size();
1492 RendererPtr rendererPtr = RendererPtr( &renderer );
1493 mRenderers->push_back( rendererPtr );
1494 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1498 unsigned int Actor::GetRendererCount() const
1500 unsigned int rendererCount(0);
1503 rendererCount = mRenderers->size();
1506 return rendererCount;
1509 RendererPtr Actor::GetRendererAt( unsigned int index )
1511 RendererPtr renderer;
1512 if( index < GetRendererCount() )
1514 renderer = ( *mRenderers )[ index ];
1520 void Actor::RemoveRenderer( Renderer& renderer )
1524 RendererIter end = mRenderers->end();
1525 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1527 if( (*iter).Get() == &renderer )
1529 mRenderers->erase( iter );
1530 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1537 void Actor::RemoveRenderer( unsigned int index )
1539 if( index < GetRendererCount() )
1541 RendererPtr renderer = ( *mRenderers )[ index ];
1542 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1543 mRenderers->erase( mRenderers->begin()+index );
1547 bool Actor::IsOverlay() const
1549 return ( DrawMode::OVERLAY_2D == mDrawMode );
1552 void Actor::SetDrawMode( DrawMode::Type drawMode )
1554 // this flag is not animatable so keep the value
1555 mDrawMode = drawMode;
1556 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1558 // mNode is being used in a separate thread; queue a message to set the value
1559 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1563 DrawMode::Type Actor::GetDrawMode() const
1568 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1570 // only valid when on-stage
1571 StagePtr stage = Stage::GetCurrent();
1572 if( stage && OnStage() )
1574 const RenderTaskList& taskList = stage->GetRenderTaskList();
1576 Vector2 converted( screenX, screenY );
1578 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1579 const int taskCount = taskList.GetTaskCount();
1580 for( int i = taskCount - 1; i >= 0; --i )
1582 Dali::RenderTask task = taskList.GetTask( i );
1583 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1585 // found a task where this conversion was ok so return
1593 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1595 bool retval = false;
1596 // only valid when on-stage
1599 CameraActor* camera = renderTask.GetCameraActor();
1603 renderTask.GetViewport( viewport );
1605 // need to translate coordinates to render tasks coordinate space
1606 Vector2 converted( screenX, screenY );
1607 if( renderTask.TranslateCoordinates( converted ) )
1609 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1616 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1618 // Early-out if mNode is NULL
1624 // Get the ModelView matrix
1626 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1628 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1629 Matrix invertedMvp( false/*don't init*/);
1630 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1631 bool success = invertedMvp.Invert();
1633 // Convert to GL coordinates
1634 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1639 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1646 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1652 if( XyPlaneIntersect( nearPos, farPos, local ) )
1654 Vector3 size = GetCurrentSize();
1655 localX = local.x + size.x * 0.5f;
1656 localY = local.y + size.y * 0.5f;
1667 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1670 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1672 Mathematical Formulation
1674 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1676 ( p - c ) dot ( p - c ) = r^2
1678 Given a ray with a point of origin 'o', and a direction vector 'd':
1680 ray(t) = o + td, t >= 0
1682 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1684 (o + td - c ) dot ( o + td - c ) = r^2
1686 To solve for t we first expand the above into a more recognisable quadratic equation form
1688 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1697 B = 2( o - c ) dot d
1698 C = ( o - c ) dot ( o - c ) - r^2
1700 which can be solved using a standard quadratic formula.
1702 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1704 Practical Simplification
1706 In a renderer, we often differentiate between world space and object space. In the object space
1707 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1708 into object space, the mathematical solution presented above can be simplified significantly.
1710 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1714 and we can find the t at which the (transformed) ray intersects the sphere by
1716 ( o + td ) dot ( o + td ) = r^2
1718 According to the reasoning above, we expand the above quadratic equation into the general form
1722 which now has coefficients:
1729 // Early out if mNode is NULL
1735 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1737 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1738 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1739 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1741 // Compute the radius is not needed, square radius it's enough.
1742 const Vector3& size( mNode->GetSize( bufferIndex ) );
1744 // Scale the sphere.
1745 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1747 const float width = size.width * scale.width;
1748 const float height = size.height * scale.height;
1750 float squareSphereRadius = 0.5f * ( width * width + height * height );
1752 float a = rayDir.Dot( rayDir ); // a
1753 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1754 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1756 return ( b2 * b2 - a * c ) >= 0.f;
1759 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1763 if( OnStage() && NULL != mNode )
1765 // Transforms the ray to the local reference system.
1766 // Calculate the inverse of Model matrix
1767 Matrix invModelMatrix( false/*don't init*/);
1769 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1770 invModelMatrix = mNode->GetWorldMatrix(0);
1771 invModelMatrix.Invert();
1773 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1774 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1776 // Test with the actor's XY plane (Normal = 0 0 1 1).
1778 float a = -rayOriginLocal.z;
1779 float b = rayDirLocal.z;
1781 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1783 // Ray travels distance * rayDirLocal to intersect with plane.
1786 const Vector3& size = mNode->GetSize( bufferIndex );
1788 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1789 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1791 // Test with the actor's geometry.
1792 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1799 void Actor::SetLeaveRequired( bool required )
1801 mLeaveRequired = required;
1804 bool Actor::GetLeaveRequired() const
1806 return mLeaveRequired;
1809 void Actor::SetKeyboardFocusable( bool focusable )
1811 mKeyboardFocusable = focusable;
1814 bool Actor::IsKeyboardFocusable() const
1816 return mKeyboardFocusable;
1819 bool Actor::GetTouchRequired() const
1821 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1824 bool Actor::GetHoverRequired() const
1826 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1829 bool Actor::GetWheelEventRequired() const
1831 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1834 bool Actor::IsHittable() const
1836 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1839 ActorGestureData& Actor::GetGestureData()
1841 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1842 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1843 if( NULL == mGestureData )
1845 mGestureData = new ActorGestureData;
1847 return *mGestureData;
1850 bool Actor::IsGestureRequred( Gesture::Type type ) const
1852 return mGestureData && mGestureData->IsGestureRequred( type );
1855 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1857 bool consumed = false;
1859 if( !mTouchSignal.Empty() )
1861 Dali::Actor handle( this );
1862 consumed = mTouchSignal.Emit( handle, touch );
1865 if( !mTouchedSignal.Empty() )
1867 Dali::Actor handle( this );
1868 consumed |= mTouchedSignal.Emit( handle, event );
1873 // Notification for derived classes
1874 consumed = OnTouchEvent( event ); // TODO
1880 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1882 bool consumed = false;
1884 if( !mHoveredSignal.Empty() )
1886 Dali::Actor handle( this );
1887 consumed = mHoveredSignal.Emit( handle, event );
1892 // Notification for derived classes
1893 consumed = OnHoverEvent( event );
1899 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1901 bool consumed = false;
1903 if( !mWheelEventSignal.Empty() )
1905 Dali::Actor handle( this );
1906 consumed = mWheelEventSignal.Emit( handle, event );
1911 // Notification for derived classes
1912 consumed = OnWheelEvent( event );
1918 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1920 return mTouchedSignal;
1923 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1925 return mTouchSignal;
1928 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1930 return mHoveredSignal;
1933 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1935 return mWheelEventSignal;
1938 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1940 return mOnStageSignal;
1943 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1945 return mOffStageSignal;
1948 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1950 return mOnRelayoutSignal;
1953 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1955 bool connected( true );
1956 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1958 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1960 actor->TouchedSignal().Connect( tracker, functor );
1962 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1964 actor->HoveredSignal().Connect( tracker, functor );
1966 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1968 actor->WheelEventSignal().Connect( tracker, functor );
1970 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1972 actor->OnStageSignal().Connect( tracker, functor );
1974 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1976 actor->OffStageSignal().Connect( tracker, functor );
1978 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1980 actor->OnRelayoutSignal().Connect( tracker, functor );
1982 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1984 actor->TouchSignal().Connect( tracker, functor );
1988 // signalName does not match any signal
1995 Actor::Actor( DerivedType derivedType )
2000 mParentOrigin( NULL ),
2001 mAnchorPoint( NULL ),
2002 mRelayoutData( NULL ),
2003 mGestureData( NULL ),
2004 mTargetSize( 0.0f, 0.0f, 0.0f ),
2006 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2009 mIsRoot( ROOT_LAYER == derivedType ),
2010 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2011 mIsOnStage( false ),
2013 mLeaveRequired( false ),
2014 mKeyboardFocusable( false ),
2015 mDerivedRequiresTouch( false ),
2016 mDerivedRequiresHover( false ),
2017 mDerivedRequiresWheelEvent( false ),
2018 mOnStageSignalled( false ),
2019 mInsideOnSizeSet( false ),
2020 mInheritPosition( true ),
2021 mInheritOrientation( true ),
2022 mInheritScale( true ),
2023 mDrawMode( DrawMode::NORMAL ),
2024 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2025 mColorMode( Node::DEFAULT_COLOR_MODE ),
2026 mClippingMode( ClippingMode::DISABLED )
2030 void Actor::Initialize()
2033 SceneGraph::Node* node = CreateNode();
2035 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2036 mNode = node; // Keep raw-pointer to Node
2040 GetEventThreadServices().RegisterObject( this );
2045 // Remove mParent pointers from children even if we're destroying core,
2046 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2049 ActorConstIter endIter = mChildren->end();
2050 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2052 (*iter)->SetParent( NULL );
2058 // Guard to allow handle destruction after Core has been destroyed
2059 if( EventThreadServices::IsCoreRunning() )
2063 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2064 mNode = NULL; // Node is about to be destroyed
2067 GetEventThreadServices().UnregisterObject( this );
2070 // Cleanup optional gesture data
2071 delete mGestureData;
2073 // Cleanup optional parent origin and anchor
2074 delete mParentOrigin;
2075 delete mAnchorPoint;
2077 // Delete optional relayout data
2080 delete mRelayoutData;
2084 void Actor::ConnectToStage( unsigned int parentDepth )
2086 // This container is used instead of walking the Actor hierarchy.
2087 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2088 ActorContainer connectionList;
2090 // This stage is atomic i.e. not interrupted by user callbacks.
2091 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2093 // Notify applications about the newly connected actors.
2094 const ActorIter endIter = connectionList.end();
2095 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2097 (*iter)->NotifyStageConnection();
2103 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2105 DALI_ASSERT_ALWAYS( !OnStage() );
2109 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2111 ConnectToSceneGraph();
2113 // Notification for internal derived classes
2114 OnStageConnectionInternal();
2116 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2117 connectionList.push_back( ActorPtr( this ) );
2119 // Recursively connect children
2122 ActorConstIter endIter = mChildren->end();
2123 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2125 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2131 * This method is called when the Actor is connected to the Stage.
2132 * The parent must have added its Node to the scene-graph.
2133 * The child must connect its Node to the parent's Node.
2134 * This is recursive; the child calls ConnectToStage() for its children.
2136 void Actor::ConnectToSceneGraph()
2138 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2142 // Reparent Node in next Update
2143 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2146 // Request relayout on all actors that are added to the scenegraph
2149 // Notification for Object::Observers
2153 void Actor::NotifyStageConnection()
2155 // Actors can be removed (in a callback), before the on-stage stage is reported.
2156 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2157 if( OnStage() && !mOnStageSignalled )
2159 // Notification for external (CustomActor) derived classes
2160 OnStageConnectionExternal( mDepth );
2162 if( !mOnStageSignal.Empty() )
2164 Dali::Actor handle( this );
2165 mOnStageSignal.Emit( handle );
2168 // Guard against Remove during callbacks
2171 mOnStageSignalled = true; // signal required next time Actor is removed
2176 void Actor::DisconnectFromStage()
2178 // This container is used instead of walking the Actor hierachy.
2179 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2180 ActorContainer disconnectionList;
2182 // This stage is atomic i.e. not interrupted by user callbacks
2183 RecursiveDisconnectFromStage( disconnectionList );
2185 // Notify applications about the newly disconnected actors.
2186 const ActorIter endIter = disconnectionList.end();
2187 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2189 (*iter)->NotifyStageDisconnection();
2193 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2195 DALI_ASSERT_ALWAYS( OnStage() );
2197 // Recursively disconnect children
2200 ActorConstIter endIter = mChildren->end();
2201 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2203 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2207 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2208 disconnectionList.push_back( ActorPtr( this ) );
2210 // Notification for internal derived classes
2211 OnStageDisconnectionInternal();
2213 DisconnectFromSceneGraph();
2219 * This method is called by an actor or its parent, before a node removal message is sent.
2220 * This is recursive; the child calls DisconnectFromStage() for its children.
2222 void Actor::DisconnectFromSceneGraph()
2224 // Notification for Object::Observers
2225 OnSceneObjectRemove();
2228 void Actor::NotifyStageDisconnection()
2230 // Actors can be added (in a callback), before the off-stage state is reported.
2231 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2232 // only do this step if there is a stage, i.e. Core is not being shut down
2233 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2235 // Notification for external (CustomeActor) derived classes
2236 OnStageDisconnectionExternal();
2238 if( !mOffStageSignal.Empty() )
2240 Dali::Actor handle( this );
2241 mOffStageSignal.Emit( handle );
2244 // Guard against Add during callbacks
2247 mOnStageSignalled = false; // signal required next time Actor is added
2252 bool Actor::IsNodeConnected() const
2254 bool connected( false );
2256 if( OnStage() && ( NULL != mNode ) )
2258 if( IsRoot() || mNode->GetParent() )
2267 unsigned int Actor::GetDefaultPropertyCount() const
2269 return DEFAULT_PROPERTY_COUNT;
2272 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2274 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2276 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2278 indices.PushBack( i );
2282 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2284 if( index < DEFAULT_PROPERTY_COUNT )
2286 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2292 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2294 Property::Index index = Property::INVALID_INDEX;
2296 // Look for name in default properties
2297 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2299 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2300 if( 0 == name.compare( property->name ) )
2310 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2312 if( index < DEFAULT_PROPERTY_COUNT )
2314 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2320 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2322 if( index < DEFAULT_PROPERTY_COUNT )
2324 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2330 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2332 if( index < DEFAULT_PROPERTY_COUNT )
2334 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2340 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2342 if( index < DEFAULT_PROPERTY_COUNT )
2344 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2347 // index out of range...return Property::NONE
2348 return Property::NONE;
2351 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2355 case Dali::Actor::Property::PARENT_ORIGIN:
2357 Property::Type type = property.GetType();
2358 if( type == Property::VECTOR3 )
2360 SetParentOrigin( property.Get< Vector3 >() );
2362 else if ( type == Property::STRING )
2364 std::string parentOriginString;
2365 property.Get( parentOriginString );
2366 Vector3 parentOrigin;
2367 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2369 SetParentOrigin( parentOrigin );
2375 case Dali::Actor::Property::PARENT_ORIGIN_X:
2377 SetParentOriginX( property.Get< float >() );
2381 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2383 SetParentOriginY( property.Get< float >() );
2387 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2389 SetParentOriginZ( property.Get< float >() );
2393 case Dali::Actor::Property::ANCHOR_POINT:
2395 Property::Type type = property.GetType();
2396 if( type == Property::VECTOR3 )
2398 SetAnchorPoint( property.Get< Vector3 >() );
2400 else if ( type == Property::STRING )
2402 std::string anchorPointString;
2403 property.Get( anchorPointString );
2405 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2407 SetAnchorPoint( anchor );
2413 case Dali::Actor::Property::ANCHOR_POINT_X:
2415 SetAnchorPointX( property.Get< float >() );
2419 case Dali::Actor::Property::ANCHOR_POINT_Y:
2421 SetAnchorPointY( property.Get< float >() );
2425 case Dali::Actor::Property::ANCHOR_POINT_Z:
2427 SetAnchorPointZ( property.Get< float >() );
2431 case Dali::Actor::Property::SIZE:
2433 SetSize( property.Get< Vector3 >() );
2437 case Dali::Actor::Property::SIZE_WIDTH:
2439 SetWidth( property.Get< float >() );
2443 case Dali::Actor::Property::SIZE_HEIGHT:
2445 SetHeight( property.Get< float >() );
2449 case Dali::Actor::Property::SIZE_DEPTH:
2451 SetDepth( property.Get< float >() );
2455 case Dali::Actor::Property::POSITION:
2457 SetPosition( property.Get< Vector3 >() );
2461 case Dali::Actor::Property::POSITION_X:
2463 SetX( property.Get< float >() );
2467 case Dali::Actor::Property::POSITION_Y:
2469 SetY( property.Get< float >() );
2473 case Dali::Actor::Property::POSITION_Z:
2475 SetZ( property.Get< float >() );
2479 case Dali::Actor::Property::ORIENTATION:
2481 SetOrientation( property.Get< Quaternion >() );
2485 case Dali::Actor::Property::SCALE:
2487 SetScale( property.Get< Vector3 >() );
2491 case Dali::Actor::Property::SCALE_X:
2493 SetScaleX( property.Get< float >() );
2497 case Dali::Actor::Property::SCALE_Y:
2499 SetScaleY( property.Get< float >() );
2503 case Dali::Actor::Property::SCALE_Z:
2505 SetScaleZ( property.Get< float >() );
2509 case Dali::Actor::Property::VISIBLE:
2511 SetVisible( property.Get< bool >() );
2515 case Dali::Actor::Property::COLOR:
2517 SetColor( property.Get< Vector4 >() );
2521 case Dali::Actor::Property::COLOR_RED:
2523 SetColorRed( property.Get< float >() );
2527 case Dali::Actor::Property::COLOR_GREEN:
2529 SetColorGreen( property.Get< float >() );
2533 case Dali::Actor::Property::COLOR_BLUE:
2535 SetColorBlue( property.Get< float >() );
2539 case Dali::Actor::Property::COLOR_ALPHA:
2540 case Dali::DevelActor::Property::OPACITY:
2543 if( property.Get( value ) )
2545 SetOpacity( value );
2550 case Dali::Actor::Property::NAME:
2552 SetName( property.Get< std::string >() );
2556 case Dali::Actor::Property::SENSITIVE:
2558 SetSensitive( property.Get< bool >() );
2562 case Dali::Actor::Property::LEAVE_REQUIRED:
2564 SetLeaveRequired( property.Get< bool >() );
2568 case Dali::Actor::Property::INHERIT_POSITION:
2570 SetInheritPosition( property.Get< bool >() );
2574 case Dali::Actor::Property::INHERIT_ORIENTATION:
2576 SetInheritOrientation( property.Get< bool >() );
2580 case Dali::Actor::Property::INHERIT_SCALE:
2582 SetInheritScale( property.Get< bool >() );
2586 case Dali::Actor::Property::COLOR_MODE:
2588 ColorMode mode = mColorMode;
2589 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2591 SetColorMode( mode );
2596 case Dali::Actor::Property::POSITION_INHERITANCE:
2598 PositionInheritanceMode mode = mPositionInheritanceMode;
2599 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2601 SetPositionInheritanceMode( mode );
2606 case Dali::Actor::Property::DRAW_MODE:
2608 DrawMode::Type mode = mDrawMode;
2609 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2611 SetDrawMode( mode );
2616 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2618 SetSizeModeFactor( property.Get< Vector3 >() );
2622 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2624 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2625 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2627 SetResizePolicy( type, Dimension::WIDTH );
2632 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2634 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2635 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2637 SetResizePolicy( type, Dimension::HEIGHT );
2642 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2644 SizeScalePolicy::Type type;
2645 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2647 SetSizeScalePolicy( type );
2652 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2654 if( property.Get< bool >() )
2656 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2661 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2663 if( property.Get< bool >() )
2665 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2670 case Dali::Actor::Property::PADDING:
2672 Vector4 padding = property.Get< Vector4 >();
2673 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2674 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2678 case Dali::Actor::Property::MINIMUM_SIZE:
2680 Vector2 size = property.Get< Vector2 >();
2681 SetMinimumSize( size.x, Dimension::WIDTH );
2682 SetMinimumSize( size.y, Dimension::HEIGHT );
2686 case Dali::Actor::Property::MAXIMUM_SIZE:
2688 Vector2 size = property.Get< Vector2 >();
2689 SetMaximumSize( size.x, Dimension::WIDTH );
2690 SetMaximumSize( size.y, Dimension::HEIGHT );
2694 case Dali::DevelActor::Property::SIBLING_ORDER:
2698 if( property.Get( value ) )
2700 if( static_cast<unsigned int>(value) != mSiblingOrder )
2702 mSiblingOrder = value;
2705 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2712 case Dali::Actor::Property::CLIPPING_MODE:
2714 ClippingMode::Type convertedValue = mClippingMode;
2715 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2717 mClippingMode = convertedValue;
2720 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2728 // this can happen in the case of a non-animatable default property so just do nothing
2734 // TODO: This method needs to be removed
2735 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2737 switch( entry.GetType() )
2739 case Property::BOOLEAN:
2741 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2742 DALI_ASSERT_DEBUG( NULL != property );
2744 // property is being used in a separate thread; queue a message to set the property
2745 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2750 case Property::INTEGER:
2752 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2753 DALI_ASSERT_DEBUG( NULL != property );
2755 // property is being used in a separate thread; queue a message to set the property
2756 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2761 case Property::FLOAT:
2763 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2764 DALI_ASSERT_DEBUG( NULL != property );
2766 // property is being used in a separate thread; queue a message to set the property
2767 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2772 case Property::VECTOR2:
2774 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2775 DALI_ASSERT_DEBUG( NULL != property );
2777 // property is being used in a separate thread; queue a message to set the property
2778 if(entry.componentIndex == 0)
2780 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2782 else if(entry.componentIndex == 1)
2784 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2788 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2794 case Property::VECTOR3:
2796 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2797 DALI_ASSERT_DEBUG( NULL != property );
2799 // property is being used in a separate thread; queue a message to set the property
2800 if(entry.componentIndex == 0)
2802 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2804 else if(entry.componentIndex == 1)
2806 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2808 else if(entry.componentIndex == 2)
2810 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2814 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2820 case Property::VECTOR4:
2822 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2823 DALI_ASSERT_DEBUG( NULL != property );
2825 // property is being used in a separate thread; queue a message to set the property
2826 if(entry.componentIndex == 0)
2828 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2830 else if(entry.componentIndex == 1)
2832 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2834 else if(entry.componentIndex == 2)
2836 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2838 else if(entry.componentIndex == 3)
2840 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2844 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2850 case Property::ROTATION:
2852 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2853 DALI_ASSERT_DEBUG( NULL != property );
2855 // property is being used in a separate thread; queue a message to set the property
2856 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2861 case Property::MATRIX:
2863 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2864 DALI_ASSERT_DEBUG( NULL != property );
2866 // property is being used in a separate thread; queue a message to set the property
2867 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2872 case Property::MATRIX3:
2874 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2875 DALI_ASSERT_DEBUG( NULL != property );
2877 // property is being used in a separate thread; queue a message to set the property
2878 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2885 // nothing to do for other types
2890 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2892 Property::Value value;
2894 if( index >= DEFAULT_PROPERTY_COUNT )
2901 case Dali::Actor::Property::PARENT_ORIGIN:
2903 value = GetCurrentParentOrigin();
2907 case Dali::Actor::Property::PARENT_ORIGIN_X:
2909 value = GetCurrentParentOrigin().x;
2913 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2915 value = GetCurrentParentOrigin().y;
2919 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2921 value = GetCurrentParentOrigin().z;
2925 case Dali::Actor::Property::ANCHOR_POINT:
2927 value = GetCurrentAnchorPoint();
2931 case Dali::Actor::Property::ANCHOR_POINT_X:
2933 value = GetCurrentAnchorPoint().x;
2937 case Dali::Actor::Property::ANCHOR_POINT_Y:
2939 value = GetCurrentAnchorPoint().y;
2943 case Dali::Actor::Property::ANCHOR_POINT_Z:
2945 value = GetCurrentAnchorPoint().z;
2949 case Dali::Actor::Property::SIZE:
2951 Vector3 size = GetTargetSize();
2953 // Should return preferred size if size is fixed as set by SetSize
2954 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
2956 size.width = GetPreferredSize().width;
2958 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
2960 size.height = GetPreferredSize().height;
2968 case Dali::Actor::Property::SIZE_WIDTH:
2970 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
2972 // Should return preferred size if size is fixed as set by SetSize
2973 value = GetPreferredSize().width;
2977 value = GetTargetSize().width;
2982 case Dali::Actor::Property::SIZE_HEIGHT:
2984 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
2986 // Should return preferred size if size is fixed as set by SetSize
2987 value = GetPreferredSize().height;
2991 value = GetTargetSize().height;
2996 case Dali::Actor::Property::SIZE_DEPTH:
2998 value = GetTargetSize().depth;
3002 case Dali::Actor::Property::POSITION:
3004 value = GetTargetPosition();
3008 case Dali::Actor::Property::POSITION_X:
3010 value = GetTargetPosition().x;
3014 case Dali::Actor::Property::POSITION_Y:
3016 value = GetTargetPosition().y;
3020 case Dali::Actor::Property::POSITION_Z:
3022 value = GetTargetPosition().z;
3026 case Dali::Actor::Property::WORLD_POSITION:
3028 value = GetCurrentWorldPosition();
3032 case Dali::Actor::Property::WORLD_POSITION_X:
3034 value = GetCurrentWorldPosition().x;
3038 case Dali::Actor::Property::WORLD_POSITION_Y:
3040 value = GetCurrentWorldPosition().y;
3044 case Dali::Actor::Property::WORLD_POSITION_Z:
3046 value = GetCurrentWorldPosition().z;
3050 case Dali::Actor::Property::ORIENTATION:
3052 value = GetCurrentOrientation();
3056 case Dali::Actor::Property::WORLD_ORIENTATION:
3058 value = GetCurrentWorldOrientation();
3062 case Dali::Actor::Property::SCALE:
3064 value = GetCurrentScale();
3068 case Dali::Actor::Property::SCALE_X:
3070 value = GetCurrentScale().x;
3074 case Dali::Actor::Property::SCALE_Y:
3076 value = GetCurrentScale().y;
3080 case Dali::Actor::Property::SCALE_Z:
3082 value = GetCurrentScale().z;
3086 case Dali::Actor::Property::WORLD_SCALE:
3088 value = GetCurrentWorldScale();
3092 case Dali::Actor::Property::VISIBLE:
3094 value = IsVisible();
3098 case Dali::Actor::Property::COLOR:
3100 value = GetCurrentColor();
3104 case Dali::Actor::Property::COLOR_RED:
3106 value = GetCurrentColor().r;
3110 case Dali::Actor::Property::COLOR_GREEN:
3112 value = GetCurrentColor().g;
3116 case Dali::Actor::Property::COLOR_BLUE:
3118 value = GetCurrentColor().b;
3122 case Dali::Actor::Property::COLOR_ALPHA:
3123 case Dali::DevelActor::Property::OPACITY:
3125 value = GetCurrentColor().a;
3129 case Dali::Actor::Property::WORLD_COLOR:
3131 value = GetCurrentWorldColor();
3135 case Dali::Actor::Property::WORLD_MATRIX:
3137 value = GetCurrentWorldMatrix();
3141 case Dali::Actor::Property::NAME:
3147 case Dali::Actor::Property::SENSITIVE:
3149 value = IsSensitive();
3153 case Dali::Actor::Property::LEAVE_REQUIRED:
3155 value = GetLeaveRequired();
3159 case Dali::Actor::Property::INHERIT_POSITION:
3161 value = IsPositionInherited();
3165 case Dali::Actor::Property::INHERIT_ORIENTATION:
3167 value = IsOrientationInherited();
3171 case Dali::Actor::Property::INHERIT_SCALE:
3173 value = IsScaleInherited();
3177 case Dali::Actor::Property::COLOR_MODE:
3179 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3183 case Dali::Actor::Property::POSITION_INHERITANCE:
3185 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3189 case Dali::Actor::Property::DRAW_MODE:
3191 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3195 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3197 value = GetSizeModeFactor();
3201 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3203 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3207 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3209 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3213 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3215 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3219 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3221 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3225 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3227 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3231 case Dali::Actor::Property::PADDING:
3233 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3234 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3235 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3239 case Dali::Actor::Property::MINIMUM_SIZE:
3241 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3245 case Dali::Actor::Property::MAXIMUM_SIZE:
3247 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3251 case Dali::DevelActor::Property::SIBLING_ORDER:
3253 value = static_cast<int>(mSiblingOrder);
3257 case Dali::Actor::Property::CLIPPING_MODE:
3259 value = mClippingMode;
3267 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3272 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3274 // This method should only return an object connected to the scene-graph
3275 return OnStage() ? mNode : NULL;
3278 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3280 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3282 const PropertyBase* property( NULL );
3284 // This method should only return a property of an object connected to the scene-graph
3290 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3292 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3293 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3295 property = animatable->GetSceneGraphProperty();
3297 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3298 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3300 CustomPropertyMetadata* custom = FindCustomProperty( index );
3301 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3303 property = custom->GetSceneGraphProperty();
3305 else if( NULL != mNode )
3309 case Dali::Actor::Property::SIZE:
3310 property = &mNode->mSize;
3313 case Dali::Actor::Property::SIZE_WIDTH:
3314 property = &mNode->mSize;
3317 case Dali::Actor::Property::SIZE_HEIGHT:
3318 property = &mNode->mSize;
3321 case Dali::Actor::Property::SIZE_DEPTH:
3322 property = &mNode->mSize;
3325 case Dali::Actor::Property::POSITION:
3326 property = &mNode->mPosition;
3329 case Dali::Actor::Property::POSITION_X:
3330 property = &mNode->mPosition;
3333 case Dali::Actor::Property::POSITION_Y:
3334 property = &mNode->mPosition;
3337 case Dali::Actor::Property::POSITION_Z:
3338 property = &mNode->mPosition;
3341 case Dali::Actor::Property::ORIENTATION:
3342 property = &mNode->mOrientation;
3345 case Dali::Actor::Property::SCALE:
3346 property = &mNode->mScale;
3349 case Dali::Actor::Property::SCALE_X:
3350 property = &mNode->mScale;
3353 case Dali::Actor::Property::SCALE_Y:
3354 property = &mNode->mScale;
3357 case Dali::Actor::Property::SCALE_Z:
3358 property = &mNode->mScale;
3361 case Dali::Actor::Property::VISIBLE:
3362 property = &mNode->mVisible;
3365 case Dali::Actor::Property::COLOR:
3366 property = &mNode->mColor;
3369 case Dali::Actor::Property::COLOR_RED:
3370 property = &mNode->mColor;
3373 case Dali::Actor::Property::COLOR_GREEN:
3374 property = &mNode->mColor;
3377 case Dali::Actor::Property::COLOR_BLUE:
3378 property = &mNode->mColor;
3381 case Dali::Actor::Property::COLOR_ALPHA:
3382 case Dali::DevelActor::Property::OPACITY:
3383 property = &mNode->mColor;
3394 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3396 const PropertyInputImpl* property( NULL );
3398 // This method should only return a property of an object connected to the scene-graph
3404 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3406 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3407 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3409 property = animatable->GetSceneGraphProperty();
3411 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3412 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3414 CustomPropertyMetadata* custom = FindCustomProperty( index );
3415 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3416 property = custom->GetSceneGraphProperty();
3418 else if( NULL != mNode )
3422 case Dali::Actor::Property::PARENT_ORIGIN:
3423 property = &mNode->mParentOrigin;
3426 case Dali::Actor::Property::PARENT_ORIGIN_X:
3427 property = &mNode->mParentOrigin;
3430 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3431 property = &mNode->mParentOrigin;
3434 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3435 property = &mNode->mParentOrigin;
3438 case Dali::Actor::Property::ANCHOR_POINT:
3439 property = &mNode->mAnchorPoint;
3442 case Dali::Actor::Property::ANCHOR_POINT_X:
3443 property = &mNode->mAnchorPoint;
3446 case Dali::Actor::Property::ANCHOR_POINT_Y:
3447 property = &mNode->mAnchorPoint;
3450 case Dali::Actor::Property::ANCHOR_POINT_Z:
3451 property = &mNode->mAnchorPoint;
3454 case Dali::Actor::Property::SIZE:
3455 property = &mNode->mSize;
3458 case Dali::Actor::Property::SIZE_WIDTH:
3459 property = &mNode->mSize;
3462 case Dali::Actor::Property::SIZE_HEIGHT:
3463 property = &mNode->mSize;
3466 case Dali::Actor::Property::SIZE_DEPTH:
3467 property = &mNode->mSize;
3470 case Dali::Actor::Property::POSITION:
3471 property = &mNode->mPosition;
3474 case Dali::Actor::Property::POSITION_X:
3475 property = &mNode->mPosition;
3478 case Dali::Actor::Property::POSITION_Y:
3479 property = &mNode->mPosition;
3482 case Dali::Actor::Property::POSITION_Z:
3483 property = &mNode->mPosition;
3486 case Dali::Actor::Property::WORLD_POSITION:
3487 property = &mNode->mWorldPosition;
3490 case Dali::Actor::Property::WORLD_POSITION_X:
3491 property = &mNode->mWorldPosition;
3494 case Dali::Actor::Property::WORLD_POSITION_Y:
3495 property = &mNode->mWorldPosition;
3498 case Dali::Actor::Property::WORLD_POSITION_Z:
3499 property = &mNode->mWorldPosition;
3502 case Dali::Actor::Property::ORIENTATION:
3503 property = &mNode->mOrientation;
3506 case Dali::Actor::Property::WORLD_ORIENTATION:
3507 property = &mNode->mWorldOrientation;
3510 case Dali::Actor::Property::SCALE:
3511 property = &mNode->mScale;
3514 case Dali::Actor::Property::SCALE_X:
3515 property = &mNode->mScale;
3518 case Dali::Actor::Property::SCALE_Y:
3519 property = &mNode->mScale;
3522 case Dali::Actor::Property::SCALE_Z:
3523 property = &mNode->mScale;
3526 case Dali::Actor::Property::WORLD_SCALE:
3527 property = &mNode->mWorldScale;
3530 case Dali::Actor::Property::VISIBLE:
3531 property = &mNode->mVisible;
3534 case Dali::Actor::Property::COLOR:
3535 property = &mNode->mColor;
3538 case Dali::Actor::Property::COLOR_RED:
3539 property = &mNode->mColor;
3542 case Dali::Actor::Property::COLOR_GREEN:
3543 property = &mNode->mColor;
3546 case Dali::Actor::Property::COLOR_BLUE:
3547 property = &mNode->mColor;
3550 case Dali::Actor::Property::COLOR_ALPHA:
3551 case Dali::DevelActor::Property::OPACITY:
3553 property = &mNode->mColor;
3557 case Dali::Actor::Property::WORLD_COLOR:
3558 property = &mNode->mWorldColor;
3561 case Dali::Actor::Property::WORLD_MATRIX:
3562 property = &mNode->mWorldMatrix;
3573 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3575 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3577 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3579 // check whether the animatable property is registered already, if not then register one.
3580 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3581 if( animatableProperty )
3583 componentIndex = animatableProperty->componentIndex;
3590 case Dali::Actor::Property::PARENT_ORIGIN_X:
3591 case Dali::Actor::Property::ANCHOR_POINT_X:
3592 case Dali::Actor::Property::SIZE_WIDTH:
3593 case Dali::Actor::Property::POSITION_X:
3594 case Dali::Actor::Property::WORLD_POSITION_X:
3595 case Dali::Actor::Property::SCALE_X:
3596 case Dali::Actor::Property::COLOR_RED:
3602 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3603 case Dali::Actor::Property::ANCHOR_POINT_Y:
3604 case Dali::Actor::Property::SIZE_HEIGHT:
3605 case Dali::Actor::Property::POSITION_Y:
3606 case Dali::Actor::Property::WORLD_POSITION_Y:
3607 case Dali::Actor::Property::SCALE_Y:
3608 case Dali::Actor::Property::COLOR_GREEN:
3614 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3615 case Dali::Actor::Property::ANCHOR_POINT_Z:
3616 case Dali::Actor::Property::SIZE_DEPTH:
3617 case Dali::Actor::Property::POSITION_Z:
3618 case Dali::Actor::Property::WORLD_POSITION_Z:
3619 case Dali::Actor::Property::SCALE_Z:
3620 case Dali::Actor::Property::COLOR_BLUE:
3626 case Dali::Actor::Property::COLOR_ALPHA:
3627 case Dali::DevelActor::Property::OPACITY:
3641 return componentIndex;
3644 void Actor::SetParent( Actor* parent )
3648 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3652 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3655 // Instruct each actor to create a corresponding node in the scene graph
3656 ConnectToStage( parent->GetHierarchyDepth() );
3659 // Resolve the name and index for the child properties if any
3660 ResolveChildProperties();
3662 else // parent being set to NULL
3664 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3668 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3671 DALI_ASSERT_ALWAYS( mNode != NULL );
3675 // Disconnect the Node & its children from the scene-graph.
3676 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3679 // Instruct each actor to discard pointers to the scene-graph
3680 DisconnectFromStage();
3685 SceneGraph::Node* Actor::CreateNode() const
3690 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3693 Actor* actor = dynamic_cast< Actor* >( object );
3697 if( 0 == actionName.compare( ACTION_SHOW ) )
3699 actor->SetVisible( true );
3702 else if( 0 == actionName.compare( ACTION_HIDE ) )
3704 actor->SetVisible( false );
3712 void Actor::EnsureRelayoutData()
3714 // Assign relayout data.
3715 if( !mRelayoutData )
3717 mRelayoutData = new RelayoutData();
3721 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3723 // Check if actor is dependent on parent
3724 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3726 if( ( dimension & ( 1 << i ) ) )
3728 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3729 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3739 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3741 // Check if actor is dependent on children
3742 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3744 if( ( dimension & ( 1 << i ) ) )
3746 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3747 switch( resizePolicy )
3749 case ResizePolicy::FIT_TO_CHILDREN:
3750 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3766 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3768 return Actor::RelayoutDependentOnChildren( dimension );
3771 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3773 // Check each possible dimension and see if it is dependent on the input one
3774 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3776 if( dimension & ( 1 << i ) )
3778 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3785 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3787 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3789 if( dimension & ( 1 << i ) )
3791 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3796 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3798 // If more than one dimension is requested, just return the first one found
3799 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3801 if( ( dimension & ( 1 << i ) ) )
3803 return mRelayoutData->negotiatedDimensions[ i ];
3807 return 0.0f; // Default
3810 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3812 EnsureRelayoutData();
3814 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3816 if( dimension & ( 1 << i ) )
3818 mRelayoutData->dimensionPadding[ i ] = padding;
3823 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3825 if ( mRelayoutData )
3827 // If more than one dimension is requested, just return the first one found
3828 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3830 if( ( dimension & ( 1 << i ) ) )
3832 return mRelayoutData->dimensionPadding[ i ];
3837 return GetDefaultDimensionPadding();
3840 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3842 EnsureRelayoutData();
3844 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3846 if( dimension & ( 1 << i ) )
3848 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3853 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3855 if ( mRelayoutData )
3857 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3859 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3869 float Actor::GetHeightForWidthBase( float width )
3871 float height = 0.0f;
3873 const Vector3 naturalSize = GetNaturalSize();
3874 if( naturalSize.width > 0.0f )
3876 height = naturalSize.height * width / naturalSize.width;
3878 else // we treat 0 as 1:1 aspect ratio
3886 float Actor::GetWidthForHeightBase( float height )
3890 const Vector3 naturalSize = GetNaturalSize();
3891 if( naturalSize.height > 0.0f )
3893 width = naturalSize.width * height / naturalSize.height;
3895 else // we treat 0 as 1:1 aspect ratio
3903 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3905 // Fill to parent, taking size mode factor into account
3906 switch( child.GetResizePolicy( dimension ) )
3908 case ResizePolicy::FILL_TO_PARENT:
3910 return GetLatestSize( dimension );
3913 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3915 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3918 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3920 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3925 return GetLatestSize( dimension );
3930 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3932 // Can be overridden in derived class
3933 return CalculateChildSizeBase( child, dimension );
3936 float Actor::GetHeightForWidth( float width )
3938 // Can be overridden in derived class
3939 return GetHeightForWidthBase( width );
3942 float Actor::GetWidthForHeight( float height )
3944 // Can be overridden in derived class
3945 return GetWidthForHeightBase( height );
3948 float Actor::GetLatestSize( Dimension::Type dimension ) const
3950 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3953 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3955 Vector2 padding = GetPadding( dimension );
3957 return GetLatestSize( dimension ) + padding.x + padding.y;
3960 float Actor::NegotiateFromParent( Dimension::Type dimension )
3962 Actor* parent = GetParent();
3965 Vector2 padding( GetPadding( dimension ) );
3966 Vector2 parentPadding( parent->GetPadding( dimension ) );
3967 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3973 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3975 float maxDimensionPoint = 0.0f;
3977 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3979 ActorPtr child = GetChildAt( i );
3981 if( !child->RelayoutDependentOnParent( dimension ) )
3983 // Calculate the min and max points that the children range across
3984 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3985 float dimensionSize = child->GetRelayoutSize( dimension );
3986 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3990 return maxDimensionPoint;
3993 float Actor::GetSize( Dimension::Type dimension ) const
3995 return GetDimensionValue( GetTargetSize(), dimension );
3998 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4000 return GetDimensionValue( GetNaturalSize(), dimension );
4003 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4005 switch( GetResizePolicy( dimension ) )
4007 case ResizePolicy::USE_NATURAL_SIZE:
4009 return GetNaturalSize( dimension );
4012 case ResizePolicy::FIXED:
4014 return GetDimensionValue( GetPreferredSize(), dimension );
4017 case ResizePolicy::USE_ASSIGNED_SIZE:
4019 return GetDimensionValue( maximumSize, dimension );
4022 case ResizePolicy::FILL_TO_PARENT:
4023 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4024 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4026 return NegotiateFromParent( dimension );
4029 case ResizePolicy::FIT_TO_CHILDREN:
4031 return NegotiateFromChildren( dimension );
4034 case ResizePolicy::DIMENSION_DEPENDENCY:
4036 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4039 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4041 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4044 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4046 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4058 return 0.0f; // Default
4061 float Actor::ClampDimension( float size, Dimension::Type dimension )
4063 const float minSize = GetMinimumSize( dimension );
4064 const float maxSize = GetMaximumSize( dimension );
4066 return std::max( minSize, std::min( size, maxSize ) );
4069 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4071 // Check if it needs to be negotiated
4072 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4074 // Check that we havn't gotten into an infinite loop
4075 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4076 bool recursionFound = false;
4077 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4079 if( *it == searchActor )
4081 recursionFound = true;
4086 if( !recursionFound )
4088 // Record the path that we have taken
4089 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4091 // Dimension dependency check
4092 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4094 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4096 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4098 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4102 // Parent dependency check
4103 Actor* parent = GetParent();
4104 if( parent && RelayoutDependentOnParent( dimension ) )
4106 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4109 // Children dependency check
4110 if( RelayoutDependentOnChildren( dimension ) )
4112 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4114 ActorPtr child = GetChildAt( i );
4116 // Only relayout child first if it is not dependent on this actor
4117 if( !child->RelayoutDependentOnParent( dimension ) )
4119 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4124 // For deriving classes
4125 OnCalculateRelayoutSize( dimension );
4127 // All dependencies checked, calculate the size and set negotiated flag
4128 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4130 SetNegotiatedDimension( newSize, dimension );
4131 SetLayoutNegotiated( true, dimension );
4133 // For deriving classes
4134 OnLayoutNegotiated( newSize, dimension );
4136 // This actor has been successfully processed, pop it off the recursion stack
4137 recursionStack.pop_back();
4141 // TODO: Break infinite loop
4142 SetLayoutNegotiated( true, dimension );
4147 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4149 // Negotiate all dimensions that require it
4150 ActorDimensionStack recursionStack;
4152 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4154 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4157 NegotiateDimension( dimension, allocatedSize, recursionStack );
4161 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4163 switch( mRelayoutData->sizeSetPolicy )
4165 case SizeScalePolicy::USE_SIZE_SET:
4170 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4172 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4173 const Vector3 naturalSize = GetNaturalSize();
4174 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4176 const float sizeRatio = size.width / size.height;
4177 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4179 if( naturalSizeRatio < sizeRatio )
4181 return Vector2( naturalSizeRatio * size.height, size.height );
4183 else if( naturalSizeRatio > sizeRatio )
4185 return Vector2( size.width, size.width / naturalSizeRatio );
4196 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4198 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4199 const Vector3 naturalSize = GetNaturalSize();
4200 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4202 const float sizeRatio = size.width / size.height;
4203 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4205 if( naturalSizeRatio < sizeRatio )
4207 return Vector2( size.width, size.width / naturalSizeRatio );
4209 else if( naturalSizeRatio > sizeRatio )
4211 return Vector2( naturalSizeRatio * size.height, size.height );
4230 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4232 // Do the set actor size
4233 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4235 // Adjust for size set policy
4236 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4238 // Lock the flag to stop recursive relayouts on set size
4239 mRelayoutData->insideRelayout = true;
4240 SetSize( negotiatedSize );
4241 mRelayoutData->insideRelayout = false;
4243 // Clear flags for all dimensions
4244 SetLayoutDirty( false );
4246 // Give deriving classes a chance to respond
4247 OnRelayout( negotiatedSize, container );
4249 if( !mOnRelayoutSignal.Empty() )
4251 Dali::Actor handle( this );
4252 mOnRelayoutSignal.Emit( handle );
4256 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4258 // Force a size negotiation for actors that has assigned size during relayout
4259 // This is required as otherwise the flags that force a relayout will not
4260 // necessarilly be set. This will occur if the actor has already been laid out.
4261 // The dirty flags are then cleared. Then if the actor is added back into the
4262 // relayout container afterwards, the dirty flags would still be clear...
4263 // causing a relayout to be skipped. Here we force any actors added to the
4264 // container to be relayed out.
4265 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4267 SetLayoutNegotiated(false, Dimension::WIDTH);
4269 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4271 SetLayoutNegotiated(false, Dimension::HEIGHT);
4274 // Do the negotiation
4275 NegotiateDimensions( allocatedSize );
4277 // Set the actor size
4278 SetNegotiatedSize( container );
4280 // Negotiate down to children
4281 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4283 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4285 ActorPtr child = GetChildAt( i );
4287 // Forces children that have already been laid out to be relayed out
4288 // if they have assigned size during relayout.
4289 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4291 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4292 child->SetLayoutDirty(true, Dimension::WIDTH);
4294 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4296 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4297 child->SetLayoutDirty(true, Dimension::HEIGHT);
4300 // Only relayout if required
4301 if( child->RelayoutRequired() )
4303 container.Add( Dali::Actor( child.Get() ), newBounds );
4308 void Actor::RelayoutRequest( Dimension::Type dimension )
4310 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4311 if( relayoutController )
4313 Dali::Actor self( this );
4314 relayoutController->RequestRelayout( self, dimension );
4318 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4322 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4326 void Actor::SetPreferredSize( const Vector2& size )
4328 EnsureRelayoutData();
4330 if( size.width > 0.0f )
4332 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4335 if( size.height > 0.0f )
4337 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4340 mRelayoutData->preferredSize = size;
4345 Vector2 Actor::GetPreferredSize() const
4347 if ( mRelayoutData )
4349 return Vector2( mRelayoutData->preferredSize );
4352 return GetDefaultPreferredSize();
4355 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4357 EnsureRelayoutData();
4359 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4361 if( dimension & ( 1 << i ) )
4363 mRelayoutData->minimumSize[ i ] = size;
4370 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4372 if ( mRelayoutData )
4374 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4376 if( dimension & ( 1 << i ) )
4378 return mRelayoutData->minimumSize[ i ];
4383 return 0.0f; // Default
4386 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4388 EnsureRelayoutData();
4390 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4392 if( dimension & ( 1 << i ) )
4394 mRelayoutData->maximumSize[ i ] = size;
4401 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4403 if ( mRelayoutData )
4405 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4407 if( dimension & ( 1 << i ) )
4409 return mRelayoutData->maximumSize[ i ];
4414 return FLT_MAX; // Default
4417 Object* Actor::GetParentObject() const
4422 } // namespace Internal