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 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1300 if( dimension & ( 1 << i ) )
1302 mRelayoutData->resizePolicies[ i ] = policy;
1306 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1308 if( dimension & Dimension::WIDTH )
1310 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1313 if( dimension & Dimension::HEIGHT )
1315 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1319 // If calling SetResizePolicy, assume we want relayout enabled
1320 SetRelayoutEnabled( true );
1322 OnSetResizePolicy( policy, dimension );
1324 // Trigger relayout on this control
1328 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1330 if ( mRelayoutData )
1332 // If more than one dimension is requested, just return the first one found
1333 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1335 if( ( dimension & ( 1 << i ) ) )
1337 return mRelayoutData->resizePolicies[ i ];
1342 return ResizePolicy::DEFAULT;
1345 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1347 EnsureRelayoutData();
1349 mRelayoutData->sizeSetPolicy = policy;
1352 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1354 if ( mRelayoutData )
1356 return mRelayoutData->sizeSetPolicy;
1359 return DEFAULT_SIZE_SCALE_POLICY;
1362 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1364 EnsureRelayoutData();
1366 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1368 if( dimension & ( 1 << i ) )
1370 mRelayoutData->dimensionDependencies[ i ] = dependency;
1375 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1377 if ( mRelayoutData )
1379 // If more than one dimension is requested, just return the first one found
1380 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1382 if( ( dimension & ( 1 << i ) ) )
1384 return mRelayoutData->dimensionDependencies[ i ];
1389 return Dimension::ALL_DIMENSIONS; // Default
1392 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1394 // If relayout data has not been allocated yet and the client is requesting
1395 // to disable it, do nothing
1396 if( mRelayoutData || relayoutEnabled )
1398 EnsureRelayoutData();
1400 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1402 mRelayoutData->relayoutEnabled = relayoutEnabled;
1406 bool Actor::IsRelayoutEnabled() const
1408 // Assume that if relayout data has not been allocated yet then
1409 // relayout is disabled
1410 return mRelayoutData && mRelayoutData->relayoutEnabled;
1413 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1415 EnsureRelayoutData();
1417 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1419 if( dimension & ( 1 << i ) )
1421 mRelayoutData->dimensionDirty[ i ] = dirty;
1426 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1428 if ( mRelayoutData )
1430 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1432 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1442 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1444 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1447 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1449 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1452 unsigned int Actor::AddRenderer( Renderer& renderer )
1456 mRenderers = new RendererContainer;
1459 unsigned int index = mRenderers->size();
1460 RendererPtr rendererPtr = RendererPtr( &renderer );
1461 mRenderers->push_back( rendererPtr );
1462 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1466 unsigned int Actor::GetRendererCount() const
1468 unsigned int rendererCount(0);
1471 rendererCount = mRenderers->size();
1474 return rendererCount;
1477 RendererPtr Actor::GetRendererAt( unsigned int index )
1479 RendererPtr renderer;
1480 if( index < GetRendererCount() )
1482 renderer = ( *mRenderers )[ index ];
1488 void Actor::RemoveRenderer( Renderer& renderer )
1492 RendererIter end = mRenderers->end();
1493 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1495 if( (*iter).Get() == &renderer )
1497 mRenderers->erase( iter );
1498 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1505 void Actor::RemoveRenderer( unsigned int index )
1507 if( index < GetRendererCount() )
1509 RendererPtr renderer = ( *mRenderers )[ index ];
1510 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1511 mRenderers->erase( mRenderers->begin()+index );
1515 bool Actor::IsOverlay() const
1517 return ( DrawMode::OVERLAY_2D == mDrawMode );
1520 void Actor::SetDrawMode( DrawMode::Type drawMode )
1522 // this flag is not animatable so keep the value
1523 mDrawMode = drawMode;
1524 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1526 // mNode is being used in a separate thread; queue a message to set the value
1527 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1531 DrawMode::Type Actor::GetDrawMode() const
1536 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1538 // only valid when on-stage
1539 StagePtr stage = Stage::GetCurrent();
1540 if( stage && OnStage() )
1542 const RenderTaskList& taskList = stage->GetRenderTaskList();
1544 Vector2 converted( screenX, screenY );
1546 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1547 const int taskCount = taskList.GetTaskCount();
1548 for( int i = taskCount - 1; i >= 0; --i )
1550 Dali::RenderTask task = taskList.GetTask( i );
1551 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1553 // found a task where this conversion was ok so return
1561 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1563 bool retval = false;
1564 // only valid when on-stage
1567 CameraActor* camera = renderTask.GetCameraActor();
1571 renderTask.GetViewport( viewport );
1573 // need to translate coordinates to render tasks coordinate space
1574 Vector2 converted( screenX, screenY );
1575 if( renderTask.TranslateCoordinates( converted ) )
1577 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1584 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1586 // Early-out if mNode is NULL
1592 // Get the ModelView matrix
1594 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1596 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1597 Matrix invertedMvp( false/*don't init*/);
1598 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1599 bool success = invertedMvp.Invert();
1601 // Convert to GL coordinates
1602 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1607 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1614 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1620 if( XyPlaneIntersect( nearPos, farPos, local ) )
1622 Vector3 size = GetCurrentSize();
1623 localX = local.x + size.x * 0.5f;
1624 localY = local.y + size.y * 0.5f;
1635 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1638 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1640 Mathematical Formulation
1642 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1644 ( p - c ) dot ( p - c ) = r^2
1646 Given a ray with a point of origin 'o', and a direction vector 'd':
1648 ray(t) = o + td, t >= 0
1650 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1652 (o + td - c ) dot ( o + td - c ) = r^2
1654 To solve for t we first expand the above into a more recognisable quadratic equation form
1656 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1665 B = 2( o - c ) dot d
1666 C = ( o - c ) dot ( o - c ) - r^2
1668 which can be solved using a standard quadratic formula.
1670 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1672 Practical Simplification
1674 In a renderer, we often differentiate between world space and object space. In the object space
1675 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1676 into object space, the mathematical solution presented above can be simplified significantly.
1678 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1682 and we can find the t at which the (transformed) ray intersects the sphere by
1684 ( o + td ) dot ( o + td ) = r^2
1686 According to the reasoning above, we expand the above quadratic equation into the general form
1690 which now has coefficients:
1697 // Early out if mNode is NULL
1703 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1705 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1706 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1707 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1709 // Compute the radius is not needed, square radius it's enough.
1710 const Vector3& size( mNode->GetSize( bufferIndex ) );
1712 // Scale the sphere.
1713 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1715 const float width = size.width * scale.width;
1716 const float height = size.height * scale.height;
1718 float squareSphereRadius = 0.5f * ( width * width + height * height );
1720 float a = rayDir.Dot( rayDir ); // a
1721 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1722 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1724 return ( b2 * b2 - a * c ) >= 0.f;
1727 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1731 if( OnStage() && NULL != mNode )
1733 // Transforms the ray to the local reference system.
1734 // Calculate the inverse of Model matrix
1735 Matrix invModelMatrix( false/*don't init*/);
1737 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1738 invModelMatrix = mNode->GetWorldMatrix(0);
1739 invModelMatrix.Invert();
1741 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1742 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1744 // Test with the actor's XY plane (Normal = 0 0 1 1).
1746 float a = -rayOriginLocal.z;
1747 float b = rayDirLocal.z;
1749 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1751 // Ray travels distance * rayDirLocal to intersect with plane.
1754 const Vector3& size = mNode->GetSize( bufferIndex );
1756 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1757 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1759 // Test with the actor's geometry.
1760 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1767 void Actor::SetLeaveRequired( bool required )
1769 mLeaveRequired = required;
1772 bool Actor::GetLeaveRequired() const
1774 return mLeaveRequired;
1777 void Actor::SetKeyboardFocusable( bool focusable )
1779 mKeyboardFocusable = focusable;
1782 bool Actor::IsKeyboardFocusable() const
1784 return mKeyboardFocusable;
1787 bool Actor::GetTouchRequired() const
1789 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1792 bool Actor::GetHoverRequired() const
1794 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1797 bool Actor::GetWheelEventRequired() const
1799 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1802 bool Actor::IsHittable() const
1804 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1807 ActorGestureData& Actor::GetGestureData()
1809 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1810 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1811 if( NULL == mGestureData )
1813 mGestureData = new ActorGestureData;
1815 return *mGestureData;
1818 bool Actor::IsGestureRequred( Gesture::Type type ) const
1820 return mGestureData && mGestureData->IsGestureRequred( type );
1823 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1825 bool consumed = false;
1827 if( !mTouchSignal.Empty() )
1829 Dali::Actor handle( this );
1830 consumed = mTouchSignal.Emit( handle, touch );
1833 if( !mTouchedSignal.Empty() )
1835 Dali::Actor handle( this );
1836 consumed |= mTouchedSignal.Emit( handle, event );
1841 // Notification for derived classes
1842 consumed = OnTouchEvent( event ); // TODO
1848 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1850 bool consumed = false;
1852 if( !mHoveredSignal.Empty() )
1854 Dali::Actor handle( this );
1855 consumed = mHoveredSignal.Emit( handle, event );
1860 // Notification for derived classes
1861 consumed = OnHoverEvent( event );
1867 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1869 bool consumed = false;
1871 if( !mWheelEventSignal.Empty() )
1873 Dali::Actor handle( this );
1874 consumed = mWheelEventSignal.Emit( handle, event );
1879 // Notification for derived classes
1880 consumed = OnWheelEvent( event );
1886 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1888 return mTouchedSignal;
1891 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1893 return mTouchSignal;
1896 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1898 return mHoveredSignal;
1901 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1903 return mWheelEventSignal;
1906 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1908 return mOnStageSignal;
1911 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1913 return mOffStageSignal;
1916 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1918 return mOnRelayoutSignal;
1921 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1923 bool connected( true );
1924 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1926 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1928 actor->TouchedSignal().Connect( tracker, functor );
1930 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1932 actor->HoveredSignal().Connect( tracker, functor );
1934 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1936 actor->WheelEventSignal().Connect( tracker, functor );
1938 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1940 actor->OnStageSignal().Connect( tracker, functor );
1942 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1944 actor->OffStageSignal().Connect( tracker, functor );
1946 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1948 actor->OnRelayoutSignal().Connect( tracker, functor );
1950 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1952 actor->TouchSignal().Connect( tracker, functor );
1956 // signalName does not match any signal
1963 Actor::Actor( DerivedType derivedType )
1968 mParentOrigin( NULL ),
1969 mAnchorPoint( NULL ),
1970 mRelayoutData( NULL ),
1971 mGestureData( NULL ),
1972 mTargetSize( 0.0f, 0.0f, 0.0f ),
1974 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1977 mIsRoot( ROOT_LAYER == derivedType ),
1978 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1979 mIsOnStage( false ),
1981 mLeaveRequired( false ),
1982 mKeyboardFocusable( false ),
1983 mDerivedRequiresTouch( false ),
1984 mDerivedRequiresHover( false ),
1985 mDerivedRequiresWheelEvent( false ),
1986 mOnStageSignalled( false ),
1987 mInsideOnSizeSet( false ),
1988 mInheritPosition( true ),
1989 mInheritOrientation( true ),
1990 mInheritScale( true ),
1991 mDrawMode( DrawMode::NORMAL ),
1992 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1993 mColorMode( Node::DEFAULT_COLOR_MODE ),
1994 mClippingMode( ClippingMode::DISABLED )
1998 void Actor::Initialize()
2001 SceneGraph::Node* node = CreateNode();
2003 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2004 mNode = node; // Keep raw-pointer to Node
2008 GetEventThreadServices().RegisterObject( this );
2013 // Remove mParent pointers from children even if we're destroying core,
2014 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2017 ActorConstIter endIter = mChildren->end();
2018 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2020 (*iter)->SetParent( NULL );
2026 // Guard to allow handle destruction after Core has been destroyed
2027 if( EventThreadServices::IsCoreRunning() )
2031 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2032 mNode = NULL; // Node is about to be destroyed
2035 GetEventThreadServices().UnregisterObject( this );
2038 // Cleanup optional gesture data
2039 delete mGestureData;
2041 // Cleanup optional parent origin and anchor
2042 delete mParentOrigin;
2043 delete mAnchorPoint;
2045 // Delete optional relayout data
2048 delete mRelayoutData;
2052 void Actor::ConnectToStage( unsigned int parentDepth )
2054 // This container is used instead of walking the Actor hierarchy.
2055 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2056 ActorContainer connectionList;
2058 // This stage is atomic i.e. not interrupted by user callbacks.
2059 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2061 // Notify applications about the newly connected actors.
2062 const ActorIter endIter = connectionList.end();
2063 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2065 (*iter)->NotifyStageConnection();
2071 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2073 DALI_ASSERT_ALWAYS( !OnStage() );
2077 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2079 ConnectToSceneGraph();
2081 // Notification for internal derived classes
2082 OnStageConnectionInternal();
2084 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2085 connectionList.push_back( ActorPtr( this ) );
2087 // Recursively connect children
2090 ActorConstIter endIter = mChildren->end();
2091 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2093 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2099 * This method is called when the Actor is connected to the Stage.
2100 * The parent must have added its Node to the scene-graph.
2101 * The child must connect its Node to the parent's Node.
2102 * This is recursive; the child calls ConnectToStage() for its children.
2104 void Actor::ConnectToSceneGraph()
2106 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2110 // Reparent Node in next Update
2111 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2114 // Request relayout on all actors that are added to the scenegraph
2117 // Notification for Object::Observers
2121 void Actor::NotifyStageConnection()
2123 // Actors can be removed (in a callback), before the on-stage stage is reported.
2124 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2125 if( OnStage() && !mOnStageSignalled )
2127 // Notification for external (CustomActor) derived classes
2128 OnStageConnectionExternal( mDepth );
2130 if( !mOnStageSignal.Empty() )
2132 Dali::Actor handle( this );
2133 mOnStageSignal.Emit( handle );
2136 // Guard against Remove during callbacks
2139 mOnStageSignalled = true; // signal required next time Actor is removed
2144 void Actor::DisconnectFromStage()
2146 // This container is used instead of walking the Actor hierachy.
2147 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2148 ActorContainer disconnectionList;
2150 // This stage is atomic i.e. not interrupted by user callbacks
2151 RecursiveDisconnectFromStage( disconnectionList );
2153 // Notify applications about the newly disconnected actors.
2154 const ActorIter endIter = disconnectionList.end();
2155 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2157 (*iter)->NotifyStageDisconnection();
2161 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2163 DALI_ASSERT_ALWAYS( OnStage() );
2165 // Recursively disconnect children
2168 ActorConstIter endIter = mChildren->end();
2169 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2171 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2175 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2176 disconnectionList.push_back( ActorPtr( this ) );
2178 // Notification for internal derived classes
2179 OnStageDisconnectionInternal();
2181 DisconnectFromSceneGraph();
2187 * This method is called by an actor or its parent, before a node removal message is sent.
2188 * This is recursive; the child calls DisconnectFromStage() for its children.
2190 void Actor::DisconnectFromSceneGraph()
2192 // Notification for Object::Observers
2193 OnSceneObjectRemove();
2196 void Actor::NotifyStageDisconnection()
2198 // Actors can be added (in a callback), before the off-stage state is reported.
2199 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2200 // only do this step if there is a stage, i.e. Core is not being shut down
2201 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2203 // Notification for external (CustomeActor) derived classes
2204 OnStageDisconnectionExternal();
2206 if( !mOffStageSignal.Empty() )
2208 Dali::Actor handle( this );
2209 mOffStageSignal.Emit( handle );
2212 // Guard against Add during callbacks
2215 mOnStageSignalled = false; // signal required next time Actor is added
2220 bool Actor::IsNodeConnected() const
2222 bool connected( false );
2224 if( OnStage() && ( NULL != mNode ) )
2226 if( IsRoot() || mNode->GetParent() )
2235 unsigned int Actor::GetDefaultPropertyCount() const
2237 return DEFAULT_PROPERTY_COUNT;
2240 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2242 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2244 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2246 indices.PushBack( i );
2250 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2252 if( index < DEFAULT_PROPERTY_COUNT )
2254 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2260 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2262 Property::Index index = Property::INVALID_INDEX;
2264 // Look for name in default properties
2265 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2267 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2268 if( 0 == name.compare( property->name ) )
2278 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2280 if( index < DEFAULT_PROPERTY_COUNT )
2282 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2288 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2290 if( index < DEFAULT_PROPERTY_COUNT )
2292 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2298 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2300 if( index < DEFAULT_PROPERTY_COUNT )
2302 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2308 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2310 if( index < DEFAULT_PROPERTY_COUNT )
2312 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2315 // index out of range...return Property::NONE
2316 return Property::NONE;
2319 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2323 case Dali::Actor::Property::PARENT_ORIGIN:
2325 Property::Type type = property.GetType();
2326 if( type == Property::VECTOR3 )
2328 SetParentOrigin( property.Get< Vector3 >() );
2330 else if ( type == Property::STRING )
2332 std::string parentOriginString;
2333 property.Get( parentOriginString );
2334 Vector3 parentOrigin;
2335 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2337 SetParentOrigin( parentOrigin );
2343 case Dali::Actor::Property::PARENT_ORIGIN_X:
2345 SetParentOriginX( property.Get< float >() );
2349 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2351 SetParentOriginY( property.Get< float >() );
2355 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2357 SetParentOriginZ( property.Get< float >() );
2361 case Dali::Actor::Property::ANCHOR_POINT:
2363 Property::Type type = property.GetType();
2364 if( type == Property::VECTOR3 )
2366 SetAnchorPoint( property.Get< Vector3 >() );
2368 else if ( type == Property::STRING )
2370 std::string anchorPointString;
2371 property.Get( anchorPointString );
2373 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2375 SetAnchorPoint( anchor );
2381 case Dali::Actor::Property::ANCHOR_POINT_X:
2383 SetAnchorPointX( property.Get< float >() );
2387 case Dali::Actor::Property::ANCHOR_POINT_Y:
2389 SetAnchorPointY( property.Get< float >() );
2393 case Dali::Actor::Property::ANCHOR_POINT_Z:
2395 SetAnchorPointZ( property.Get< float >() );
2399 case Dali::Actor::Property::SIZE:
2401 SetSize( property.Get< Vector3 >() );
2405 case Dali::Actor::Property::SIZE_WIDTH:
2407 SetWidth( property.Get< float >() );
2411 case Dali::Actor::Property::SIZE_HEIGHT:
2413 SetHeight( property.Get< float >() );
2417 case Dali::Actor::Property::SIZE_DEPTH:
2419 SetDepth( property.Get< float >() );
2423 case Dali::Actor::Property::POSITION:
2425 SetPosition( property.Get< Vector3 >() );
2429 case Dali::Actor::Property::POSITION_X:
2431 SetX( property.Get< float >() );
2435 case Dali::Actor::Property::POSITION_Y:
2437 SetY( property.Get< float >() );
2441 case Dali::Actor::Property::POSITION_Z:
2443 SetZ( property.Get< float >() );
2447 case Dali::Actor::Property::ORIENTATION:
2449 SetOrientation( property.Get< Quaternion >() );
2453 case Dali::Actor::Property::SCALE:
2455 SetScale( property.Get< Vector3 >() );
2459 case Dali::Actor::Property::SCALE_X:
2461 SetScaleX( property.Get< float >() );
2465 case Dali::Actor::Property::SCALE_Y:
2467 SetScaleY( property.Get< float >() );
2471 case Dali::Actor::Property::SCALE_Z:
2473 SetScaleZ( property.Get< float >() );
2477 case Dali::Actor::Property::VISIBLE:
2479 SetVisible( property.Get< bool >() );
2483 case Dali::Actor::Property::COLOR:
2485 SetColor( property.Get< Vector4 >() );
2489 case Dali::Actor::Property::COLOR_RED:
2491 SetColorRed( property.Get< float >() );
2495 case Dali::Actor::Property::COLOR_GREEN:
2497 SetColorGreen( property.Get< float >() );
2501 case Dali::Actor::Property::COLOR_BLUE:
2503 SetColorBlue( property.Get< float >() );
2507 case Dali::Actor::Property::COLOR_ALPHA:
2509 SetOpacity( property.Get< float >() );
2513 case Dali::Actor::Property::NAME:
2515 SetName( property.Get< std::string >() );
2519 case Dali::Actor::Property::SENSITIVE:
2521 SetSensitive( property.Get< bool >() );
2525 case Dali::Actor::Property::LEAVE_REQUIRED:
2527 SetLeaveRequired( property.Get< bool >() );
2531 case Dali::Actor::Property::INHERIT_POSITION:
2533 SetInheritPosition( property.Get< bool >() );
2537 case Dali::Actor::Property::INHERIT_ORIENTATION:
2539 SetInheritOrientation( property.Get< bool >() );
2543 case Dali::Actor::Property::INHERIT_SCALE:
2545 SetInheritScale( property.Get< bool >() );
2549 case Dali::Actor::Property::COLOR_MODE:
2551 ColorMode mode = mColorMode;
2552 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2554 SetColorMode( mode );
2559 case Dali::Actor::Property::POSITION_INHERITANCE:
2561 PositionInheritanceMode mode = mPositionInheritanceMode;
2562 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2564 SetPositionInheritanceMode( mode );
2569 case Dali::Actor::Property::DRAW_MODE:
2571 DrawMode::Type mode = mDrawMode;
2572 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2574 SetDrawMode( mode );
2579 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2581 SetSizeModeFactor( property.Get< Vector3 >() );
2585 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2587 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2588 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2590 SetResizePolicy( type, Dimension::WIDTH );
2595 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2597 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2598 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2600 SetResizePolicy( type, Dimension::HEIGHT );
2605 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2607 SizeScalePolicy::Type type;
2608 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2610 SetSizeScalePolicy( type );
2615 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2617 if( property.Get< bool >() )
2619 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2624 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2626 if( property.Get< bool >() )
2628 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2633 case Dali::Actor::Property::PADDING:
2635 Vector4 padding = property.Get< Vector4 >();
2636 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2637 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2641 case Dali::Actor::Property::MINIMUM_SIZE:
2643 Vector2 size = property.Get< Vector2 >();
2644 SetMinimumSize( size.x, Dimension::WIDTH );
2645 SetMinimumSize( size.y, Dimension::HEIGHT );
2649 case Dali::Actor::Property::MAXIMUM_SIZE:
2651 Vector2 size = property.Get< Vector2 >();
2652 SetMaximumSize( size.x, Dimension::WIDTH );
2653 SetMaximumSize( size.y, Dimension::HEIGHT );
2657 case Dali::DevelActor::Property::SIBLING_ORDER:
2661 if( property.Get( value ) )
2663 if( static_cast<unsigned int>(value) != mSiblingOrder )
2665 mSiblingOrder = value;
2668 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2675 case Dali::Actor::Property::CLIPPING_MODE:
2677 ClippingMode::Type convertedValue = mClippingMode;
2678 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2680 mClippingMode = convertedValue;
2683 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2691 // this can happen in the case of a non-animatable default property so just do nothing
2697 // TODO: This method needs to be removed
2698 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2700 switch( entry.GetType() )
2702 case Property::BOOLEAN:
2704 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2705 DALI_ASSERT_DEBUG( NULL != property );
2707 // property is being used in a separate thread; queue a message to set the property
2708 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2713 case Property::INTEGER:
2715 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2716 DALI_ASSERT_DEBUG( NULL != property );
2718 // property is being used in a separate thread; queue a message to set the property
2719 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2724 case Property::FLOAT:
2726 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2727 DALI_ASSERT_DEBUG( NULL != property );
2729 // property is being used in a separate thread; queue a message to set the property
2730 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2735 case Property::VECTOR2:
2737 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2738 DALI_ASSERT_DEBUG( NULL != property );
2740 // property is being used in a separate thread; queue a message to set the property
2741 if(entry.componentIndex == 0)
2743 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2745 else if(entry.componentIndex == 1)
2747 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2751 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2757 case Property::VECTOR3:
2759 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2760 DALI_ASSERT_DEBUG( NULL != property );
2762 // property is being used in a separate thread; queue a message to set the property
2763 if(entry.componentIndex == 0)
2765 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2767 else if(entry.componentIndex == 1)
2769 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2771 else if(entry.componentIndex == 2)
2773 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2777 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2783 case Property::VECTOR4:
2785 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2786 DALI_ASSERT_DEBUG( NULL != property );
2788 // property is being used in a separate thread; queue a message to set the property
2789 if(entry.componentIndex == 0)
2791 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2793 else if(entry.componentIndex == 1)
2795 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2797 else if(entry.componentIndex == 2)
2799 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2801 else if(entry.componentIndex == 3)
2803 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2807 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2813 case Property::ROTATION:
2815 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2816 DALI_ASSERT_DEBUG( NULL != property );
2818 // property is being used in a separate thread; queue a message to set the property
2819 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2824 case Property::MATRIX:
2826 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2827 DALI_ASSERT_DEBUG( NULL != property );
2829 // property is being used in a separate thread; queue a message to set the property
2830 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2835 case Property::MATRIX3:
2837 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2838 DALI_ASSERT_DEBUG( NULL != property );
2840 // property is being used in a separate thread; queue a message to set the property
2841 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2848 // nothing to do for other types
2853 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2855 Property::Value value;
2857 if( index >= DEFAULT_PROPERTY_COUNT )
2864 case Dali::Actor::Property::PARENT_ORIGIN:
2866 value = GetCurrentParentOrigin();
2870 case Dali::Actor::Property::PARENT_ORIGIN_X:
2872 value = GetCurrentParentOrigin().x;
2876 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2878 value = GetCurrentParentOrigin().y;
2882 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2884 value = GetCurrentParentOrigin().z;
2888 case Dali::Actor::Property::ANCHOR_POINT:
2890 value = GetCurrentAnchorPoint();
2894 case Dali::Actor::Property::ANCHOR_POINT_X:
2896 value = GetCurrentAnchorPoint().x;
2900 case Dali::Actor::Property::ANCHOR_POINT_Y:
2902 value = GetCurrentAnchorPoint().y;
2906 case Dali::Actor::Property::ANCHOR_POINT_Z:
2908 value = GetCurrentAnchorPoint().z;
2912 case Dali::Actor::Property::SIZE:
2914 value = GetTargetSize();
2918 case Dali::Actor::Property::SIZE_WIDTH:
2920 value = GetTargetSize().width;
2924 case Dali::Actor::Property::SIZE_HEIGHT:
2926 value = GetTargetSize().height;
2930 case Dali::Actor::Property::SIZE_DEPTH:
2932 value = GetTargetSize().depth;
2936 case Dali::Actor::Property::POSITION:
2938 value = GetTargetPosition();
2942 case Dali::Actor::Property::POSITION_X:
2944 value = GetTargetPosition().x;
2948 case Dali::Actor::Property::POSITION_Y:
2950 value = GetTargetPosition().y;
2954 case Dali::Actor::Property::POSITION_Z:
2956 value = GetTargetPosition().z;
2960 case Dali::Actor::Property::WORLD_POSITION:
2962 value = GetCurrentWorldPosition();
2966 case Dali::Actor::Property::WORLD_POSITION_X:
2968 value = GetCurrentWorldPosition().x;
2972 case Dali::Actor::Property::WORLD_POSITION_Y:
2974 value = GetCurrentWorldPosition().y;
2978 case Dali::Actor::Property::WORLD_POSITION_Z:
2980 value = GetCurrentWorldPosition().z;
2984 case Dali::Actor::Property::ORIENTATION:
2986 value = GetCurrentOrientation();
2990 case Dali::Actor::Property::WORLD_ORIENTATION:
2992 value = GetCurrentWorldOrientation();
2996 case Dali::Actor::Property::SCALE:
2998 value = GetCurrentScale();
3002 case Dali::Actor::Property::SCALE_X:
3004 value = GetCurrentScale().x;
3008 case Dali::Actor::Property::SCALE_Y:
3010 value = GetCurrentScale().y;
3014 case Dali::Actor::Property::SCALE_Z:
3016 value = GetCurrentScale().z;
3020 case Dali::Actor::Property::WORLD_SCALE:
3022 value = GetCurrentWorldScale();
3026 case Dali::Actor::Property::VISIBLE:
3028 value = IsVisible();
3032 case Dali::Actor::Property::COLOR:
3034 value = GetCurrentColor();
3038 case Dali::Actor::Property::COLOR_RED:
3040 value = GetCurrentColor().r;
3044 case Dali::Actor::Property::COLOR_GREEN:
3046 value = GetCurrentColor().g;
3050 case Dali::Actor::Property::COLOR_BLUE:
3052 value = GetCurrentColor().b;
3056 case Dali::Actor::Property::COLOR_ALPHA:
3058 value = GetCurrentColor().a;
3062 case Dali::Actor::Property::WORLD_COLOR:
3064 value = GetCurrentWorldColor();
3068 case Dali::Actor::Property::WORLD_MATRIX:
3070 value = GetCurrentWorldMatrix();
3074 case Dali::Actor::Property::NAME:
3080 case Dali::Actor::Property::SENSITIVE:
3082 value = IsSensitive();
3086 case Dali::Actor::Property::LEAVE_REQUIRED:
3088 value = GetLeaveRequired();
3092 case Dali::Actor::Property::INHERIT_POSITION:
3094 value = IsPositionInherited();
3098 case Dali::Actor::Property::INHERIT_ORIENTATION:
3100 value = IsOrientationInherited();
3104 case Dali::Actor::Property::INHERIT_SCALE:
3106 value = IsScaleInherited();
3110 case Dali::Actor::Property::COLOR_MODE:
3112 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3116 case Dali::Actor::Property::POSITION_INHERITANCE:
3118 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3122 case Dali::Actor::Property::DRAW_MODE:
3124 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3128 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3130 value = GetSizeModeFactor();
3134 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3136 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3140 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3142 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3146 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3148 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3152 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3154 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3158 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3160 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3164 case Dali::Actor::Property::PADDING:
3166 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3167 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3168 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3172 case Dali::Actor::Property::MINIMUM_SIZE:
3174 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3178 case Dali::Actor::Property::MAXIMUM_SIZE:
3180 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3184 case Dali::DevelActor::Property::SIBLING_ORDER:
3186 value = static_cast<int>(mSiblingOrder);
3190 case Dali::Actor::Property::CLIPPING_MODE:
3192 value = mClippingMode;
3200 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3205 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3207 // This method should only return an object connected to the scene-graph
3208 return OnStage() ? mNode : NULL;
3211 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3213 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3215 const PropertyBase* property( NULL );
3217 // This method should only return a property of an object connected to the scene-graph
3223 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3225 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3226 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3228 property = animatable->GetSceneGraphProperty();
3230 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3231 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3233 CustomPropertyMetadata* custom = FindCustomProperty( index );
3234 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3236 property = custom->GetSceneGraphProperty();
3238 else if( NULL != mNode )
3242 case Dali::Actor::Property::SIZE:
3243 property = &mNode->mSize;
3246 case Dali::Actor::Property::SIZE_WIDTH:
3247 property = &mNode->mSize;
3250 case Dali::Actor::Property::SIZE_HEIGHT:
3251 property = &mNode->mSize;
3254 case Dali::Actor::Property::SIZE_DEPTH:
3255 property = &mNode->mSize;
3258 case Dali::Actor::Property::POSITION:
3259 property = &mNode->mPosition;
3262 case Dali::Actor::Property::POSITION_X:
3263 property = &mNode->mPosition;
3266 case Dali::Actor::Property::POSITION_Y:
3267 property = &mNode->mPosition;
3270 case Dali::Actor::Property::POSITION_Z:
3271 property = &mNode->mPosition;
3274 case Dali::Actor::Property::ORIENTATION:
3275 property = &mNode->mOrientation;
3278 case Dali::Actor::Property::SCALE:
3279 property = &mNode->mScale;
3282 case Dali::Actor::Property::SCALE_X:
3283 property = &mNode->mScale;
3286 case Dali::Actor::Property::SCALE_Y:
3287 property = &mNode->mScale;
3290 case Dali::Actor::Property::SCALE_Z:
3291 property = &mNode->mScale;
3294 case Dali::Actor::Property::VISIBLE:
3295 property = &mNode->mVisible;
3298 case Dali::Actor::Property::COLOR:
3299 property = &mNode->mColor;
3302 case Dali::Actor::Property::COLOR_RED:
3303 property = &mNode->mColor;
3306 case Dali::Actor::Property::COLOR_GREEN:
3307 property = &mNode->mColor;
3310 case Dali::Actor::Property::COLOR_BLUE:
3311 property = &mNode->mColor;
3314 case Dali::Actor::Property::COLOR_ALPHA:
3315 property = &mNode->mColor;
3326 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3328 const PropertyInputImpl* property( NULL );
3330 // This method should only return a property of an object connected to the scene-graph
3336 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3338 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3339 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3341 property = animatable->GetSceneGraphProperty();
3343 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3344 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3346 CustomPropertyMetadata* custom = FindCustomProperty( index );
3347 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3348 property = custom->GetSceneGraphProperty();
3350 else if( NULL != mNode )
3354 case Dali::Actor::Property::PARENT_ORIGIN:
3355 property = &mNode->mParentOrigin;
3358 case Dali::Actor::Property::PARENT_ORIGIN_X:
3359 property = &mNode->mParentOrigin;
3362 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3363 property = &mNode->mParentOrigin;
3366 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3367 property = &mNode->mParentOrigin;
3370 case Dali::Actor::Property::ANCHOR_POINT:
3371 property = &mNode->mAnchorPoint;
3374 case Dali::Actor::Property::ANCHOR_POINT_X:
3375 property = &mNode->mAnchorPoint;
3378 case Dali::Actor::Property::ANCHOR_POINT_Y:
3379 property = &mNode->mAnchorPoint;
3382 case Dali::Actor::Property::ANCHOR_POINT_Z:
3383 property = &mNode->mAnchorPoint;
3386 case Dali::Actor::Property::SIZE:
3387 property = &mNode->mSize;
3390 case Dali::Actor::Property::SIZE_WIDTH:
3391 property = &mNode->mSize;
3394 case Dali::Actor::Property::SIZE_HEIGHT:
3395 property = &mNode->mSize;
3398 case Dali::Actor::Property::SIZE_DEPTH:
3399 property = &mNode->mSize;
3402 case Dali::Actor::Property::POSITION:
3403 property = &mNode->mPosition;
3406 case Dali::Actor::Property::POSITION_X:
3407 property = &mNode->mPosition;
3410 case Dali::Actor::Property::POSITION_Y:
3411 property = &mNode->mPosition;
3414 case Dali::Actor::Property::POSITION_Z:
3415 property = &mNode->mPosition;
3418 case Dali::Actor::Property::WORLD_POSITION:
3419 property = &mNode->mWorldPosition;
3422 case Dali::Actor::Property::WORLD_POSITION_X:
3423 property = &mNode->mWorldPosition;
3426 case Dali::Actor::Property::WORLD_POSITION_Y:
3427 property = &mNode->mWorldPosition;
3430 case Dali::Actor::Property::WORLD_POSITION_Z:
3431 property = &mNode->mWorldPosition;
3434 case Dali::Actor::Property::ORIENTATION:
3435 property = &mNode->mOrientation;
3438 case Dali::Actor::Property::WORLD_ORIENTATION:
3439 property = &mNode->mWorldOrientation;
3442 case Dali::Actor::Property::SCALE:
3443 property = &mNode->mScale;
3446 case Dali::Actor::Property::SCALE_X:
3447 property = &mNode->mScale;
3450 case Dali::Actor::Property::SCALE_Y:
3451 property = &mNode->mScale;
3454 case Dali::Actor::Property::SCALE_Z:
3455 property = &mNode->mScale;
3458 case Dali::Actor::Property::WORLD_SCALE:
3459 property = &mNode->mWorldScale;
3462 case Dali::Actor::Property::VISIBLE:
3463 property = &mNode->mVisible;
3466 case Dali::Actor::Property::COLOR:
3467 property = &mNode->mColor;
3470 case Dali::Actor::Property::COLOR_RED:
3471 property = &mNode->mColor;
3474 case Dali::Actor::Property::COLOR_GREEN:
3475 property = &mNode->mColor;
3478 case Dali::Actor::Property::COLOR_BLUE:
3479 property = &mNode->mColor;
3482 case Dali::Actor::Property::COLOR_ALPHA:
3483 property = &mNode->mColor;
3486 case Dali::Actor::Property::WORLD_COLOR:
3487 property = &mNode->mWorldColor;
3490 case Dali::Actor::Property::WORLD_MATRIX:
3491 property = &mNode->mWorldMatrix;
3502 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3504 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3506 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3508 // check whether the animatable property is registered already, if not then register one.
3509 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3510 if( animatableProperty )
3512 componentIndex = animatableProperty->componentIndex;
3519 case Dali::Actor::Property::PARENT_ORIGIN_X:
3520 case Dali::Actor::Property::ANCHOR_POINT_X:
3521 case Dali::Actor::Property::SIZE_WIDTH:
3522 case Dali::Actor::Property::POSITION_X:
3523 case Dali::Actor::Property::WORLD_POSITION_X:
3524 case Dali::Actor::Property::SCALE_X:
3525 case Dali::Actor::Property::COLOR_RED:
3531 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3532 case Dali::Actor::Property::ANCHOR_POINT_Y:
3533 case Dali::Actor::Property::SIZE_HEIGHT:
3534 case Dali::Actor::Property::POSITION_Y:
3535 case Dali::Actor::Property::WORLD_POSITION_Y:
3536 case Dali::Actor::Property::SCALE_Y:
3537 case Dali::Actor::Property::COLOR_GREEN:
3543 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3544 case Dali::Actor::Property::ANCHOR_POINT_Z:
3545 case Dali::Actor::Property::SIZE_DEPTH:
3546 case Dali::Actor::Property::POSITION_Z:
3547 case Dali::Actor::Property::WORLD_POSITION_Z:
3548 case Dali::Actor::Property::SCALE_Z:
3549 case Dali::Actor::Property::COLOR_BLUE:
3555 case Dali::Actor::Property::COLOR_ALPHA:
3569 return componentIndex;
3572 void Actor::SetParent( Actor* parent )
3576 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3580 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3583 // Instruct each actor to create a corresponding node in the scene graph
3584 ConnectToStage( parent->GetHierarchyDepth() );
3587 // Resolve the name and index for the child properties if any
3588 ResolveChildProperties();
3590 else // parent being set to NULL
3592 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3596 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3599 DALI_ASSERT_ALWAYS( mNode != NULL );
3603 // Disconnect the Node & its children from the scene-graph.
3604 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3607 // Instruct each actor to discard pointers to the scene-graph
3608 DisconnectFromStage();
3613 SceneGraph::Node* Actor::CreateNode() const
3618 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3621 Actor* actor = dynamic_cast< Actor* >( object );
3625 if( 0 == actionName.compare( ACTION_SHOW ) )
3627 actor->SetVisible( true );
3630 else if( 0 == actionName.compare( ACTION_HIDE ) )
3632 actor->SetVisible( false );
3640 void Actor::EnsureRelayoutData()
3642 // Assign relayout data.
3643 if( !mRelayoutData )
3645 mRelayoutData = new RelayoutData();
3649 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3651 // Check if actor is dependent on parent
3652 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3654 if( ( dimension & ( 1 << i ) ) )
3656 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3657 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3667 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3669 // Check if actor is dependent on children
3670 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3672 if( ( dimension & ( 1 << i ) ) )
3674 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3675 switch( resizePolicy )
3677 case ResizePolicy::FIT_TO_CHILDREN:
3678 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3694 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3696 return Actor::RelayoutDependentOnChildren( dimension );
3699 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3701 // Check each possible dimension and see if it is dependent on the input one
3702 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3704 if( dimension & ( 1 << i ) )
3706 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3713 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3715 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3717 if( dimension & ( 1 << i ) )
3719 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3724 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3726 // If more than one dimension is requested, just return the first one found
3727 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3729 if( ( dimension & ( 1 << i ) ) )
3731 return mRelayoutData->negotiatedDimensions[ i ];
3735 return 0.0f; // Default
3738 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3740 EnsureRelayoutData();
3742 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3744 if( dimension & ( 1 << i ) )
3746 mRelayoutData->dimensionPadding[ i ] = padding;
3751 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3753 if ( mRelayoutData )
3755 // If more than one dimension is requested, just return the first one found
3756 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3758 if( ( dimension & ( 1 << i ) ) )
3760 return mRelayoutData->dimensionPadding[ i ];
3765 return GetDefaultDimensionPadding();
3768 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3770 EnsureRelayoutData();
3772 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3774 if( dimension & ( 1 << i ) )
3776 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3781 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3783 if ( mRelayoutData )
3785 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3787 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3797 float Actor::GetHeightForWidthBase( float width )
3799 float height = 0.0f;
3801 const Vector3 naturalSize = GetNaturalSize();
3802 if( naturalSize.width > 0.0f )
3804 height = naturalSize.height * width / naturalSize.width;
3806 else // we treat 0 as 1:1 aspect ratio
3814 float Actor::GetWidthForHeightBase( float height )
3818 const Vector3 naturalSize = GetNaturalSize();
3819 if( naturalSize.height > 0.0f )
3821 width = naturalSize.width * height / naturalSize.height;
3823 else // we treat 0 as 1:1 aspect ratio
3831 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3833 // Fill to parent, taking size mode factor into account
3834 switch( child.GetResizePolicy( dimension ) )
3836 case ResizePolicy::FILL_TO_PARENT:
3838 return GetLatestSize( dimension );
3841 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3843 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3846 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3848 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3853 return GetLatestSize( dimension );
3858 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3860 // Can be overridden in derived class
3861 return CalculateChildSizeBase( child, dimension );
3864 float Actor::GetHeightForWidth( float width )
3866 // Can be overridden in derived class
3867 return GetHeightForWidthBase( width );
3870 float Actor::GetWidthForHeight( float height )
3872 // Can be overridden in derived class
3873 return GetWidthForHeightBase( height );
3876 float Actor::GetLatestSize( Dimension::Type dimension ) const
3878 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3881 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3883 Vector2 padding = GetPadding( dimension );
3885 return GetLatestSize( dimension ) + padding.x + padding.y;
3888 float Actor::NegotiateFromParent( Dimension::Type dimension )
3890 Actor* parent = GetParent();
3893 Vector2 padding( GetPadding( dimension ) );
3894 Vector2 parentPadding( parent->GetPadding( dimension ) );
3895 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3901 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3903 float maxDimensionPoint = 0.0f;
3905 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3907 ActorPtr child = GetChildAt( i );
3909 if( !child->RelayoutDependentOnParent( dimension ) )
3911 // Calculate the min and max points that the children range across
3912 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3913 float dimensionSize = child->GetRelayoutSize( dimension );
3914 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3918 return maxDimensionPoint;
3921 float Actor::GetSize( Dimension::Type dimension ) const
3923 return GetDimensionValue( GetTargetSize(), dimension );
3926 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3928 return GetDimensionValue( GetNaturalSize(), dimension );
3931 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3933 switch( GetResizePolicy( dimension ) )
3935 case ResizePolicy::USE_NATURAL_SIZE:
3937 return GetNaturalSize( dimension );
3940 case ResizePolicy::FIXED:
3942 return GetDimensionValue( GetPreferredSize(), dimension );
3945 case ResizePolicy::USE_ASSIGNED_SIZE:
3947 return GetDimensionValue( maximumSize, dimension );
3950 case ResizePolicy::FILL_TO_PARENT:
3951 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3952 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3954 return NegotiateFromParent( dimension );
3957 case ResizePolicy::FIT_TO_CHILDREN:
3959 return NegotiateFromChildren( dimension );
3962 case ResizePolicy::DIMENSION_DEPENDENCY:
3964 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3967 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3969 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3972 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3974 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3986 return 0.0f; // Default
3989 float Actor::ClampDimension( float size, Dimension::Type dimension )
3991 const float minSize = GetMinimumSize( dimension );
3992 const float maxSize = GetMaximumSize( dimension );
3994 return std::max( minSize, std::min( size, maxSize ) );
3997 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
3999 // Check if it needs to be negotiated
4000 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4002 // Check that we havn't gotten into an infinite loop
4003 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4004 bool recursionFound = false;
4005 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4007 if( *it == searchActor )
4009 recursionFound = true;
4014 if( !recursionFound )
4016 // Record the path that we have taken
4017 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4019 // Dimension dependency check
4020 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4022 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4024 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4026 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4030 // Parent dependency check
4031 Actor* parent = GetParent();
4032 if( parent && RelayoutDependentOnParent( dimension ) )
4034 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4037 // Children dependency check
4038 if( RelayoutDependentOnChildren( dimension ) )
4040 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4042 ActorPtr child = GetChildAt( i );
4044 // Only relayout child first if it is not dependent on this actor
4045 if( !child->RelayoutDependentOnParent( dimension ) )
4047 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4052 // For deriving classes
4053 OnCalculateRelayoutSize( dimension );
4055 // All dependencies checked, calculate the size and set negotiated flag
4056 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4058 SetNegotiatedDimension( newSize, dimension );
4059 SetLayoutNegotiated( true, dimension );
4061 // For deriving classes
4062 OnLayoutNegotiated( newSize, dimension );
4064 // This actor has been successfully processed, pop it off the recursion stack
4065 recursionStack.pop_back();
4069 // TODO: Break infinite loop
4070 SetLayoutNegotiated( true, dimension );
4075 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4077 // Negotiate all dimensions that require it
4078 ActorDimensionStack recursionStack;
4080 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4082 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4085 NegotiateDimension( dimension, allocatedSize, recursionStack );
4089 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4091 switch( mRelayoutData->sizeSetPolicy )
4093 case SizeScalePolicy::USE_SIZE_SET:
4098 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4100 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4101 const Vector3 naturalSize = GetNaturalSize();
4102 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4104 const float sizeRatio = size.width / size.height;
4105 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4107 if( naturalSizeRatio < sizeRatio )
4109 return Vector2( naturalSizeRatio * size.height, size.height );
4111 else if( naturalSizeRatio > sizeRatio )
4113 return Vector2( size.width, size.width / naturalSizeRatio );
4124 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4126 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4127 const Vector3 naturalSize = GetNaturalSize();
4128 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4130 const float sizeRatio = size.width / size.height;
4131 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4133 if( naturalSizeRatio < sizeRatio )
4135 return Vector2( size.width, size.width / naturalSizeRatio );
4137 else if( naturalSizeRatio > sizeRatio )
4139 return Vector2( naturalSizeRatio * size.height, size.height );
4158 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4160 // Do the set actor size
4161 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4163 // Adjust for size set policy
4164 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4166 // Lock the flag to stop recursive relayouts on set size
4167 mRelayoutData->insideRelayout = true;
4168 SetSize( negotiatedSize );
4169 mRelayoutData->insideRelayout = false;
4171 // Clear flags for all dimensions
4172 SetLayoutDirty( false );
4174 // Give deriving classes a chance to respond
4175 OnRelayout( negotiatedSize, container );
4177 if( !mOnRelayoutSignal.Empty() )
4179 Dali::Actor handle( this );
4180 mOnRelayoutSignal.Emit( handle );
4184 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4186 // Force a size negotiation for actors that has assigned size during relayout
4187 // This is required as otherwise the flags that force a relayout will not
4188 // necessarilly be set. This will occur if the actor has already been laid out.
4189 // The dirty flags are then cleared. Then if the actor is added back into the
4190 // relayout container afterwards, the dirty flags would still be clear...
4191 // causing a relayout to be skipped. Here we force any actors added to the
4192 // container to be relayed out.
4193 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4195 SetLayoutNegotiated(false, Dimension::WIDTH);
4197 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4199 SetLayoutNegotiated(false, Dimension::HEIGHT);
4202 // Do the negotiation
4203 NegotiateDimensions( allocatedSize );
4205 // Set the actor size
4206 SetNegotiatedSize( container );
4208 // Negotiate down to children
4209 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4211 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4213 ActorPtr child = GetChildAt( i );
4215 // Forces children that have already been laid out to be relayed out
4216 // if they have assigned size during relayout.
4217 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4219 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4220 child->SetLayoutDirty(true, Dimension::WIDTH);
4222 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4224 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4225 child->SetLayoutDirty(true, Dimension::HEIGHT);
4228 // Only relayout if required
4229 if( child->RelayoutRequired() )
4231 container.Add( Dali::Actor( child.Get() ), newBounds );
4236 void Actor::RelayoutRequest( Dimension::Type dimension )
4238 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4239 if( relayoutController )
4241 Dali::Actor self( this );
4242 relayoutController->RequestRelayout( self, dimension );
4246 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4250 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4254 void Actor::SetPreferredSize( const Vector2& size )
4256 EnsureRelayoutData();
4258 if( size.width > 0.0f )
4260 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4263 if( size.height > 0.0f )
4265 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4268 mRelayoutData->preferredSize = size;
4273 Vector2 Actor::GetPreferredSize() const
4275 if ( mRelayoutData )
4277 return Vector2( mRelayoutData->preferredSize );
4280 return GetDefaultPreferredSize();
4283 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4285 EnsureRelayoutData();
4287 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4289 if( dimension & ( 1 << i ) )
4291 mRelayoutData->minimumSize[ i ] = size;
4298 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4300 if ( mRelayoutData )
4302 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4304 if( dimension & ( 1 << i ) )
4306 return mRelayoutData->minimumSize[ i ];
4311 return 0.0f; // Default
4314 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4316 EnsureRelayoutData();
4318 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4320 if( dimension & ( 1 << i ) )
4322 mRelayoutData->maximumSize[ i ] = size;
4329 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4331 if ( mRelayoutData )
4333 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4335 if( dimension & ( 1 << i ) )
4337 return mRelayoutData->maximumSize[ i ];
4342 return FLT_MAX; // Default
4345 Object* Actor::GetParentObject() const
4350 } // namespace Internal