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_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
208 const char* const SIGNAL_TOUCHED = "touched";
209 const char* const SIGNAL_HOVERED = "hovered";
210 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
211 const char* const SIGNAL_ON_STAGE = "onStage";
212 const char* const SIGNAL_OFF_STAGE = "offStage";
213 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
214 const char* const SIGNAL_TOUCH = "touch";
218 const char* const ACTION_SHOW = "show";
219 const char* const ACTION_HIDE = "hide";
221 BaseHandle CreateActor()
223 return Dali::Actor::New();
226 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
228 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
229 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
232 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
233 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
234 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
236 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
237 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
242 const Vector3& value;
245 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
246 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
252 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
253 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
254 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
255 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
257 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
258 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
259 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
260 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
261 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
262 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
264 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
265 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
266 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
267 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
268 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
269 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
271 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
275 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
277 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
286 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
288 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
289 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
292 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
294 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
297 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
300 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
302 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
304 size_t sizeIgnored = 0;
305 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
307 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
314 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
316 // Values are the same so just use the same table as anchor-point
317 return GetAnchorPointConstant( value, parentOrigin );
321 * @brief Extract a given dimension from a Vector2
323 * @param[in] values The values to extract from
324 * @param[in] dimension The dimension to extract
325 * @return Return the value for the dimension
327 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
331 case Dimension::WIDTH:
335 case Dimension::HEIGHT:
337 return values.height;
348 * @brief Extract a given dimension from a Vector3
350 * @param[in] values The values to extract from
351 * @param[in] dimension The dimension to extract
352 * @return Return the value for the dimension
354 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
356 return GetDimensionValue( values.GetVectorXY(), dimension );
359 unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder )
361 return depth * Dali::DevelLayer::ACTOR_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
364 } // unnamed namespace
366 ActorPtr Actor::New()
368 ActorPtr actor( new Actor( BASIC ) );
370 // Second-phase construction
376 const std::string& Actor::GetName() const
381 void Actor::SetName( const std::string& name )
387 // ATTENTION: string for debug purposes is not thread safe.
388 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
392 unsigned int Actor::GetId() const
397 bool Actor::OnStage() const
402 Dali::Layer Actor::GetLayer()
406 // Short-circuit for Layer derived actors
409 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
412 // Find the immediate Layer parent
413 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
415 if( parent->IsLayer() )
417 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
424 void Actor::Add( Actor& child )
426 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
427 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
431 mChildren = new ActorContainer;
434 Actor* const oldParent( child.mParent );
436 // child might already be ours
437 if( this != oldParent )
439 // if we already have parent, unparent us first
442 oldParent->Remove( child ); // This causes OnChildRemove callback
444 // Old parent may need to readjust to missing child
445 if( oldParent->RelayoutDependentOnChildren() )
447 oldParent->RelayoutRequest();
451 // Guard against Add() during previous OnChildRemove callback
454 // Do this first, since user callbacks from within SetParent() may need to remove child
455 mChildren->push_back( ActorPtr( &child ) );
457 // SetParent asserts that child can be added
458 child.SetParent( this );
460 // Notification for derived classes
463 // Only put in a relayout request if there is a suitable dependency
464 if( RelayoutDependentOnChildren() )
472 void Actor::Remove( Actor& child )
474 if( (this == &child) || (!mChildren) )
476 // no children or removing itself
482 // Find the child in mChildren, and unparent it
483 ActorIter end = mChildren->end();
484 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
486 ActorPtr actor = (*iter);
488 if( actor.Get() == &child )
490 // Keep handle for OnChildRemove notification
493 // Do this first, since user callbacks from within SetParent() may need to add the child
494 mChildren->erase( iter );
496 DALI_ASSERT_DEBUG( actor->GetParent() == this );
497 actor->SetParent( NULL );
505 // Only put in a relayout request if there is a suitable dependency
506 if( RelayoutDependentOnChildren() )
512 // Notification for derived classes
513 OnChildRemove( child );
516 void Actor::Unparent()
520 // Remove this actor from the parent. The remove will put a relayout request in for
521 // the parent if required
522 mParent->Remove( *this );
523 // mParent is now NULL!
527 unsigned int Actor::GetChildCount() const
529 return ( NULL != mChildren ) ? mChildren->size() : 0;
532 ActorPtr Actor::GetChildAt( unsigned int index ) const
534 DALI_ASSERT_ALWAYS( index < GetChildCount() );
536 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
539 ActorPtr Actor::FindChildByName( const std::string& actorName )
542 if( actorName == mName )
548 ActorIter end = mChildren->end();
549 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
551 child = (*iter)->FindChildByName( actorName );
562 ActorPtr Actor::FindChildById( const unsigned int id )
571 ActorIter end = mChildren->end();
572 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
574 child = (*iter)->FindChildById( id );
585 void Actor::SetParentOrigin( const Vector3& origin )
589 // mNode is being used in a separate thread; queue a message to set the value & base value
590 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
593 // Cache for event-thread access
596 // not allocated, check if different from default
597 if( ParentOrigin::DEFAULT != origin )
599 mParentOrigin = new Vector3( origin );
604 // check if different from current costs more than just set
605 *mParentOrigin = origin;
609 void Actor::SetParentOriginX( float x )
611 const Vector3& current = GetCurrentParentOrigin();
613 SetParentOrigin( Vector3( x, current.y, current.z ) );
616 void Actor::SetParentOriginY( float y )
618 const Vector3& current = GetCurrentParentOrigin();
620 SetParentOrigin( Vector3( current.x, y, current.z ) );
623 void Actor::SetParentOriginZ( float z )
625 const Vector3& current = GetCurrentParentOrigin();
627 SetParentOrigin( Vector3( current.x, current.y, z ) );
630 const Vector3& Actor::GetCurrentParentOrigin() const
632 // Cached for event-thread access
633 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
636 void Actor::SetAnchorPoint( const Vector3& anchor )
640 // mNode is being used in a separate thread; queue a message to set the value & base value
641 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
644 // Cache for event-thread access
647 // not allocated, check if different from default
648 if( AnchorPoint::DEFAULT != anchor )
650 mAnchorPoint = new Vector3( anchor );
655 // check if different from current costs more than just set
656 *mAnchorPoint = anchor;
660 void Actor::SetAnchorPointX( float x )
662 const Vector3& current = GetCurrentAnchorPoint();
664 SetAnchorPoint( Vector3( x, current.y, current.z ) );
667 void Actor::SetAnchorPointY( float y )
669 const Vector3& current = GetCurrentAnchorPoint();
671 SetAnchorPoint( Vector3( current.x, y, current.z ) );
674 void Actor::SetAnchorPointZ( float z )
676 const Vector3& current = GetCurrentAnchorPoint();
678 SetAnchorPoint( Vector3( current.x, current.y, z ) );
681 const Vector3& Actor::GetCurrentAnchorPoint() const
683 // Cached for event-thread access
684 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
687 void Actor::SetPosition( float x, float y )
689 SetPosition( Vector3( x, y, 0.0f ) );
692 void Actor::SetPosition( float x, float y, float z )
694 SetPosition( Vector3( x, y, z ) );
697 void Actor::SetPosition( const Vector3& position )
699 mTargetPosition = position;
703 // mNode is being used in a separate thread; queue a message to set the value & base value
704 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
708 void Actor::SetX( float x )
710 mTargetPosition.x = x;
714 // mNode is being used in a separate thread; queue a message to set the value & base value
715 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
719 void Actor::SetY( float y )
721 mTargetPosition.y = y;
725 // mNode is being used in a separate thread; queue a message to set the value & base value
726 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
730 void Actor::SetZ( float z )
732 mTargetPosition.z = z;
736 // mNode is being used in a separate thread; queue a message to set the value & base value
737 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
741 void Actor::TranslateBy( const Vector3& distance )
743 mTargetPosition += distance;
747 // mNode is being used in a separate thread; queue a message to set the value & base value
748 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
752 const Vector3& Actor::GetCurrentPosition() const
756 // mNode is being used in a separate thread; copy the value from the previous update
757 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
760 return Vector3::ZERO;
763 const Vector3& Actor::GetTargetPosition() const
765 return mTargetPosition;
768 const Vector3& Actor::GetCurrentWorldPosition() const
772 // mNode is being used in a separate thread; copy the value from the previous update
773 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
776 return Vector3::ZERO;
779 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
781 // this flag is not animatable so keep the value
782 mPositionInheritanceMode = mode;
785 // mNode is being used in a separate thread; queue a message to set the value
786 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
790 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
792 // Cached for event-thread access
793 return mPositionInheritanceMode;
796 void Actor::SetInheritPosition( bool inherit )
798 if( mInheritPosition != inherit && NULL != mNode )
800 // non animateable so keep local copy
801 mInheritPosition = inherit;
802 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
806 bool Actor::IsPositionInherited() const
808 return mInheritPosition;
811 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
813 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
814 normalizedAxis.Normalize();
816 Quaternion orientation( angle, normalizedAxis );
818 SetOrientation( orientation );
821 void Actor::SetOrientation( const Quaternion& orientation )
825 // mNode is being used in a separate thread; queue a message to set the value & base value
826 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
830 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
834 // mNode is being used in a separate thread; queue a message to set the value & base value
835 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
839 void Actor::RotateBy( const Quaternion& relativeRotation )
843 // mNode is being used in a separate thread; queue a message to set the value & base value
844 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
848 const Quaternion& Actor::GetCurrentOrientation() const
852 // mNode is being used in a separate thread; copy the value from the previous update
853 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
856 return Quaternion::IDENTITY;
859 const Quaternion& Actor::GetCurrentWorldOrientation() const
863 // mNode is being used in a separate thread; copy the value from the previous update
864 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
867 return Quaternion::IDENTITY;
870 void Actor::SetScale( float scale )
872 SetScale( Vector3( scale, scale, scale ) );
875 void Actor::SetScale( float x, float y, float z )
877 SetScale( Vector3( x, y, z ) );
880 void Actor::SetScale( const Vector3& scale )
884 // mNode is being used in a separate thread; queue a message to set the value & base value
885 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
889 void Actor::SetScaleX( float x )
893 // mNode is being used in a separate thread; queue a message to set the value & base value
894 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
898 void Actor::SetScaleY( float y )
902 // mNode is being used in a separate thread; queue a message to set the value & base value
903 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
907 void Actor::SetScaleZ( float z )
911 // mNode is being used in a separate thread; queue a message to set the value & base value
912 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
916 void Actor::ScaleBy(const Vector3& relativeScale)
920 // mNode is being used in a separate thread; queue a message to set the value & base value
921 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
925 const Vector3& Actor::GetCurrentScale() const
929 // mNode is being used in a separate thread; copy the value from the previous update
930 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
936 const Vector3& Actor::GetCurrentWorldScale() const
940 // mNode is being used in a separate thread; copy the value from the previous update
941 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
947 void Actor::SetInheritScale( bool inherit )
950 if( mInheritScale != inherit && NULL != mNode )
952 // non animateable so keep local copy
953 mInheritScale = inherit;
954 // mNode is being used in a separate thread; queue a message to set the value
955 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
959 bool Actor::IsScaleInherited() const
961 return mInheritScale;
964 Matrix Actor::GetCurrentWorldMatrix() const
968 return mNode->GetWorldMatrix(0);
971 return Matrix::IDENTITY;
974 void Actor::SetVisible( bool visible )
978 // mNode is being used in a separate thread; queue a message to set the value & base value
979 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
983 bool Actor::IsVisible() const
987 // mNode is being used in a separate thread; copy the value from the previous update
988 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
994 void Actor::SetOpacity( float opacity )
998 // mNode is being used in a separate thread; queue a message to set the value & base value
999 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1003 float Actor::GetCurrentOpacity() const
1007 // mNode is being used in a separate thread; copy the value from the previous update
1008 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1014 ClippingMode::Type Actor::GetClippingMode() const
1016 return mClippingMode;
1019 unsigned int Actor::GetSortingDepth()
1021 return GetDepthIndex( mDepth, mSiblingOrder );
1024 const Vector4& Actor::GetCurrentWorldColor() const
1028 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1031 return Color::WHITE;
1034 void Actor::SetColor( const Vector4& color )
1038 // mNode is being used in a separate thread; queue a message to set the value & base value
1039 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1043 void Actor::SetColorRed( float red )
1047 // mNode is being used in a separate thread; queue a message to set the value & base value
1048 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1052 void Actor::SetColorGreen( float green )
1056 // mNode is being used in a separate thread; queue a message to set the value & base value
1057 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1061 void Actor::SetColorBlue( float blue )
1065 // mNode is being used in a separate thread; queue a message to set the value & base value
1066 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1070 const Vector4& Actor::GetCurrentColor() const
1074 // mNode is being used in a separate thread; copy the value from the previous update
1075 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1078 return Color::WHITE;
1081 void Actor::SetInheritOrientation( bool inherit )
1083 if( mInheritOrientation != inherit && NULL != mNode)
1085 // non animateable so keep local copy
1086 mInheritOrientation = inherit;
1087 // mNode is being used in a separate thread; queue a message to set the value
1088 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1092 bool Actor::IsOrientationInherited() const
1094 return mInheritOrientation;
1097 void Actor::SetSizeModeFactor( const Vector3& factor )
1099 EnsureRelayoutData();
1101 mRelayoutData->sizeModeFactor = factor;
1104 const Vector3& Actor::GetSizeModeFactor() const
1106 if ( mRelayoutData )
1108 return mRelayoutData->sizeModeFactor;
1111 return GetDefaultSizeModeFactor();
1114 void Actor::SetColorMode( ColorMode colorMode )
1116 // non animateable so keep local copy
1117 mColorMode = colorMode;
1120 // mNode is being used in a separate thread; queue a message to set the value
1121 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1125 ColorMode Actor::GetColorMode() const
1127 // we have cached copy
1131 void Actor::SetSize( float width, float height )
1133 SetSize( Vector2( width, height ) );
1136 void Actor::SetSize( float width, float height, float depth )
1138 SetSize( Vector3( width, height, depth ) );
1141 void Actor::SetSize( const Vector2& size )
1143 SetSize( Vector3( size.width, size.height, 0.f ) );
1146 void Actor::SetSizeInternal( const Vector2& size )
1148 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1151 void Actor::SetSize( const Vector3& size )
1153 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1155 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1156 SetPreferredSize( size.GetVectorXY() );
1160 SetSizeInternal( size );
1164 void Actor::SetSizeInternal( const Vector3& size )
1166 // dont allow recursive loop
1167 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1168 // 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
1169 if( ( NULL != mNode )&&
1170 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1171 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1172 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1176 // mNode is being used in a separate thread; queue a message to set the value & base value
1177 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1179 // Notification for derived classes
1180 mInsideOnSizeSet = true;
1181 OnSizeSet( mTargetSize );
1182 mInsideOnSizeSet = false;
1184 // Raise a relayout request if the flag is not locked
1185 if( mRelayoutData && !mRelayoutData->insideRelayout )
1192 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1194 mTargetSize = targetSize;
1196 // Notify deriving classes
1197 OnSizeAnimation( animation, mTargetSize );
1200 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1202 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1204 mTargetSize.width = targetSize;
1206 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1208 mTargetSize.height = targetSize;
1210 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1212 mTargetSize.depth = targetSize;
1214 // Notify deriving classes
1215 OnSizeAnimation( animation, mTargetSize );
1218 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1220 mTargetPosition = targetPosition;
1223 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1225 if ( Dali::Actor::Property::POSITION_X == property )
1227 mTargetPosition.x = targetPosition;
1229 else if ( Dali::Actor::Property::POSITION_Y == property )
1231 mTargetPosition.y = targetPosition;
1233 else if ( Dali::Actor::Property::POSITION_Z == property )
1235 mTargetPosition.z = targetPosition;
1239 void Actor::SetWidth( float width )
1241 mTargetSize.width = width;
1245 // mNode is being used in a separate thread; queue a message to set the value & base value
1246 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1250 void Actor::SetHeight( float height )
1252 mTargetSize.height = height;
1256 // mNode is being used in a separate thread; queue a message to set the value & base value
1257 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1261 void Actor::SetDepth( float depth )
1263 mTargetSize.depth = depth;
1267 // mNode is being used in a separate thread; queue a message to set the value & base value
1268 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1272 const Vector3& Actor::GetTargetSize() const
1277 const Vector3& Actor::GetCurrentSize() const
1281 // mNode is being used in a separate thread; copy the value from the previous update
1282 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1285 return Vector3::ZERO;
1288 Vector3 Actor::GetNaturalSize() const
1290 // It is up to deriving classes to return the appropriate natural size
1291 return Vector3( 0.0f, 0.0f, 0.0f );
1294 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1296 EnsureRelayoutData();
1298 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1299 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1301 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1303 if( dimension & ( 1 << i ) )
1305 mRelayoutData->resizePolicies[ i ] = policy;
1309 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1311 if( dimension & Dimension::WIDTH )
1313 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1316 if( dimension & Dimension::HEIGHT )
1318 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1322 // If calling SetResizePolicy, assume we want relayout enabled
1323 SetRelayoutEnabled( true );
1325 // If the resize policy is set to be FIXED, the preferred size
1326 // should be overrided by the target size. Otherwise the target
1327 // size should be overrided by the preferred size.
1329 if( dimension & Dimension::WIDTH )
1331 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1333 mRelayoutData->preferredSize.width = mTargetSize.width;
1335 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1337 mTargetSize.width = mRelayoutData->preferredSize.width;
1341 if( dimension & Dimension::HEIGHT )
1343 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1345 mRelayoutData->preferredSize.height = mTargetSize.height;
1347 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1349 mTargetSize.height = mRelayoutData->preferredSize.height;
1353 OnSetResizePolicy( policy, dimension );
1355 // Trigger relayout on this control
1359 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1361 if ( mRelayoutData )
1363 // If more than one dimension is requested, just return the first one found
1364 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1366 if( ( dimension & ( 1 << i ) ) )
1368 return mRelayoutData->resizePolicies[ i ];
1373 return ResizePolicy::DEFAULT;
1376 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1378 EnsureRelayoutData();
1380 mRelayoutData->sizeSetPolicy = policy;
1383 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1385 if ( mRelayoutData )
1387 return mRelayoutData->sizeSetPolicy;
1390 return DEFAULT_SIZE_SCALE_POLICY;
1393 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1395 EnsureRelayoutData();
1397 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1399 if( dimension & ( 1 << i ) )
1401 mRelayoutData->dimensionDependencies[ i ] = dependency;
1406 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1408 if ( mRelayoutData )
1410 // If more than one dimension is requested, just return the first one found
1411 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1413 if( ( dimension & ( 1 << i ) ) )
1415 return mRelayoutData->dimensionDependencies[ i ];
1420 return Dimension::ALL_DIMENSIONS; // Default
1423 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1425 // If relayout data has not been allocated yet and the client is requesting
1426 // to disable it, do nothing
1427 if( mRelayoutData || relayoutEnabled )
1429 EnsureRelayoutData();
1431 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1433 mRelayoutData->relayoutEnabled = relayoutEnabled;
1437 bool Actor::IsRelayoutEnabled() const
1439 // Assume that if relayout data has not been allocated yet then
1440 // relayout is disabled
1441 return mRelayoutData && mRelayoutData->relayoutEnabled;
1444 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1446 EnsureRelayoutData();
1448 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1450 if( dimension & ( 1 << i ) )
1452 mRelayoutData->dimensionDirty[ i ] = dirty;
1457 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1459 if ( mRelayoutData )
1461 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1463 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1473 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1475 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1478 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1480 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1483 unsigned int Actor::AddRenderer( Renderer& renderer )
1487 mRenderers = new RendererContainer;
1490 unsigned int index = mRenderers->size();
1491 RendererPtr rendererPtr = RendererPtr( &renderer );
1492 mRenderers->push_back( rendererPtr );
1493 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1497 unsigned int Actor::GetRendererCount() const
1499 unsigned int rendererCount(0);
1502 rendererCount = mRenderers->size();
1505 return rendererCount;
1508 RendererPtr Actor::GetRendererAt( unsigned int index )
1510 RendererPtr renderer;
1511 if( index < GetRendererCount() )
1513 renderer = ( *mRenderers )[ index ];
1519 void Actor::RemoveRenderer( Renderer& renderer )
1523 RendererIter end = mRenderers->end();
1524 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1526 if( (*iter).Get() == &renderer )
1528 mRenderers->erase( iter );
1529 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1536 void Actor::RemoveRenderer( unsigned int index )
1538 if( index < GetRendererCount() )
1540 RendererPtr renderer = ( *mRenderers )[ index ];
1541 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1542 mRenderers->erase( mRenderers->begin()+index );
1546 bool Actor::IsOverlay() const
1548 return ( DrawMode::OVERLAY_2D == mDrawMode );
1551 void Actor::SetDrawMode( DrawMode::Type drawMode )
1553 // this flag is not animatable so keep the value
1554 mDrawMode = drawMode;
1555 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1557 // mNode is being used in a separate thread; queue a message to set the value
1558 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1562 DrawMode::Type Actor::GetDrawMode() const
1567 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1569 // only valid when on-stage
1570 StagePtr stage = Stage::GetCurrent();
1571 if( stage && OnStage() )
1573 const RenderTaskList& taskList = stage->GetRenderTaskList();
1575 Vector2 converted( screenX, screenY );
1577 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1578 const int taskCount = taskList.GetTaskCount();
1579 for( int i = taskCount - 1; i >= 0; --i )
1581 Dali::RenderTask task = taskList.GetTask( i );
1582 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1584 // found a task where this conversion was ok so return
1592 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1594 bool retval = false;
1595 // only valid when on-stage
1598 CameraActor* camera = renderTask.GetCameraActor();
1602 renderTask.GetViewport( viewport );
1604 // need to translate coordinates to render tasks coordinate space
1605 Vector2 converted( screenX, screenY );
1606 if( renderTask.TranslateCoordinates( converted ) )
1608 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1615 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1617 // Early-out if mNode is NULL
1623 // Get the ModelView matrix
1625 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1627 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1628 Matrix invertedMvp( false/*don't init*/);
1629 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1630 bool success = invertedMvp.Invert();
1632 // Convert to GL coordinates
1633 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1638 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1645 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1651 if( XyPlaneIntersect( nearPos, farPos, local ) )
1653 Vector3 size = GetCurrentSize();
1654 localX = local.x + size.x * 0.5f;
1655 localY = local.y + size.y * 0.5f;
1666 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1669 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1671 Mathematical Formulation
1673 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1675 ( p - c ) dot ( p - c ) = r^2
1677 Given a ray with a point of origin 'o', and a direction vector 'd':
1679 ray(t) = o + td, t >= 0
1681 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1683 (o + td - c ) dot ( o + td - c ) = r^2
1685 To solve for t we first expand the above into a more recognisable quadratic equation form
1687 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1696 B = 2( o - c ) dot d
1697 C = ( o - c ) dot ( o - c ) - r^2
1699 which can be solved using a standard quadratic formula.
1701 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1703 Practical Simplification
1705 In a renderer, we often differentiate between world space and object space. In the object space
1706 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1707 into object space, the mathematical solution presented above can be simplified significantly.
1709 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1713 and we can find the t at which the (transformed) ray intersects the sphere by
1715 ( o + td ) dot ( o + td ) = r^2
1717 According to the reasoning above, we expand the above quadratic equation into the general form
1721 which now has coefficients:
1728 // Early out if mNode is NULL
1734 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1736 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1737 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1738 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1740 // Compute the radius is not needed, square radius it's enough.
1741 const Vector3& size( mNode->GetSize( bufferIndex ) );
1743 // Scale the sphere.
1744 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1746 const float width = size.width * scale.width;
1747 const float height = size.height * scale.height;
1749 float squareSphereRadius = 0.5f * ( width * width + height * height );
1751 float a = rayDir.Dot( rayDir ); // a
1752 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1753 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1755 return ( b2 * b2 - a * c ) >= 0.f;
1758 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1762 if( OnStage() && NULL != mNode )
1764 // Transforms the ray to the local reference system.
1765 // Calculate the inverse of Model matrix
1766 Matrix invModelMatrix( false/*don't init*/);
1768 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1769 invModelMatrix = mNode->GetWorldMatrix(0);
1770 invModelMatrix.Invert();
1772 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1773 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1775 // Test with the actor's XY plane (Normal = 0 0 1 1).
1777 float a = -rayOriginLocal.z;
1778 float b = rayDirLocal.z;
1780 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1782 // Ray travels distance * rayDirLocal to intersect with plane.
1785 const Vector3& size = mNode->GetSize( bufferIndex );
1787 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1788 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1790 // Test with the actor's geometry.
1791 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1798 void Actor::SetLeaveRequired( bool required )
1800 mLeaveRequired = required;
1803 bool Actor::GetLeaveRequired() const
1805 return mLeaveRequired;
1808 void Actor::SetKeyboardFocusable( bool focusable )
1810 mKeyboardFocusable = focusable;
1813 bool Actor::IsKeyboardFocusable() const
1815 return mKeyboardFocusable;
1818 bool Actor::GetTouchRequired() const
1820 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1823 bool Actor::GetHoverRequired() const
1825 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1828 bool Actor::GetWheelEventRequired() const
1830 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1833 bool Actor::IsHittable() const
1835 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1838 ActorGestureData& Actor::GetGestureData()
1840 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1841 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1842 if( NULL == mGestureData )
1844 mGestureData = new ActorGestureData;
1846 return *mGestureData;
1849 bool Actor::IsGestureRequred( Gesture::Type type ) const
1851 return mGestureData && mGestureData->IsGestureRequred( type );
1854 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1856 bool consumed = false;
1858 if( !mTouchSignal.Empty() )
1860 Dali::Actor handle( this );
1861 consumed = mTouchSignal.Emit( handle, touch );
1864 if( !mTouchedSignal.Empty() )
1866 Dali::Actor handle( this );
1867 consumed |= mTouchedSignal.Emit( handle, event );
1872 // Notification for derived classes
1873 consumed = OnTouchEvent( event ); // TODO
1879 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1881 bool consumed = false;
1883 if( !mHoveredSignal.Empty() )
1885 Dali::Actor handle( this );
1886 consumed = mHoveredSignal.Emit( handle, event );
1891 // Notification for derived classes
1892 consumed = OnHoverEvent( event );
1898 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1900 bool consumed = false;
1902 if( !mWheelEventSignal.Empty() )
1904 Dali::Actor handle( this );
1905 consumed = mWheelEventSignal.Emit( handle, event );
1910 // Notification for derived classes
1911 consumed = OnWheelEvent( event );
1917 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1919 return mTouchedSignal;
1922 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1924 return mTouchSignal;
1927 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1929 return mHoveredSignal;
1932 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1934 return mWheelEventSignal;
1937 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1939 return mOnStageSignal;
1942 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1944 return mOffStageSignal;
1947 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1949 return mOnRelayoutSignal;
1952 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1954 bool connected( true );
1955 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1957 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1959 actor->TouchedSignal().Connect( tracker, functor );
1961 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1963 actor->HoveredSignal().Connect( tracker, functor );
1965 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1967 actor->WheelEventSignal().Connect( tracker, functor );
1969 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1971 actor->OnStageSignal().Connect( tracker, functor );
1973 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1975 actor->OffStageSignal().Connect( tracker, functor );
1977 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1979 actor->OnRelayoutSignal().Connect( tracker, functor );
1981 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1983 actor->TouchSignal().Connect( tracker, functor );
1987 // signalName does not match any signal
1994 Actor::Actor( DerivedType derivedType )
1999 mParentOrigin( NULL ),
2000 mAnchorPoint( NULL ),
2001 mRelayoutData( NULL ),
2002 mGestureData( NULL ),
2003 mTargetSize( 0.0f, 0.0f, 0.0f ),
2005 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2008 mIsRoot( ROOT_LAYER == derivedType ),
2009 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2010 mIsOnStage( false ),
2012 mLeaveRequired( false ),
2013 mKeyboardFocusable( false ),
2014 mDerivedRequiresTouch( false ),
2015 mDerivedRequiresHover( false ),
2016 mDerivedRequiresWheelEvent( false ),
2017 mOnStageSignalled( false ),
2018 mInsideOnSizeSet( false ),
2019 mInheritPosition( true ),
2020 mInheritOrientation( true ),
2021 mInheritScale( true ),
2022 mDrawMode( DrawMode::NORMAL ),
2023 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2024 mColorMode( Node::DEFAULT_COLOR_MODE ),
2025 mClippingMode( ClippingMode::DISABLED )
2029 void Actor::Initialize()
2032 SceneGraph::Node* node = CreateNode();
2034 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2035 mNode = node; // Keep raw-pointer to Node
2039 GetEventThreadServices().RegisterObject( this );
2044 // Remove mParent pointers from children even if we're destroying core,
2045 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2048 ActorConstIter endIter = mChildren->end();
2049 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2051 (*iter)->SetParent( NULL );
2057 // Guard to allow handle destruction after Core has been destroyed
2058 if( EventThreadServices::IsCoreRunning() )
2062 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2063 mNode = NULL; // Node is about to be destroyed
2066 GetEventThreadServices().UnregisterObject( this );
2069 // Cleanup optional gesture data
2070 delete mGestureData;
2072 // Cleanup optional parent origin and anchor
2073 delete mParentOrigin;
2074 delete mAnchorPoint;
2076 // Delete optional relayout data
2079 delete mRelayoutData;
2083 void Actor::ConnectToStage( unsigned int parentDepth )
2085 // This container is used instead of walking the Actor hierarchy.
2086 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2087 ActorContainer connectionList;
2089 // This stage is atomic i.e. not interrupted by user callbacks.
2090 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2092 // Notify applications about the newly connected actors.
2093 const ActorIter endIter = connectionList.end();
2094 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2096 (*iter)->NotifyStageConnection();
2102 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2104 DALI_ASSERT_ALWAYS( !OnStage() );
2108 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2110 ConnectToSceneGraph();
2112 // Notification for internal derived classes
2113 OnStageConnectionInternal();
2115 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2116 connectionList.push_back( ActorPtr( this ) );
2118 // Recursively connect children
2121 ActorConstIter endIter = mChildren->end();
2122 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2124 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2130 * This method is called when the Actor is connected to the Stage.
2131 * The parent must have added its Node to the scene-graph.
2132 * The child must connect its Node to the parent's Node.
2133 * This is recursive; the child calls ConnectToStage() for its children.
2135 void Actor::ConnectToSceneGraph()
2137 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2141 // Reparent Node in next Update
2142 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2145 // Request relayout on all actors that are added to the scenegraph
2148 // Notification for Object::Observers
2152 void Actor::NotifyStageConnection()
2154 // Actors can be removed (in a callback), before the on-stage stage is reported.
2155 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2156 if( OnStage() && !mOnStageSignalled )
2158 // Notification for external (CustomActor) derived classes
2159 OnStageConnectionExternal( mDepth );
2161 if( !mOnStageSignal.Empty() )
2163 Dali::Actor handle( this );
2164 mOnStageSignal.Emit( handle );
2167 // Guard against Remove during callbacks
2170 mOnStageSignalled = true; // signal required next time Actor is removed
2175 void Actor::DisconnectFromStage()
2177 // This container is used instead of walking the Actor hierachy.
2178 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2179 ActorContainer disconnectionList;
2181 // This stage is atomic i.e. not interrupted by user callbacks
2182 RecursiveDisconnectFromStage( disconnectionList );
2184 // Notify applications about the newly disconnected actors.
2185 const ActorIter endIter = disconnectionList.end();
2186 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2188 (*iter)->NotifyStageDisconnection();
2192 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2194 DALI_ASSERT_ALWAYS( OnStage() );
2196 // Recursively disconnect children
2199 ActorConstIter endIter = mChildren->end();
2200 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2202 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2206 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2207 disconnectionList.push_back( ActorPtr( this ) );
2209 // Notification for internal derived classes
2210 OnStageDisconnectionInternal();
2212 DisconnectFromSceneGraph();
2218 * This method is called by an actor or its parent, before a node removal message is sent.
2219 * This is recursive; the child calls DisconnectFromStage() for its children.
2221 void Actor::DisconnectFromSceneGraph()
2223 // Notification for Object::Observers
2224 OnSceneObjectRemove();
2227 void Actor::NotifyStageDisconnection()
2229 // Actors can be added (in a callback), before the off-stage state is reported.
2230 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2231 // only do this step if there is a stage, i.e. Core is not being shut down
2232 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2234 // Notification for external (CustomeActor) derived classes
2235 OnStageDisconnectionExternal();
2237 if( !mOffStageSignal.Empty() )
2239 Dali::Actor handle( this );
2240 mOffStageSignal.Emit( handle );
2243 // Guard against Add during callbacks
2246 mOnStageSignalled = false; // signal required next time Actor is added
2251 bool Actor::IsNodeConnected() const
2253 bool connected( false );
2255 if( OnStage() && ( NULL != mNode ) )
2257 if( IsRoot() || mNode->GetParent() )
2266 unsigned int Actor::GetDefaultPropertyCount() const
2268 return DEFAULT_PROPERTY_COUNT;
2271 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2273 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2275 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2277 indices.PushBack( i );
2281 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2283 if( index < DEFAULT_PROPERTY_COUNT )
2285 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2291 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2293 Property::Index index = Property::INVALID_INDEX;
2295 // Look for name in default properties
2296 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2298 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2299 if( 0 == name.compare( property->name ) )
2309 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2311 if( index < DEFAULT_PROPERTY_COUNT )
2313 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2319 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2321 if( index < DEFAULT_PROPERTY_COUNT )
2323 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2329 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2331 if( index < DEFAULT_PROPERTY_COUNT )
2333 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2339 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2341 if( index < DEFAULT_PROPERTY_COUNT )
2343 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2346 // index out of range...return Property::NONE
2347 return Property::NONE;
2350 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2354 case Dali::Actor::Property::PARENT_ORIGIN:
2356 Property::Type type = property.GetType();
2357 if( type == Property::VECTOR3 )
2359 SetParentOrigin( property.Get< Vector3 >() );
2361 else if ( type == Property::STRING )
2363 std::string parentOriginString;
2364 property.Get( parentOriginString );
2365 Vector3 parentOrigin;
2366 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2368 SetParentOrigin( parentOrigin );
2374 case Dali::Actor::Property::PARENT_ORIGIN_X:
2376 SetParentOriginX( property.Get< float >() );
2380 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2382 SetParentOriginY( property.Get< float >() );
2386 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2388 SetParentOriginZ( property.Get< float >() );
2392 case Dali::Actor::Property::ANCHOR_POINT:
2394 Property::Type type = property.GetType();
2395 if( type == Property::VECTOR3 )
2397 SetAnchorPoint( property.Get< Vector3 >() );
2399 else if ( type == Property::STRING )
2401 std::string anchorPointString;
2402 property.Get( anchorPointString );
2404 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2406 SetAnchorPoint( anchor );
2412 case Dali::Actor::Property::ANCHOR_POINT_X:
2414 SetAnchorPointX( property.Get< float >() );
2418 case Dali::Actor::Property::ANCHOR_POINT_Y:
2420 SetAnchorPointY( property.Get< float >() );
2424 case Dali::Actor::Property::ANCHOR_POINT_Z:
2426 SetAnchorPointZ( property.Get< float >() );
2430 case Dali::Actor::Property::SIZE:
2432 SetSize( property.Get< Vector3 >() );
2436 case Dali::Actor::Property::SIZE_WIDTH:
2438 SetWidth( property.Get< float >() );
2442 case Dali::Actor::Property::SIZE_HEIGHT:
2444 SetHeight( property.Get< float >() );
2448 case Dali::Actor::Property::SIZE_DEPTH:
2450 SetDepth( property.Get< float >() );
2454 case Dali::Actor::Property::POSITION:
2456 SetPosition( property.Get< Vector3 >() );
2460 case Dali::Actor::Property::POSITION_X:
2462 SetX( property.Get< float >() );
2466 case Dali::Actor::Property::POSITION_Y:
2468 SetY( property.Get< float >() );
2472 case Dali::Actor::Property::POSITION_Z:
2474 SetZ( property.Get< float >() );
2478 case Dali::Actor::Property::ORIENTATION:
2480 SetOrientation( property.Get< Quaternion >() );
2484 case Dali::Actor::Property::SCALE:
2486 SetScale( property.Get< Vector3 >() );
2490 case Dali::Actor::Property::SCALE_X:
2492 SetScaleX( property.Get< float >() );
2496 case Dali::Actor::Property::SCALE_Y:
2498 SetScaleY( property.Get< float >() );
2502 case Dali::Actor::Property::SCALE_Z:
2504 SetScaleZ( property.Get< float >() );
2508 case Dali::Actor::Property::VISIBLE:
2510 SetVisible( property.Get< bool >() );
2514 case Dali::Actor::Property::COLOR:
2516 SetColor( property.Get< Vector4 >() );
2520 case Dali::Actor::Property::COLOR_RED:
2522 SetColorRed( property.Get< float >() );
2526 case Dali::Actor::Property::COLOR_GREEN:
2528 SetColorGreen( property.Get< float >() );
2532 case Dali::Actor::Property::COLOR_BLUE:
2534 SetColorBlue( property.Get< float >() );
2538 case Dali::Actor::Property::COLOR_ALPHA:
2540 SetOpacity( property.Get< float >() );
2544 case Dali::Actor::Property::NAME:
2546 SetName( property.Get< std::string >() );
2550 case Dali::Actor::Property::SENSITIVE:
2552 SetSensitive( property.Get< bool >() );
2556 case Dali::Actor::Property::LEAVE_REQUIRED:
2558 SetLeaveRequired( property.Get< bool >() );
2562 case Dali::Actor::Property::INHERIT_POSITION:
2564 SetInheritPosition( property.Get< bool >() );
2568 case Dali::Actor::Property::INHERIT_ORIENTATION:
2570 SetInheritOrientation( property.Get< bool >() );
2574 case Dali::Actor::Property::INHERIT_SCALE:
2576 SetInheritScale( property.Get< bool >() );
2580 case Dali::Actor::Property::COLOR_MODE:
2582 ColorMode mode = mColorMode;
2583 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2585 SetColorMode( mode );
2590 case Dali::Actor::Property::POSITION_INHERITANCE:
2592 PositionInheritanceMode mode = mPositionInheritanceMode;
2593 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2595 SetPositionInheritanceMode( mode );
2600 case Dali::Actor::Property::DRAW_MODE:
2602 DrawMode::Type mode = mDrawMode;
2603 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2605 SetDrawMode( mode );
2610 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2612 SetSizeModeFactor( property.Get< Vector3 >() );
2616 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2618 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2619 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2621 SetResizePolicy( type, Dimension::WIDTH );
2626 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2628 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2629 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2631 SetResizePolicy( type, Dimension::HEIGHT );
2636 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2638 SizeScalePolicy::Type type;
2639 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2641 SetSizeScalePolicy( type );
2646 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2648 if( property.Get< bool >() )
2650 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2655 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2657 if( property.Get< bool >() )
2659 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2664 case Dali::Actor::Property::PADDING:
2666 Vector4 padding = property.Get< Vector4 >();
2667 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2668 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2672 case Dali::Actor::Property::MINIMUM_SIZE:
2674 Vector2 size = property.Get< Vector2 >();
2675 SetMinimumSize( size.x, Dimension::WIDTH );
2676 SetMinimumSize( size.y, Dimension::HEIGHT );
2680 case Dali::Actor::Property::MAXIMUM_SIZE:
2682 Vector2 size = property.Get< Vector2 >();
2683 SetMaximumSize( size.x, Dimension::WIDTH );
2684 SetMaximumSize( size.y, Dimension::HEIGHT );
2688 case Dali::DevelActor::Property::SIBLING_ORDER:
2692 if( property.Get( value ) )
2694 if( static_cast<unsigned int>(value) != mSiblingOrder )
2696 mSiblingOrder = value;
2699 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2706 case Dali::Actor::Property::CLIPPING_MODE:
2708 ClippingMode::Type convertedValue = mClippingMode;
2709 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2711 mClippingMode = convertedValue;
2714 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2722 // this can happen in the case of a non-animatable default property so just do nothing
2728 // TODO: This method needs to be removed
2729 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2731 switch( entry.GetType() )
2733 case Property::BOOLEAN:
2735 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2736 DALI_ASSERT_DEBUG( NULL != property );
2738 // property is being used in a separate thread; queue a message to set the property
2739 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2744 case Property::INTEGER:
2746 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2747 DALI_ASSERT_DEBUG( NULL != property );
2749 // property is being used in a separate thread; queue a message to set the property
2750 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2755 case Property::FLOAT:
2757 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2758 DALI_ASSERT_DEBUG( NULL != property );
2760 // property is being used in a separate thread; queue a message to set the property
2761 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2766 case Property::VECTOR2:
2768 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2769 DALI_ASSERT_DEBUG( NULL != property );
2771 // property is being used in a separate thread; queue a message to set the property
2772 if(entry.componentIndex == 0)
2774 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2776 else if(entry.componentIndex == 1)
2778 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2782 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2788 case Property::VECTOR3:
2790 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2791 DALI_ASSERT_DEBUG( NULL != property );
2793 // property is being used in a separate thread; queue a message to set the property
2794 if(entry.componentIndex == 0)
2796 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2798 else if(entry.componentIndex == 1)
2800 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2802 else if(entry.componentIndex == 2)
2804 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2808 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2814 case Property::VECTOR4:
2816 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2817 DALI_ASSERT_DEBUG( NULL != property );
2819 // property is being used in a separate thread; queue a message to set the property
2820 if(entry.componentIndex == 0)
2822 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2824 else if(entry.componentIndex == 1)
2826 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2828 else if(entry.componentIndex == 2)
2830 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2832 else if(entry.componentIndex == 3)
2834 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2838 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2844 case Property::ROTATION:
2846 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2847 DALI_ASSERT_DEBUG( NULL != property );
2849 // property is being used in a separate thread; queue a message to set the property
2850 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2855 case Property::MATRIX:
2857 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2858 DALI_ASSERT_DEBUG( NULL != property );
2860 // property is being used in a separate thread; queue a message to set the property
2861 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2866 case Property::MATRIX3:
2868 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2869 DALI_ASSERT_DEBUG( NULL != property );
2871 // property is being used in a separate thread; queue a message to set the property
2872 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2879 // nothing to do for other types
2884 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2886 Property::Value value;
2888 if( index >= DEFAULT_PROPERTY_COUNT )
2895 case Dali::Actor::Property::PARENT_ORIGIN:
2897 value = GetCurrentParentOrigin();
2901 case Dali::Actor::Property::PARENT_ORIGIN_X:
2903 value = GetCurrentParentOrigin().x;
2907 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2909 value = GetCurrentParentOrigin().y;
2913 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2915 value = GetCurrentParentOrigin().z;
2919 case Dali::Actor::Property::ANCHOR_POINT:
2921 value = GetCurrentAnchorPoint();
2925 case Dali::Actor::Property::ANCHOR_POINT_X:
2927 value = GetCurrentAnchorPoint().x;
2931 case Dali::Actor::Property::ANCHOR_POINT_Y:
2933 value = GetCurrentAnchorPoint().y;
2937 case Dali::Actor::Property::ANCHOR_POINT_Z:
2939 value = GetCurrentAnchorPoint().z;
2943 case Dali::Actor::Property::SIZE:
2945 Vector3 size = GetTargetSize();
2947 // Should return preferred size if size is fixed as set by SetSize
2948 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
2950 size.width = GetPreferredSize().width;
2952 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
2954 size.height = GetPreferredSize().height;
2962 case Dali::Actor::Property::SIZE_WIDTH:
2964 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
2966 // Should return preferred size if size is fixed as set by SetSize
2967 value = GetPreferredSize().width;
2971 value = GetTargetSize().width;
2976 case Dali::Actor::Property::SIZE_HEIGHT:
2978 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
2980 // Should return preferred size if size is fixed as set by SetSize
2981 value = GetPreferredSize().height;
2985 value = GetTargetSize().height;
2990 case Dali::Actor::Property::SIZE_DEPTH:
2992 value = GetTargetSize().depth;
2996 case Dali::Actor::Property::POSITION:
2998 value = GetTargetPosition();
3002 case Dali::Actor::Property::POSITION_X:
3004 value = GetTargetPosition().x;
3008 case Dali::Actor::Property::POSITION_Y:
3010 value = GetTargetPosition().y;
3014 case Dali::Actor::Property::POSITION_Z:
3016 value = GetTargetPosition().z;
3020 case Dali::Actor::Property::WORLD_POSITION:
3022 value = GetCurrentWorldPosition();
3026 case Dali::Actor::Property::WORLD_POSITION_X:
3028 value = GetCurrentWorldPosition().x;
3032 case Dali::Actor::Property::WORLD_POSITION_Y:
3034 value = GetCurrentWorldPosition().y;
3038 case Dali::Actor::Property::WORLD_POSITION_Z:
3040 value = GetCurrentWorldPosition().z;
3044 case Dali::Actor::Property::ORIENTATION:
3046 value = GetCurrentOrientation();
3050 case Dali::Actor::Property::WORLD_ORIENTATION:
3052 value = GetCurrentWorldOrientation();
3056 case Dali::Actor::Property::SCALE:
3058 value = GetCurrentScale();
3062 case Dali::Actor::Property::SCALE_X:
3064 value = GetCurrentScale().x;
3068 case Dali::Actor::Property::SCALE_Y:
3070 value = GetCurrentScale().y;
3074 case Dali::Actor::Property::SCALE_Z:
3076 value = GetCurrentScale().z;
3080 case Dali::Actor::Property::WORLD_SCALE:
3082 value = GetCurrentWorldScale();
3086 case Dali::Actor::Property::VISIBLE:
3088 value = IsVisible();
3092 case Dali::Actor::Property::COLOR:
3094 value = GetCurrentColor();
3098 case Dali::Actor::Property::COLOR_RED:
3100 value = GetCurrentColor().r;
3104 case Dali::Actor::Property::COLOR_GREEN:
3106 value = GetCurrentColor().g;
3110 case Dali::Actor::Property::COLOR_BLUE:
3112 value = GetCurrentColor().b;
3116 case Dali::Actor::Property::COLOR_ALPHA:
3118 value = GetCurrentColor().a;
3122 case Dali::Actor::Property::WORLD_COLOR:
3124 value = GetCurrentWorldColor();
3128 case Dali::Actor::Property::WORLD_MATRIX:
3130 value = GetCurrentWorldMatrix();
3134 case Dali::Actor::Property::NAME:
3140 case Dali::Actor::Property::SENSITIVE:
3142 value = IsSensitive();
3146 case Dali::Actor::Property::LEAVE_REQUIRED:
3148 value = GetLeaveRequired();
3152 case Dali::Actor::Property::INHERIT_POSITION:
3154 value = IsPositionInherited();
3158 case Dali::Actor::Property::INHERIT_ORIENTATION:
3160 value = IsOrientationInherited();
3164 case Dali::Actor::Property::INHERIT_SCALE:
3166 value = IsScaleInherited();
3170 case Dali::Actor::Property::COLOR_MODE:
3172 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3176 case Dali::Actor::Property::POSITION_INHERITANCE:
3178 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3182 case Dali::Actor::Property::DRAW_MODE:
3184 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3188 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3190 value = GetSizeModeFactor();
3194 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3196 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3200 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3202 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3206 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3208 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3212 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3214 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3218 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3220 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3224 case Dali::Actor::Property::PADDING:
3226 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3227 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3228 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3232 case Dali::Actor::Property::MINIMUM_SIZE:
3234 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3238 case Dali::Actor::Property::MAXIMUM_SIZE:
3240 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3244 case Dali::DevelActor::Property::SIBLING_ORDER:
3246 value = static_cast<int>(mSiblingOrder);
3250 case Dali::Actor::Property::CLIPPING_MODE:
3252 value = mClippingMode;
3260 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3265 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3267 // This method should only return an object connected to the scene-graph
3268 return OnStage() ? mNode : NULL;
3271 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3273 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3275 const PropertyBase* property( NULL );
3277 // This method should only return a property of an object connected to the scene-graph
3283 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3285 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3286 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3288 property = animatable->GetSceneGraphProperty();
3290 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3291 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3293 CustomPropertyMetadata* custom = FindCustomProperty( index );
3294 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3296 property = custom->GetSceneGraphProperty();
3298 else if( NULL != mNode )
3302 case Dali::Actor::Property::SIZE:
3303 property = &mNode->mSize;
3306 case Dali::Actor::Property::SIZE_WIDTH:
3307 property = &mNode->mSize;
3310 case Dali::Actor::Property::SIZE_HEIGHT:
3311 property = &mNode->mSize;
3314 case Dali::Actor::Property::SIZE_DEPTH:
3315 property = &mNode->mSize;
3318 case Dali::Actor::Property::POSITION:
3319 property = &mNode->mPosition;
3322 case Dali::Actor::Property::POSITION_X:
3323 property = &mNode->mPosition;
3326 case Dali::Actor::Property::POSITION_Y:
3327 property = &mNode->mPosition;
3330 case Dali::Actor::Property::POSITION_Z:
3331 property = &mNode->mPosition;
3334 case Dali::Actor::Property::ORIENTATION:
3335 property = &mNode->mOrientation;
3338 case Dali::Actor::Property::SCALE:
3339 property = &mNode->mScale;
3342 case Dali::Actor::Property::SCALE_X:
3343 property = &mNode->mScale;
3346 case Dali::Actor::Property::SCALE_Y:
3347 property = &mNode->mScale;
3350 case Dali::Actor::Property::SCALE_Z:
3351 property = &mNode->mScale;
3354 case Dali::Actor::Property::VISIBLE:
3355 property = &mNode->mVisible;
3358 case Dali::Actor::Property::COLOR:
3359 property = &mNode->mColor;
3362 case Dali::Actor::Property::COLOR_RED:
3363 property = &mNode->mColor;
3366 case Dali::Actor::Property::COLOR_GREEN:
3367 property = &mNode->mColor;
3370 case Dali::Actor::Property::COLOR_BLUE:
3371 property = &mNode->mColor;
3374 case Dali::Actor::Property::COLOR_ALPHA:
3375 property = &mNode->mColor;
3386 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3388 const PropertyInputImpl* property( NULL );
3390 // This method should only return a property of an object connected to the scene-graph
3396 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3398 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3399 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3401 property = animatable->GetSceneGraphProperty();
3403 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3404 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3406 CustomPropertyMetadata* custom = FindCustomProperty( index );
3407 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3408 property = custom->GetSceneGraphProperty();
3410 else if( NULL != mNode )
3414 case Dali::Actor::Property::PARENT_ORIGIN:
3415 property = &mNode->mParentOrigin;
3418 case Dali::Actor::Property::PARENT_ORIGIN_X:
3419 property = &mNode->mParentOrigin;
3422 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3423 property = &mNode->mParentOrigin;
3426 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3427 property = &mNode->mParentOrigin;
3430 case Dali::Actor::Property::ANCHOR_POINT:
3431 property = &mNode->mAnchorPoint;
3434 case Dali::Actor::Property::ANCHOR_POINT_X:
3435 property = &mNode->mAnchorPoint;
3438 case Dali::Actor::Property::ANCHOR_POINT_Y:
3439 property = &mNode->mAnchorPoint;
3442 case Dali::Actor::Property::ANCHOR_POINT_Z:
3443 property = &mNode->mAnchorPoint;
3446 case Dali::Actor::Property::SIZE:
3447 property = &mNode->mSize;
3450 case Dali::Actor::Property::SIZE_WIDTH:
3451 property = &mNode->mSize;
3454 case Dali::Actor::Property::SIZE_HEIGHT:
3455 property = &mNode->mSize;
3458 case Dali::Actor::Property::SIZE_DEPTH:
3459 property = &mNode->mSize;
3462 case Dali::Actor::Property::POSITION:
3463 property = &mNode->mPosition;
3466 case Dali::Actor::Property::POSITION_X:
3467 property = &mNode->mPosition;
3470 case Dali::Actor::Property::POSITION_Y:
3471 property = &mNode->mPosition;
3474 case Dali::Actor::Property::POSITION_Z:
3475 property = &mNode->mPosition;
3478 case Dali::Actor::Property::WORLD_POSITION:
3479 property = &mNode->mWorldPosition;
3482 case Dali::Actor::Property::WORLD_POSITION_X:
3483 property = &mNode->mWorldPosition;
3486 case Dali::Actor::Property::WORLD_POSITION_Y:
3487 property = &mNode->mWorldPosition;
3490 case Dali::Actor::Property::WORLD_POSITION_Z:
3491 property = &mNode->mWorldPosition;
3494 case Dali::Actor::Property::ORIENTATION:
3495 property = &mNode->mOrientation;
3498 case Dali::Actor::Property::WORLD_ORIENTATION:
3499 property = &mNode->mWorldOrientation;
3502 case Dali::Actor::Property::SCALE:
3503 property = &mNode->mScale;
3506 case Dali::Actor::Property::SCALE_X:
3507 property = &mNode->mScale;
3510 case Dali::Actor::Property::SCALE_Y:
3511 property = &mNode->mScale;
3514 case Dali::Actor::Property::SCALE_Z:
3515 property = &mNode->mScale;
3518 case Dali::Actor::Property::WORLD_SCALE:
3519 property = &mNode->mWorldScale;
3522 case Dali::Actor::Property::VISIBLE:
3523 property = &mNode->mVisible;
3526 case Dali::Actor::Property::COLOR:
3527 property = &mNode->mColor;
3530 case Dali::Actor::Property::COLOR_RED:
3531 property = &mNode->mColor;
3534 case Dali::Actor::Property::COLOR_GREEN:
3535 property = &mNode->mColor;
3538 case Dali::Actor::Property::COLOR_BLUE:
3539 property = &mNode->mColor;
3542 case Dali::Actor::Property::COLOR_ALPHA:
3543 property = &mNode->mColor;
3546 case Dali::Actor::Property::WORLD_COLOR:
3547 property = &mNode->mWorldColor;
3550 case Dali::Actor::Property::WORLD_MATRIX:
3551 property = &mNode->mWorldMatrix;
3562 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3564 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3566 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3568 // check whether the animatable property is registered already, if not then register one.
3569 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3570 if( animatableProperty )
3572 componentIndex = animatableProperty->componentIndex;
3579 case Dali::Actor::Property::PARENT_ORIGIN_X:
3580 case Dali::Actor::Property::ANCHOR_POINT_X:
3581 case Dali::Actor::Property::SIZE_WIDTH:
3582 case Dali::Actor::Property::POSITION_X:
3583 case Dali::Actor::Property::WORLD_POSITION_X:
3584 case Dali::Actor::Property::SCALE_X:
3585 case Dali::Actor::Property::COLOR_RED:
3591 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3592 case Dali::Actor::Property::ANCHOR_POINT_Y:
3593 case Dali::Actor::Property::SIZE_HEIGHT:
3594 case Dali::Actor::Property::POSITION_Y:
3595 case Dali::Actor::Property::WORLD_POSITION_Y:
3596 case Dali::Actor::Property::SCALE_Y:
3597 case Dali::Actor::Property::COLOR_GREEN:
3603 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3604 case Dali::Actor::Property::ANCHOR_POINT_Z:
3605 case Dali::Actor::Property::SIZE_DEPTH:
3606 case Dali::Actor::Property::POSITION_Z:
3607 case Dali::Actor::Property::WORLD_POSITION_Z:
3608 case Dali::Actor::Property::SCALE_Z:
3609 case Dali::Actor::Property::COLOR_BLUE:
3615 case Dali::Actor::Property::COLOR_ALPHA:
3629 return componentIndex;
3632 void Actor::SetParent( Actor* parent )
3636 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3640 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3643 // Instruct each actor to create a corresponding node in the scene graph
3644 ConnectToStage( parent->GetHierarchyDepth() );
3647 // Resolve the name and index for the child properties if any
3648 ResolveChildProperties();
3650 else // parent being set to NULL
3652 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3656 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3659 DALI_ASSERT_ALWAYS( mNode != NULL );
3663 // Disconnect the Node & its children from the scene-graph.
3664 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3667 // Instruct each actor to discard pointers to the scene-graph
3668 DisconnectFromStage();
3673 SceneGraph::Node* Actor::CreateNode() const
3678 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3681 Actor* actor = dynamic_cast< Actor* >( object );
3685 if( 0 == actionName.compare( ACTION_SHOW ) )
3687 actor->SetVisible( true );
3690 else if( 0 == actionName.compare( ACTION_HIDE ) )
3692 actor->SetVisible( false );
3700 void Actor::EnsureRelayoutData()
3702 // Assign relayout data.
3703 if( !mRelayoutData )
3705 mRelayoutData = new RelayoutData();
3709 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3711 // Check if actor is dependent on parent
3712 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3714 if( ( dimension & ( 1 << i ) ) )
3716 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3717 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3727 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3729 // Check if actor is dependent on children
3730 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3732 if( ( dimension & ( 1 << i ) ) )
3734 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3735 switch( resizePolicy )
3737 case ResizePolicy::FIT_TO_CHILDREN:
3738 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3754 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3756 return Actor::RelayoutDependentOnChildren( dimension );
3759 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3761 // Check each possible dimension and see if it is dependent on the input one
3762 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3764 if( dimension & ( 1 << i ) )
3766 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3773 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3775 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3777 if( dimension & ( 1 << i ) )
3779 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3784 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3786 // If more than one dimension is requested, just return the first one found
3787 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3789 if( ( dimension & ( 1 << i ) ) )
3791 return mRelayoutData->negotiatedDimensions[ i ];
3795 return 0.0f; // Default
3798 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3800 EnsureRelayoutData();
3802 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3804 if( dimension & ( 1 << i ) )
3806 mRelayoutData->dimensionPadding[ i ] = padding;
3811 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3813 if ( mRelayoutData )
3815 // If more than one dimension is requested, just return the first one found
3816 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3818 if( ( dimension & ( 1 << i ) ) )
3820 return mRelayoutData->dimensionPadding[ i ];
3825 return GetDefaultDimensionPadding();
3828 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3830 EnsureRelayoutData();
3832 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3834 if( dimension & ( 1 << i ) )
3836 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3841 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3843 if ( mRelayoutData )
3845 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3847 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3857 float Actor::GetHeightForWidthBase( float width )
3859 float height = 0.0f;
3861 const Vector3 naturalSize = GetNaturalSize();
3862 if( naturalSize.width > 0.0f )
3864 height = naturalSize.height * width / naturalSize.width;
3866 else // we treat 0 as 1:1 aspect ratio
3874 float Actor::GetWidthForHeightBase( float height )
3878 const Vector3 naturalSize = GetNaturalSize();
3879 if( naturalSize.height > 0.0f )
3881 width = naturalSize.width * height / naturalSize.height;
3883 else // we treat 0 as 1:1 aspect ratio
3891 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3893 // Fill to parent, taking size mode factor into account
3894 switch( child.GetResizePolicy( dimension ) )
3896 case ResizePolicy::FILL_TO_PARENT:
3898 return GetLatestSize( dimension );
3901 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3903 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3906 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3908 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3913 return GetLatestSize( dimension );
3918 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3920 // Can be overridden in derived class
3921 return CalculateChildSizeBase( child, dimension );
3924 float Actor::GetHeightForWidth( float width )
3926 // Can be overridden in derived class
3927 return GetHeightForWidthBase( width );
3930 float Actor::GetWidthForHeight( float height )
3932 // Can be overridden in derived class
3933 return GetWidthForHeightBase( height );
3936 float Actor::GetLatestSize( Dimension::Type dimension ) const
3938 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3941 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3943 Vector2 padding = GetPadding( dimension );
3945 return GetLatestSize( dimension ) + padding.x + padding.y;
3948 float Actor::NegotiateFromParent( Dimension::Type dimension )
3950 Actor* parent = GetParent();
3953 Vector2 padding( GetPadding( dimension ) );
3954 Vector2 parentPadding( parent->GetPadding( dimension ) );
3955 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3961 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3963 float maxDimensionPoint = 0.0f;
3965 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3967 ActorPtr child = GetChildAt( i );
3969 if( !child->RelayoutDependentOnParent( dimension ) )
3971 // Calculate the min and max points that the children range across
3972 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3973 float dimensionSize = child->GetRelayoutSize( dimension );
3974 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3978 return maxDimensionPoint;
3981 float Actor::GetSize( Dimension::Type dimension ) const
3983 return GetDimensionValue( GetTargetSize(), dimension );
3986 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3988 return GetDimensionValue( GetNaturalSize(), dimension );
3991 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3993 switch( GetResizePolicy( dimension ) )
3995 case ResizePolicy::USE_NATURAL_SIZE:
3997 return GetNaturalSize( dimension );
4000 case ResizePolicy::FIXED:
4002 return GetDimensionValue( GetPreferredSize(), dimension );
4005 case ResizePolicy::USE_ASSIGNED_SIZE:
4007 return GetDimensionValue( maximumSize, dimension );
4010 case ResizePolicy::FILL_TO_PARENT:
4011 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4012 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4014 return NegotiateFromParent( dimension );
4017 case ResizePolicy::FIT_TO_CHILDREN:
4019 return NegotiateFromChildren( dimension );
4022 case ResizePolicy::DIMENSION_DEPENDENCY:
4024 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4027 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4029 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4032 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4034 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4046 return 0.0f; // Default
4049 float Actor::ClampDimension( float size, Dimension::Type dimension )
4051 const float minSize = GetMinimumSize( dimension );
4052 const float maxSize = GetMaximumSize( dimension );
4054 return std::max( minSize, std::min( size, maxSize ) );
4057 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4059 // Check if it needs to be negotiated
4060 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4062 // Check that we havn't gotten into an infinite loop
4063 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4064 bool recursionFound = false;
4065 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4067 if( *it == searchActor )
4069 recursionFound = true;
4074 if( !recursionFound )
4076 // Record the path that we have taken
4077 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4079 // Dimension dependency check
4080 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4082 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4084 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4086 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4090 // Parent dependency check
4091 Actor* parent = GetParent();
4092 if( parent && RelayoutDependentOnParent( dimension ) )
4094 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4097 // Children dependency check
4098 if( RelayoutDependentOnChildren( dimension ) )
4100 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4102 ActorPtr child = GetChildAt( i );
4104 // Only relayout child first if it is not dependent on this actor
4105 if( !child->RelayoutDependentOnParent( dimension ) )
4107 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4112 // For deriving classes
4113 OnCalculateRelayoutSize( dimension );
4115 // All dependencies checked, calculate the size and set negotiated flag
4116 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4118 SetNegotiatedDimension( newSize, dimension );
4119 SetLayoutNegotiated( true, dimension );
4121 // For deriving classes
4122 OnLayoutNegotiated( newSize, dimension );
4124 // This actor has been successfully processed, pop it off the recursion stack
4125 recursionStack.pop_back();
4129 // TODO: Break infinite loop
4130 SetLayoutNegotiated( true, dimension );
4135 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4137 // Negotiate all dimensions that require it
4138 ActorDimensionStack recursionStack;
4140 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4142 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4145 NegotiateDimension( dimension, allocatedSize, recursionStack );
4149 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4151 switch( mRelayoutData->sizeSetPolicy )
4153 case SizeScalePolicy::USE_SIZE_SET:
4158 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4160 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4161 const Vector3 naturalSize = GetNaturalSize();
4162 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4164 const float sizeRatio = size.width / size.height;
4165 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4167 if( naturalSizeRatio < sizeRatio )
4169 return Vector2( naturalSizeRatio * size.height, size.height );
4171 else if( naturalSizeRatio > sizeRatio )
4173 return Vector2( size.width, size.width / naturalSizeRatio );
4184 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4186 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4187 const Vector3 naturalSize = GetNaturalSize();
4188 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4190 const float sizeRatio = size.width / size.height;
4191 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4193 if( naturalSizeRatio < sizeRatio )
4195 return Vector2( size.width, size.width / naturalSizeRatio );
4197 else if( naturalSizeRatio > sizeRatio )
4199 return Vector2( naturalSizeRatio * size.height, size.height );
4218 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4220 // Do the set actor size
4221 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4223 // Adjust for size set policy
4224 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4226 // Lock the flag to stop recursive relayouts on set size
4227 mRelayoutData->insideRelayout = true;
4228 SetSize( negotiatedSize );
4229 mRelayoutData->insideRelayout = false;
4231 // Clear flags for all dimensions
4232 SetLayoutDirty( false );
4234 // Give deriving classes a chance to respond
4235 OnRelayout( negotiatedSize, container );
4237 if( !mOnRelayoutSignal.Empty() )
4239 Dali::Actor handle( this );
4240 mOnRelayoutSignal.Emit( handle );
4244 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4246 // Force a size negotiation for actors that has assigned size during relayout
4247 // This is required as otherwise the flags that force a relayout will not
4248 // necessarilly be set. This will occur if the actor has already been laid out.
4249 // The dirty flags are then cleared. Then if the actor is added back into the
4250 // relayout container afterwards, the dirty flags would still be clear...
4251 // causing a relayout to be skipped. Here we force any actors added to the
4252 // container to be relayed out.
4253 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4255 SetLayoutNegotiated(false, Dimension::WIDTH);
4257 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4259 SetLayoutNegotiated(false, Dimension::HEIGHT);
4262 // Do the negotiation
4263 NegotiateDimensions( allocatedSize );
4265 // Set the actor size
4266 SetNegotiatedSize( container );
4268 // Negotiate down to children
4269 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4271 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4273 ActorPtr child = GetChildAt( i );
4275 // Forces children that have already been laid out to be relayed out
4276 // if they have assigned size during relayout.
4277 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4279 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4280 child->SetLayoutDirty(true, Dimension::WIDTH);
4282 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4284 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4285 child->SetLayoutDirty(true, Dimension::HEIGHT);
4288 // Only relayout if required
4289 if( child->RelayoutRequired() )
4291 container.Add( Dali::Actor( child.Get() ), newBounds );
4296 void Actor::RelayoutRequest( Dimension::Type dimension )
4298 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4299 if( relayoutController )
4301 Dali::Actor self( this );
4302 relayoutController->RequestRelayout( self, dimension );
4306 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4310 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4314 void Actor::SetPreferredSize( const Vector2& size )
4316 EnsureRelayoutData();
4318 if( size.width > 0.0f )
4320 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4323 if( size.height > 0.0f )
4325 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4328 mRelayoutData->preferredSize = size;
4333 Vector2 Actor::GetPreferredSize() const
4335 if ( mRelayoutData )
4337 return Vector2( mRelayoutData->preferredSize );
4340 return GetDefaultPreferredSize();
4343 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4345 EnsureRelayoutData();
4347 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4349 if( dimension & ( 1 << i ) )
4351 mRelayoutData->minimumSize[ i ] = size;
4358 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4360 if ( mRelayoutData )
4362 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4364 if( dimension & ( 1 << i ) )
4366 return mRelayoutData->minimumSize[ i ];
4371 return 0.0f; // Default
4374 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4376 EnsureRelayoutData();
4378 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4380 if( dimension & ( 1 << i ) )
4382 mRelayoutData->maximumSize[ i ] = size;
4389 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4391 if ( mRelayoutData )
4393 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4395 if( dimension & ( 1 << i ) )
4397 return mRelayoutData->maximumSize[ i ];
4402 return FLT_MAX; // Default
4405 Object* Actor::GetParentObject() const
4410 } // namespace Internal