2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/common/animatable-property.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/nodes/node-declarations.h>
51 #include <dali/internal/update/animation/scene-graph-constraint.h>
52 #include <dali/internal/event/events/actor-gesture-data.h>
53 #include <dali/internal/common/message.h>
54 #include <dali/integration-api/debug.h>
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::PropertyBase;
66 unsigned int Actor::mActorCounter = 0;
70 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
71 inline const Vector3& GetDefaultSizeModeFactor()
76 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
77 inline const Vector2& GetDefaultPreferredSize()
82 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
83 inline const Vector2& GetDefaultDimensionPadding()
88 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
90 } // unnamed namespace
93 * Struct to collect relayout variables
95 struct Actor::RelayoutData
98 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
100 // Set size negotiation defaults
101 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
103 resizePolicies[ i ] = ResizePolicy::DEFAULT;
104 negotiatedDimensions[ i ] = 0.0f;
105 dimensionNegotiated[ i ] = false;
106 dimensionDirty[ i ] = false;
107 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
108 dimensionPadding[ i ] = GetDefaultDimensionPadding();
109 minimumSize[ i ] = 0.0f;
110 maximumSize[ i ] = FLT_MAX;
114 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
116 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
118 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
120 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
122 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
123 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
125 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
126 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
128 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
130 Vector2 preferredSize; ///< The preferred size of the actor
132 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
134 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
135 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
138 namespace // unnamed namespace
144 * We want to discourage the use of property strings (minimize string comparisons),
145 * particularly for the default properties.
146 * Name Type writable animatable constraint-input enum for index-checking
148 DALI_PROPERTY_TABLE_BEGIN
149 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
150 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
151 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
152 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
153 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
154 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
155 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
156 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
157 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
158 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
159 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
160 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
161 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
162 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
163 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
164 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
165 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
166 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
167 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
168 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
169 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
170 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
171 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
172 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
173 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
174 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
175 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
176 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
177 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
178 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
179 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
180 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
181 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
182 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
183 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
184 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
185 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
186 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
187 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
188 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
189 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
190 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
191 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
192 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
193 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
194 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
195 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
196 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
197 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
198 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
199 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
200 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
201 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
202 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
203 DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::DevelActor::Property::BATCH_PARENT )
204 DALI_PROPERTY_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::TREE_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 const Vector4& Actor::GetCurrentWorldColor() const
1023 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1026 return Color::WHITE;
1029 void Actor::SetColor( const Vector4& color )
1033 // mNode is being used in a separate thread; queue a message to set the value & base value
1034 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1038 void Actor::SetColorRed( float red )
1042 // mNode is being used in a separate thread; queue a message to set the value & base value
1043 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1047 void Actor::SetColorGreen( float green )
1051 // mNode is being used in a separate thread; queue a message to set the value & base value
1052 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1056 void Actor::SetColorBlue( float blue )
1060 // mNode is being used in a separate thread; queue a message to set the value & base value
1061 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1065 const Vector4& Actor::GetCurrentColor() const
1069 // mNode is being used in a separate thread; copy the value from the previous update
1070 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1073 return Color::WHITE;
1076 void Actor::SetInheritOrientation( bool inherit )
1078 if( mInheritOrientation != inherit && NULL != mNode)
1080 // non animateable so keep local copy
1081 mInheritOrientation = inherit;
1082 // mNode is being used in a separate thread; queue a message to set the value
1083 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1087 bool Actor::IsOrientationInherited() const
1089 return mInheritOrientation;
1092 void Actor::SetSizeModeFactor( const Vector3& factor )
1094 EnsureRelayoutData();
1096 mRelayoutData->sizeModeFactor = factor;
1099 const Vector3& Actor::GetSizeModeFactor() const
1101 if ( mRelayoutData )
1103 return mRelayoutData->sizeModeFactor;
1106 return GetDefaultSizeModeFactor();
1109 void Actor::SetColorMode( ColorMode colorMode )
1111 // non animateable so keep local copy
1112 mColorMode = colorMode;
1115 // mNode is being used in a separate thread; queue a message to set the value
1116 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1120 ColorMode Actor::GetColorMode() const
1122 // we have cached copy
1126 void Actor::SetSize( float width, float height )
1128 SetSize( Vector2( width, height ) );
1131 void Actor::SetSize( float width, float height, float depth )
1133 SetSize( Vector3( width, height, depth ) );
1136 void Actor::SetSize( const Vector2& size )
1138 SetSize( Vector3( size.width, size.height, 0.f ) );
1141 void Actor::SetSizeInternal( const Vector2& size )
1143 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1146 void Actor::SetSize( const Vector3& size )
1148 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1150 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1151 SetPreferredSize( size.GetVectorXY() );
1155 SetSizeInternal( size );
1159 void Actor::SetSizeInternal( const Vector3& size )
1161 // dont allow recursive loop
1162 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1163 // 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
1164 if( ( NULL != mNode )&&
1165 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1166 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1167 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1171 // mNode is being used in a separate thread; queue a message to set the value & base value
1172 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1174 // Notification for derived classes
1175 mInsideOnSizeSet = true;
1176 OnSizeSet( mTargetSize );
1177 mInsideOnSizeSet = false;
1179 // Raise a relayout request if the flag is not locked
1180 if( mRelayoutData && !mRelayoutData->insideRelayout )
1187 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1189 mTargetSize = targetSize;
1191 // Notify deriving classes
1192 OnSizeAnimation( animation, mTargetSize );
1195 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1197 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1199 mTargetSize.width = targetSize;
1201 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1203 mTargetSize.height = targetSize;
1205 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1207 mTargetSize.depth = targetSize;
1209 // Notify deriving classes
1210 OnSizeAnimation( animation, mTargetSize );
1213 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1215 mTargetPosition = targetPosition;
1218 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1220 if ( Dali::Actor::Property::POSITION_X == property )
1222 mTargetPosition.x = targetPosition;
1224 else if ( Dali::Actor::Property::POSITION_Y == property )
1226 mTargetPosition.y = targetPosition;
1228 else if ( Dali::Actor::Property::POSITION_Z == property )
1230 mTargetPosition.z = targetPosition;
1234 void Actor::SetWidth( float width )
1236 mTargetSize.width = width;
1240 // mNode is being used in a separate thread; queue a message to set the value & base value
1241 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1245 void Actor::SetHeight( float height )
1247 mTargetSize.height = height;
1251 // mNode is being used in a separate thread; queue a message to set the value & base value
1252 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1256 void Actor::SetDepth( float depth )
1258 mTargetSize.depth = depth;
1262 // mNode is being used in a separate thread; queue a message to set the value & base value
1263 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1267 const Vector3& Actor::GetTargetSize() const
1272 const Vector3& Actor::GetCurrentSize() const
1276 // mNode is being used in a separate thread; copy the value from the previous update
1277 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1280 return Vector3::ZERO;
1283 Vector3 Actor::GetNaturalSize() const
1285 // It is up to deriving classes to return the appropriate natural size
1286 return Vector3( 0.0f, 0.0f, 0.0f );
1289 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1291 EnsureRelayoutData();
1293 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1295 if( dimension & ( 1 << i ) )
1297 mRelayoutData->resizePolicies[ i ] = policy;
1301 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1303 if( dimension & Dimension::WIDTH )
1305 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1308 if( dimension & Dimension::HEIGHT )
1310 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1314 // If calling SetResizePolicy, assume we want relayout enabled
1315 SetRelayoutEnabled( true );
1317 OnSetResizePolicy( policy, dimension );
1319 // Trigger relayout on this control
1323 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1325 if ( mRelayoutData )
1327 // If more than one dimension is requested, just return the first one found
1328 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1330 if( ( dimension & ( 1 << i ) ) )
1332 return mRelayoutData->resizePolicies[ i ];
1337 return ResizePolicy::DEFAULT;
1340 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1342 EnsureRelayoutData();
1344 mRelayoutData->sizeSetPolicy = policy;
1347 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1349 if ( mRelayoutData )
1351 return mRelayoutData->sizeSetPolicy;
1354 return DEFAULT_SIZE_SCALE_POLICY;
1357 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1359 EnsureRelayoutData();
1361 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1363 if( dimension & ( 1 << i ) )
1365 mRelayoutData->dimensionDependencies[ i ] = dependency;
1370 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1372 if ( mRelayoutData )
1374 // If more than one dimension is requested, just return the first one found
1375 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1377 if( ( dimension & ( 1 << i ) ) )
1379 return mRelayoutData->dimensionDependencies[ i ];
1384 return Dimension::ALL_DIMENSIONS; // Default
1387 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1389 // If relayout data has not been allocated yet and the client is requesting
1390 // to disable it, do nothing
1391 if( mRelayoutData || relayoutEnabled )
1393 EnsureRelayoutData();
1395 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1397 mRelayoutData->relayoutEnabled = relayoutEnabled;
1401 bool Actor::IsRelayoutEnabled() const
1403 // Assume that if relayout data has not been allocated yet then
1404 // relayout is disabled
1405 return mRelayoutData && mRelayoutData->relayoutEnabled;
1408 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1410 EnsureRelayoutData();
1412 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1414 if( dimension & ( 1 << i ) )
1416 mRelayoutData->dimensionDirty[ i ] = dirty;
1421 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1423 if ( mRelayoutData )
1425 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1427 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1437 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1439 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1442 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1444 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1447 unsigned int Actor::AddRenderer( Renderer& renderer )
1451 mRenderers = new RendererContainer;
1454 unsigned int index = mRenderers->size();
1455 RendererPtr rendererPtr = RendererPtr( &renderer );
1456 mRenderers->push_back( rendererPtr );
1457 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1461 rendererPtr->Connect();
1467 unsigned int Actor::GetRendererCount() const
1469 unsigned int rendererCount(0);
1472 rendererCount = mRenderers->size();
1475 return rendererCount;
1478 RendererPtr Actor::GetRendererAt( unsigned int index )
1480 RendererPtr renderer;
1481 if( index < GetRendererCount() )
1483 renderer = ( *mRenderers )[ index ];
1489 void Actor::RemoveRenderer( Renderer& renderer )
1493 RendererIter end = mRenderers->end();
1494 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1496 if( (*iter).Get() == &renderer )
1498 mRenderers->erase( iter );
1499 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1506 void Actor::RemoveRenderer( unsigned int index )
1508 if( index < GetRendererCount() )
1510 RendererPtr renderer = ( *mRenderers )[ index ];
1511 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1512 mRenderers->erase( mRenderers->begin()+index );
1516 bool Actor::IsOverlay() const
1518 return ( DrawMode::OVERLAY_2D == mDrawMode );
1521 void Actor::SetDrawMode( DrawMode::Type drawMode )
1523 // this flag is not animatable so keep the value
1524 mDrawMode = drawMode;
1525 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1527 // mNode is being used in a separate thread; queue a message to set the value
1528 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1532 DrawMode::Type Actor::GetDrawMode() const
1537 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1539 // only valid when on-stage
1540 StagePtr stage = Stage::GetCurrent();
1541 if( stage && OnStage() )
1543 const RenderTaskList& taskList = stage->GetRenderTaskList();
1545 Vector2 converted( screenX, screenY );
1547 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1548 const int taskCount = taskList.GetTaskCount();
1549 for( int i = taskCount - 1; i >= 0; --i )
1551 Dali::RenderTask task = taskList.GetTask( i );
1552 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1554 // found a task where this conversion was ok so return
1562 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1564 bool retval = false;
1565 // only valid when on-stage
1568 CameraActor* camera = renderTask.GetCameraActor();
1572 renderTask.GetViewport( viewport );
1574 // need to translate coordinates to render tasks coordinate space
1575 Vector2 converted( screenX, screenY );
1576 if( renderTask.TranslateCoordinates( converted ) )
1578 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1585 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1587 // Early-out if mNode is NULL
1593 // Get the ModelView matrix
1595 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1597 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1598 Matrix invertedMvp( false/*don't init*/);
1599 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1600 bool success = invertedMvp.Invert();
1602 // Convert to GL coordinates
1603 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1608 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1615 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1621 if( XyPlaneIntersect( nearPos, farPos, local ) )
1623 Vector3 size = GetCurrentSize();
1624 localX = local.x + size.x * 0.5f;
1625 localY = local.y + size.y * 0.5f;
1636 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1639 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1641 Mathematical Formulation
1643 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1645 ( p - c ) dot ( p - c ) = r^2
1647 Given a ray with a point of origin 'o', and a direction vector 'd':
1649 ray(t) = o + td, t >= 0
1651 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1653 (o + td - c ) dot ( o + td - c ) = r^2
1655 To solve for t we first expand the above into a more recognisable quadratic equation form
1657 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1666 B = 2( o - c ) dot d
1667 C = ( o - c ) dot ( o - c ) - r^2
1669 which can be solved using a standard quadratic formula.
1671 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1673 Practical Simplification
1675 In a renderer, we often differentiate between world space and object space. In the object space
1676 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1677 into object space, the mathematical solution presented above can be simplified significantly.
1679 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1683 and we can find the t at which the (transformed) ray intersects the sphere by
1685 ( o + td ) dot ( o + td ) = r^2
1687 According to the reasoning above, we expand the above quadratic equation into the general form
1691 which now has coefficients:
1698 // Early out if mNode is NULL
1704 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1706 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1707 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1708 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1710 // Compute the radius is not needed, square radius it's enough.
1711 const Vector3& size( mNode->GetSize( bufferIndex ) );
1713 // Scale the sphere.
1714 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1716 const float width = size.width * scale.width;
1717 const float height = size.height * scale.height;
1719 float squareSphereRadius = 0.5f * ( width * width + height * height );
1721 float a = rayDir.Dot( rayDir ); // a
1722 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1723 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1725 return ( b2 * b2 - a * c ) >= 0.f;
1728 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1732 if( OnStage() && NULL != mNode )
1734 // Transforms the ray to the local reference system.
1735 // Calculate the inverse of Model matrix
1736 Matrix invModelMatrix( false/*don't init*/);
1738 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1739 invModelMatrix = mNode->GetWorldMatrix(0);
1740 invModelMatrix.Invert();
1742 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1743 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1745 // Test with the actor's XY plane (Normal = 0 0 1 1).
1747 float a = -rayOriginLocal.z;
1748 float b = rayDirLocal.z;
1750 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1752 // Ray travels distance * rayDirLocal to intersect with plane.
1755 const Vector3& size = mNode->GetSize( bufferIndex );
1757 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1758 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1760 // Test with the actor's geometry.
1761 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1768 void Actor::SetLeaveRequired( bool required )
1770 mLeaveRequired = required;
1773 bool Actor::GetLeaveRequired() const
1775 return mLeaveRequired;
1778 void Actor::SetKeyboardFocusable( bool focusable )
1780 mKeyboardFocusable = focusable;
1783 bool Actor::IsKeyboardFocusable() const
1785 return mKeyboardFocusable;
1788 bool Actor::GetTouchRequired() const
1790 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1793 bool Actor::GetHoverRequired() const
1795 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1798 bool Actor::GetWheelEventRequired() const
1800 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1803 bool Actor::IsHittable() const
1805 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1808 ActorGestureData& Actor::GetGestureData()
1810 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1811 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1812 if( NULL == mGestureData )
1814 mGestureData = new ActorGestureData;
1816 return *mGestureData;
1819 bool Actor::IsGestureRequred( Gesture::Type type ) const
1821 return mGestureData && mGestureData->IsGestureRequred( type );
1824 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1826 bool consumed = false;
1828 if( !mTouchSignal.Empty() )
1830 Dali::Actor handle( this );
1831 consumed = mTouchSignal.Emit( handle, touch );
1834 if( !mTouchedSignal.Empty() )
1836 Dali::Actor handle( this );
1837 consumed |= mTouchedSignal.Emit( handle, event );
1842 // Notification for derived classes
1843 consumed = OnTouchEvent( event ); // TODO
1849 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1851 bool consumed = false;
1853 if( !mHoveredSignal.Empty() )
1855 Dali::Actor handle( this );
1856 consumed = mHoveredSignal.Emit( handle, event );
1861 // Notification for derived classes
1862 consumed = OnHoverEvent( event );
1868 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1870 bool consumed = false;
1872 if( !mWheelEventSignal.Empty() )
1874 Dali::Actor handle( this );
1875 consumed = mWheelEventSignal.Emit( handle, event );
1880 // Notification for derived classes
1881 consumed = OnWheelEvent( event );
1887 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1889 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1890 return mTouchedSignal;
1893 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1895 return mTouchSignal;
1898 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1900 return mHoveredSignal;
1903 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1905 return mWheelEventSignal;
1908 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1910 return mOnStageSignal;
1913 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1915 return mOffStageSignal;
1918 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1920 return mOnRelayoutSignal;
1923 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1925 bool connected( true );
1926 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1928 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1930 actor->TouchedSignal().Connect( tracker, functor );
1932 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1934 actor->HoveredSignal().Connect( tracker, functor );
1936 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1938 actor->WheelEventSignal().Connect( tracker, functor );
1940 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1942 actor->OnStageSignal().Connect( tracker, functor );
1944 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1946 actor->OffStageSignal().Connect( tracker, functor );
1948 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1950 actor->OnRelayoutSignal().Connect( tracker, functor );
1952 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1954 actor->TouchSignal().Connect( tracker, functor );
1958 // signalName does not match any signal
1965 Actor::Actor( DerivedType derivedType )
1970 mParentOrigin( NULL ),
1971 mAnchorPoint( NULL ),
1972 mRelayoutData( NULL ),
1973 mGestureData( NULL ),
1974 mTargetSize( 0.0f, 0.0f, 0.0f ),
1976 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1979 mIsRoot( ROOT_LAYER == derivedType ),
1980 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1981 mIsOnStage( false ),
1983 mLeaveRequired( false ),
1984 mKeyboardFocusable( false ),
1985 mDerivedRequiresTouch( false ),
1986 mDerivedRequiresHover( false ),
1987 mDerivedRequiresWheelEvent( false ),
1988 mOnStageSignalled( false ),
1989 mInsideOnSizeSet( false ),
1990 mInheritPosition( true ),
1991 mInheritOrientation( true ),
1992 mInheritScale( true ),
1993 mDrawMode( DrawMode::NORMAL ),
1994 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1995 mColorMode( Node::DEFAULT_COLOR_MODE ),
1996 mClippingMode( ClippingMode::DISABLED ),
1997 mIsBatchParent( false )
2001 void Actor::Initialize()
2004 SceneGraph::Node* node = CreateNode();
2006 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2007 mNode = node; // Keep raw-pointer to Node
2011 GetEventThreadServices().RegisterObject( this );
2016 // Remove mParent pointers from children even if we're destroying core,
2017 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2020 ActorConstIter endIter = mChildren->end();
2021 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2023 (*iter)->SetParent( NULL );
2029 // Guard to allow handle destruction after Core has been destroyed
2030 if( EventThreadServices::IsCoreRunning() )
2034 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2035 mNode = NULL; // Node is about to be destroyed
2038 GetEventThreadServices().UnregisterObject( this );
2041 // Cleanup optional gesture data
2042 delete mGestureData;
2044 // Cleanup optional parent origin and anchor
2045 delete mParentOrigin;
2046 delete mAnchorPoint;
2048 // Delete optional relayout data
2051 delete mRelayoutData;
2055 void Actor::ConnectToStage( unsigned int parentDepth )
2057 // This container is used instead of walking the Actor hierarchy.
2058 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2059 ActorContainer connectionList;
2061 // This stage is atomic i.e. not interrupted by user callbacks.
2062 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2064 // Notify applications about the newly connected actors.
2065 const ActorIter endIter = connectionList.end();
2066 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2068 (*iter)->NotifyStageConnection();
2074 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2076 DALI_ASSERT_ALWAYS( !OnStage() );
2080 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2082 ConnectToSceneGraph();
2084 // Notification for internal derived classes
2085 OnStageConnectionInternal();
2087 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2088 connectionList.push_back( ActorPtr( this ) );
2090 // Recursively connect children
2093 ActorConstIter endIter = mChildren->end();
2094 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2096 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2102 * This method is called when the Actor is connected to the Stage.
2103 * The parent must have added its Node to the scene-graph.
2104 * The child must connect its Node to the parent's Node.
2105 * This is recursive; the child calls ConnectToStage() for its children.
2107 void Actor::ConnectToSceneGraph()
2109 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2113 // Reparent Node in next Update
2114 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2117 unsigned int rendererCount( GetRendererCount() );
2118 for( unsigned int i(0); i<rendererCount; ++i )
2120 GetRendererAt(i)->Connect();
2123 // Request relayout on all actors that are added to the scenegraph
2126 // Notification for Object::Observers
2130 void Actor::NotifyStageConnection()
2132 // Actors can be removed (in a callback), before the on-stage stage is reported.
2133 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2134 if( OnStage() && !mOnStageSignalled )
2136 // Notification for external (CustomActor) derived classes
2137 OnStageConnectionExternal( mDepth );
2139 if( !mOnStageSignal.Empty() )
2141 Dali::Actor handle( this );
2142 mOnStageSignal.Emit( handle );
2145 // Guard against Remove during callbacks
2148 mOnStageSignalled = true; // signal required next time Actor is removed
2153 void Actor::DisconnectFromStage()
2155 // This container is used instead of walking the Actor hierachy.
2156 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2157 ActorContainer disconnectionList;
2159 // This stage is atomic i.e. not interrupted by user callbacks
2160 RecursiveDisconnectFromStage( disconnectionList );
2162 // Notify applications about the newly disconnected actors.
2163 const ActorIter endIter = disconnectionList.end();
2164 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2166 (*iter)->NotifyStageDisconnection();
2170 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2172 DALI_ASSERT_ALWAYS( OnStage() );
2174 // Recursively disconnect children
2177 ActorConstIter endIter = mChildren->end();
2178 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2180 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2184 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2185 disconnectionList.push_back( ActorPtr( this ) );
2187 // Notification for internal derived classes
2188 OnStageDisconnectionInternal();
2190 DisconnectFromSceneGraph();
2196 * This method is called by an actor or its parent, before a node removal message is sent.
2197 * This is recursive; the child calls DisconnectFromStage() for its children.
2199 void Actor::DisconnectFromSceneGraph()
2201 // Notification for Object::Observers
2202 OnSceneObjectRemove();
2204 unsigned int rendererCount( GetRendererCount() );
2205 for( unsigned int i(0); i<rendererCount; ++i )
2207 GetRendererAt(i)->Disconnect();
2211 void Actor::NotifyStageDisconnection()
2213 // Actors can be added (in a callback), before the off-stage state is reported.
2214 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2215 // only do this step if there is a stage, i.e. Core is not being shut down
2216 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2218 // Notification for external (CustomeActor) derived classes
2219 OnStageDisconnectionExternal();
2221 if( !mOffStageSignal.Empty() )
2223 Dali::Actor handle( this );
2224 mOffStageSignal.Emit( handle );
2227 // Guard against Add during callbacks
2230 mOnStageSignalled = false; // signal required next time Actor is added
2235 bool Actor::IsNodeConnected() const
2237 bool connected( false );
2239 if( OnStage() && ( NULL != mNode ) )
2241 if( IsRoot() || mNode->GetParent() )
2250 unsigned int Actor::GetDefaultPropertyCount() const
2252 return DEFAULT_PROPERTY_COUNT;
2255 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2257 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2259 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2261 indices.PushBack( i );
2265 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2267 if( index < DEFAULT_PROPERTY_COUNT )
2269 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2275 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2277 Property::Index index = Property::INVALID_INDEX;
2279 // Look for name in default properties
2280 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2282 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2283 if( 0 == name.compare( property->name ) )
2293 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2295 if( index < DEFAULT_PROPERTY_COUNT )
2297 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2303 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2305 if( index < DEFAULT_PROPERTY_COUNT )
2307 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2313 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2315 if( index < DEFAULT_PROPERTY_COUNT )
2317 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2323 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2325 if( index < DEFAULT_PROPERTY_COUNT )
2327 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2330 // index out of range...return Property::NONE
2331 return Property::NONE;
2334 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2338 case Dali::Actor::Property::PARENT_ORIGIN:
2340 Property::Type type = property.GetType();
2341 if( type == Property::VECTOR3 )
2343 SetParentOrigin( property.Get< Vector3 >() );
2345 else if ( type == Property::STRING )
2347 std::string parentOriginString;
2348 property.Get( parentOriginString );
2349 Vector3 parentOrigin;
2350 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2352 SetParentOrigin( parentOrigin );
2358 case Dali::Actor::Property::PARENT_ORIGIN_X:
2360 SetParentOriginX( property.Get< float >() );
2364 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2366 SetParentOriginY( property.Get< float >() );
2370 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2372 SetParentOriginZ( property.Get< float >() );
2376 case Dali::Actor::Property::ANCHOR_POINT:
2378 Property::Type type = property.GetType();
2379 if( type == Property::VECTOR3 )
2381 SetAnchorPoint( property.Get< Vector3 >() );
2383 else if ( type == Property::STRING )
2385 std::string anchorPointString;
2386 property.Get( anchorPointString );
2388 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2390 SetAnchorPoint( anchor );
2396 case Dali::Actor::Property::ANCHOR_POINT_X:
2398 SetAnchorPointX( property.Get< float >() );
2402 case Dali::Actor::Property::ANCHOR_POINT_Y:
2404 SetAnchorPointY( property.Get< float >() );
2408 case Dali::Actor::Property::ANCHOR_POINT_Z:
2410 SetAnchorPointZ( property.Get< float >() );
2414 case Dali::Actor::Property::SIZE:
2416 SetSize( property.Get< Vector3 >() );
2420 case Dali::Actor::Property::SIZE_WIDTH:
2422 SetWidth( property.Get< float >() );
2426 case Dali::Actor::Property::SIZE_HEIGHT:
2428 SetHeight( property.Get< float >() );
2432 case Dali::Actor::Property::SIZE_DEPTH:
2434 SetDepth( property.Get< float >() );
2438 case Dali::Actor::Property::POSITION:
2440 SetPosition( property.Get< Vector3 >() );
2444 case Dali::Actor::Property::POSITION_X:
2446 SetX( property.Get< float >() );
2450 case Dali::Actor::Property::POSITION_Y:
2452 SetY( property.Get< float >() );
2456 case Dali::Actor::Property::POSITION_Z:
2458 SetZ( property.Get< float >() );
2462 case Dali::Actor::Property::ORIENTATION:
2464 SetOrientation( property.Get< Quaternion >() );
2468 case Dali::Actor::Property::SCALE:
2470 SetScale( property.Get< Vector3 >() );
2474 case Dali::Actor::Property::SCALE_X:
2476 SetScaleX( property.Get< float >() );
2480 case Dali::Actor::Property::SCALE_Y:
2482 SetScaleY( property.Get< float >() );
2486 case Dali::Actor::Property::SCALE_Z:
2488 SetScaleZ( property.Get< float >() );
2492 case Dali::Actor::Property::VISIBLE:
2494 SetVisible( property.Get< bool >() );
2498 case Dali::Actor::Property::COLOR:
2500 SetColor( property.Get< Vector4 >() );
2504 case Dali::Actor::Property::COLOR_RED:
2506 SetColorRed( property.Get< float >() );
2510 case Dali::Actor::Property::COLOR_GREEN:
2512 SetColorGreen( property.Get< float >() );
2516 case Dali::Actor::Property::COLOR_BLUE:
2518 SetColorBlue( property.Get< float >() );
2522 case Dali::Actor::Property::COLOR_ALPHA:
2524 SetOpacity( property.Get< float >() );
2528 case Dali::Actor::Property::NAME:
2530 SetName( property.Get< std::string >() );
2534 case Dali::Actor::Property::SENSITIVE:
2536 SetSensitive( property.Get< bool >() );
2540 case Dali::Actor::Property::LEAVE_REQUIRED:
2542 SetLeaveRequired( property.Get< bool >() );
2546 case Dali::Actor::Property::INHERIT_POSITION:
2548 SetInheritPosition( property.Get< bool >() );
2552 case Dali::Actor::Property::INHERIT_ORIENTATION:
2554 SetInheritOrientation( property.Get< bool >() );
2558 case Dali::Actor::Property::INHERIT_SCALE:
2560 SetInheritScale( property.Get< bool >() );
2564 case Dali::Actor::Property::COLOR_MODE:
2567 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2569 SetColorMode( mode );
2574 case Dali::Actor::Property::POSITION_INHERITANCE:
2576 PositionInheritanceMode mode;
2577 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2579 SetPositionInheritanceMode( mode );
2584 case Dali::Actor::Property::DRAW_MODE:
2586 DrawMode::Type mode;
2587 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2589 SetDrawMode( mode );
2594 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2596 SetSizeModeFactor( property.Get< Vector3 >() );
2600 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2602 ResizePolicy::Type type;
2603 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2605 SetResizePolicy( type, Dimension::WIDTH );
2610 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2612 ResizePolicy::Type type;
2613 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2615 SetResizePolicy( type, Dimension::HEIGHT );
2620 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2622 SizeScalePolicy::Type type;
2623 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2625 SetSizeScalePolicy( type );
2630 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2632 if( property.Get< bool >() )
2634 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2639 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2641 if( property.Get< bool >() )
2643 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2648 case Dali::Actor::Property::PADDING:
2650 Vector4 padding = property.Get< Vector4 >();
2651 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2652 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2656 case Dali::Actor::Property::MINIMUM_SIZE:
2658 Vector2 size = property.Get< Vector2 >();
2659 SetMinimumSize( size.x, Dimension::WIDTH );
2660 SetMinimumSize( size.y, Dimension::HEIGHT );
2664 case Dali::Actor::Property::MAXIMUM_SIZE:
2666 Vector2 size = property.Get< Vector2 >();
2667 SetMaximumSize( size.x, Dimension::WIDTH );
2668 SetMaximumSize( size.y, Dimension::HEIGHT );
2672 case Dali::DevelActor::Property::BATCH_PARENT:
2676 if( property.Get( value ) )
2678 if( value != mIsBatchParent )
2680 mIsBatchParent = value;
2681 SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2687 case Dali::DevelActor::Property::SIBLING_ORDER:
2691 if( property.Get( value ) )
2693 if( static_cast<unsigned int>(value) != mSiblingOrder )
2695 mSiblingOrder = value;
2698 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2705 case Dali::Actor::Property::CLIPPING_MODE:
2707 ClippingMode::Type convertedValue = mClippingMode;
2708 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2710 mClippingMode = convertedValue;
2713 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2721 // this can happen in the case of a non-animatable default property so just do nothing
2727 // TODO: This method needs to be removed
2728 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2730 switch( entry.GetType() )
2732 case Property::BOOLEAN:
2734 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2735 DALI_ASSERT_DEBUG( NULL != property );
2737 // property is being used in a separate thread; queue a message to set the property
2738 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2743 case Property::INTEGER:
2745 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2746 DALI_ASSERT_DEBUG( NULL != property );
2748 // property is being used in a separate thread; queue a message to set the property
2749 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2754 case Property::FLOAT:
2756 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2757 DALI_ASSERT_DEBUG( NULL != property );
2759 // property is being used in a separate thread; queue a message to set the property
2760 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2765 case Property::VECTOR2:
2767 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2768 DALI_ASSERT_DEBUG( NULL != property );
2770 // property is being used in a separate thread; queue a message to set the property
2771 if(entry.componentIndex == 0)
2773 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2775 else if(entry.componentIndex == 1)
2777 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2781 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2787 case Property::VECTOR3:
2789 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2790 DALI_ASSERT_DEBUG( NULL != property );
2792 // property is being used in a separate thread; queue a message to set the property
2793 if(entry.componentIndex == 0)
2795 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2797 else if(entry.componentIndex == 1)
2799 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2801 else if(entry.componentIndex == 2)
2803 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2807 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2813 case Property::VECTOR4:
2815 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( 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 if(entry.componentIndex == 0)
2821 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2823 else if(entry.componentIndex == 1)
2825 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2827 else if(entry.componentIndex == 2)
2829 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2831 else if(entry.componentIndex == 3)
2833 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2837 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2843 case Property::ROTATION:
2845 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2846 DALI_ASSERT_DEBUG( NULL != property );
2848 // property is being used in a separate thread; queue a message to set the property
2849 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2854 case Property::MATRIX:
2856 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2857 DALI_ASSERT_DEBUG( NULL != property );
2859 // property is being used in a separate thread; queue a message to set the property
2860 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2865 case Property::MATRIX3:
2867 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2868 DALI_ASSERT_DEBUG( NULL != property );
2870 // property is being used in a separate thread; queue a message to set the property
2871 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2878 // nothing to do for other types
2883 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2885 Property::Value value;
2889 case Dali::Actor::Property::PARENT_ORIGIN:
2891 value = GetCurrentParentOrigin();
2895 case Dali::Actor::Property::PARENT_ORIGIN_X:
2897 value = GetCurrentParentOrigin().x;
2901 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2903 value = GetCurrentParentOrigin().y;
2907 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2909 value = GetCurrentParentOrigin().z;
2913 case Dali::Actor::Property::ANCHOR_POINT:
2915 value = GetCurrentAnchorPoint();
2919 case Dali::Actor::Property::ANCHOR_POINT_X:
2921 value = GetCurrentAnchorPoint().x;
2925 case Dali::Actor::Property::ANCHOR_POINT_Y:
2927 value = GetCurrentAnchorPoint().y;
2931 case Dali::Actor::Property::ANCHOR_POINT_Z:
2933 value = GetCurrentAnchorPoint().z;
2937 case Dali::Actor::Property::SIZE:
2939 value = GetTargetSize();
2943 case Dali::Actor::Property::SIZE_WIDTH:
2945 value = GetTargetSize().width;
2949 case Dali::Actor::Property::SIZE_HEIGHT:
2951 value = GetTargetSize().height;
2955 case Dali::Actor::Property::SIZE_DEPTH:
2957 value = GetTargetSize().depth;
2961 case Dali::Actor::Property::POSITION:
2963 value = GetTargetPosition();
2967 case Dali::Actor::Property::POSITION_X:
2969 value = GetTargetPosition().x;
2973 case Dali::Actor::Property::POSITION_Y:
2975 value = GetTargetPosition().y;
2979 case Dali::Actor::Property::POSITION_Z:
2981 value = GetTargetPosition().z;
2985 case Dali::Actor::Property::WORLD_POSITION:
2987 value = GetCurrentWorldPosition();
2991 case Dali::Actor::Property::WORLD_POSITION_X:
2993 value = GetCurrentWorldPosition().x;
2997 case Dali::Actor::Property::WORLD_POSITION_Y:
2999 value = GetCurrentWorldPosition().y;
3003 case Dali::Actor::Property::WORLD_POSITION_Z:
3005 value = GetCurrentWorldPosition().z;
3009 case Dali::Actor::Property::ORIENTATION:
3011 value = GetCurrentOrientation();
3015 case Dali::Actor::Property::WORLD_ORIENTATION:
3017 value = GetCurrentWorldOrientation();
3021 case Dali::Actor::Property::SCALE:
3023 value = GetCurrentScale();
3027 case Dali::Actor::Property::SCALE_X:
3029 value = GetCurrentScale().x;
3033 case Dali::Actor::Property::SCALE_Y:
3035 value = GetCurrentScale().y;
3039 case Dali::Actor::Property::SCALE_Z:
3041 value = GetCurrentScale().z;
3045 case Dali::Actor::Property::WORLD_SCALE:
3047 value = GetCurrentWorldScale();
3051 case Dali::Actor::Property::VISIBLE:
3053 value = IsVisible();
3057 case Dali::Actor::Property::COLOR:
3059 value = GetCurrentColor();
3063 case Dali::Actor::Property::COLOR_RED:
3065 value = GetCurrentColor().r;
3069 case Dali::Actor::Property::COLOR_GREEN:
3071 value = GetCurrentColor().g;
3075 case Dali::Actor::Property::COLOR_BLUE:
3077 value = GetCurrentColor().b;
3081 case Dali::Actor::Property::COLOR_ALPHA:
3083 value = GetCurrentColor().a;
3087 case Dali::Actor::Property::WORLD_COLOR:
3089 value = GetCurrentWorldColor();
3093 case Dali::Actor::Property::WORLD_MATRIX:
3095 value = GetCurrentWorldMatrix();
3099 case Dali::Actor::Property::NAME:
3105 case Dali::Actor::Property::SENSITIVE:
3107 value = IsSensitive();
3111 case Dali::Actor::Property::LEAVE_REQUIRED:
3113 value = GetLeaveRequired();
3117 case Dali::Actor::Property::INHERIT_POSITION:
3119 value = IsPositionInherited();
3123 case Dali::Actor::Property::INHERIT_ORIENTATION:
3125 value = IsOrientationInherited();
3129 case Dali::Actor::Property::INHERIT_SCALE:
3131 value = IsScaleInherited();
3135 case Dali::Actor::Property::COLOR_MODE:
3137 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3141 case Dali::Actor::Property::POSITION_INHERITANCE:
3143 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3147 case Dali::Actor::Property::DRAW_MODE:
3149 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3153 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3155 value = GetSizeModeFactor();
3159 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3161 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3165 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3167 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3171 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3173 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3177 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3179 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3183 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3185 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3189 case Dali::Actor::Property::PADDING:
3191 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3192 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3193 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3197 case Dali::Actor::Property::MINIMUM_SIZE:
3199 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3203 case Dali::Actor::Property::MAXIMUM_SIZE:
3205 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3209 case Dali::DevelActor::Property::BATCH_PARENT:
3211 value = mIsBatchParent;
3215 case Dali::DevelActor::Property::SIBLING_ORDER:
3217 value = static_cast<int>(mSiblingOrder);
3221 case Dali::Actor::Property::CLIPPING_MODE:
3223 value = mClippingMode;
3231 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3236 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3238 // This method should only return an object connected to the scene-graph
3239 return OnStage() ? mNode : NULL;
3242 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3244 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3246 const PropertyBase* property( NULL );
3248 // This method should only return a property of an object connected to the scene-graph
3254 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3256 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3257 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3259 property = animatable->GetSceneGraphProperty();
3261 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3262 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3264 CustomPropertyMetadata* custom = FindCustomProperty( index );
3265 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3267 property = custom->GetSceneGraphProperty();
3269 else if( NULL != mNode )
3273 case Dali::Actor::Property::SIZE:
3274 property = &mNode->mSize;
3277 case Dali::Actor::Property::SIZE_WIDTH:
3278 property = &mNode->mSize;
3281 case Dali::Actor::Property::SIZE_HEIGHT:
3282 property = &mNode->mSize;
3285 case Dali::Actor::Property::SIZE_DEPTH:
3286 property = &mNode->mSize;
3289 case Dali::Actor::Property::POSITION:
3290 property = &mNode->mPosition;
3293 case Dali::Actor::Property::POSITION_X:
3294 property = &mNode->mPosition;
3297 case Dali::Actor::Property::POSITION_Y:
3298 property = &mNode->mPosition;
3301 case Dali::Actor::Property::POSITION_Z:
3302 property = &mNode->mPosition;
3305 case Dali::Actor::Property::ORIENTATION:
3306 property = &mNode->mOrientation;
3309 case Dali::Actor::Property::SCALE:
3310 property = &mNode->mScale;
3313 case Dali::Actor::Property::SCALE_X:
3314 property = &mNode->mScale;
3317 case Dali::Actor::Property::SCALE_Y:
3318 property = &mNode->mScale;
3321 case Dali::Actor::Property::SCALE_Z:
3322 property = &mNode->mScale;
3325 case Dali::Actor::Property::VISIBLE:
3326 property = &mNode->mVisible;
3329 case Dali::Actor::Property::COLOR:
3330 property = &mNode->mColor;
3333 case Dali::Actor::Property::COLOR_RED:
3334 property = &mNode->mColor;
3337 case Dali::Actor::Property::COLOR_GREEN:
3338 property = &mNode->mColor;
3341 case Dali::Actor::Property::COLOR_BLUE:
3342 property = &mNode->mColor;
3345 case Dali::Actor::Property::COLOR_ALPHA:
3346 property = &mNode->mColor;
3357 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3359 const PropertyInputImpl* property( NULL );
3361 // This method should only return a property of an object connected to the scene-graph
3367 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3369 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3370 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3372 property = animatable->GetSceneGraphProperty();
3374 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3375 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3377 CustomPropertyMetadata* custom = FindCustomProperty( index );
3378 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3379 property = custom->GetSceneGraphProperty();
3381 else if( NULL != mNode )
3385 case Dali::Actor::Property::PARENT_ORIGIN:
3386 property = &mNode->mParentOrigin;
3389 case Dali::Actor::Property::PARENT_ORIGIN_X:
3390 property = &mNode->mParentOrigin;
3393 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3394 property = &mNode->mParentOrigin;
3397 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3398 property = &mNode->mParentOrigin;
3401 case Dali::Actor::Property::ANCHOR_POINT:
3402 property = &mNode->mAnchorPoint;
3405 case Dali::Actor::Property::ANCHOR_POINT_X:
3406 property = &mNode->mAnchorPoint;
3409 case Dali::Actor::Property::ANCHOR_POINT_Y:
3410 property = &mNode->mAnchorPoint;
3413 case Dali::Actor::Property::ANCHOR_POINT_Z:
3414 property = &mNode->mAnchorPoint;
3417 case Dali::Actor::Property::SIZE:
3418 property = &mNode->mSize;
3421 case Dali::Actor::Property::SIZE_WIDTH:
3422 property = &mNode->mSize;
3425 case Dali::Actor::Property::SIZE_HEIGHT:
3426 property = &mNode->mSize;
3429 case Dali::Actor::Property::SIZE_DEPTH:
3430 property = &mNode->mSize;
3433 case Dali::Actor::Property::POSITION:
3434 property = &mNode->mPosition;
3437 case Dali::Actor::Property::POSITION_X:
3438 property = &mNode->mPosition;
3441 case Dali::Actor::Property::POSITION_Y:
3442 property = &mNode->mPosition;
3445 case Dali::Actor::Property::POSITION_Z:
3446 property = &mNode->mPosition;
3449 case Dali::Actor::Property::WORLD_POSITION:
3450 property = &mNode->mWorldPosition;
3453 case Dali::Actor::Property::WORLD_POSITION_X:
3454 property = &mNode->mWorldPosition;
3457 case Dali::Actor::Property::WORLD_POSITION_Y:
3458 property = &mNode->mWorldPosition;
3461 case Dali::Actor::Property::WORLD_POSITION_Z:
3462 property = &mNode->mWorldPosition;
3465 case Dali::Actor::Property::ORIENTATION:
3466 property = &mNode->mOrientation;
3469 case Dali::Actor::Property::WORLD_ORIENTATION:
3470 property = &mNode->mWorldOrientation;
3473 case Dali::Actor::Property::SCALE:
3474 property = &mNode->mScale;
3477 case Dali::Actor::Property::SCALE_X:
3478 property = &mNode->mScale;
3481 case Dali::Actor::Property::SCALE_Y:
3482 property = &mNode->mScale;
3485 case Dali::Actor::Property::SCALE_Z:
3486 property = &mNode->mScale;
3489 case Dali::Actor::Property::WORLD_SCALE:
3490 property = &mNode->mWorldScale;
3493 case Dali::Actor::Property::VISIBLE:
3494 property = &mNode->mVisible;
3497 case Dali::Actor::Property::COLOR:
3498 property = &mNode->mColor;
3501 case Dali::Actor::Property::COLOR_RED:
3502 property = &mNode->mColor;
3505 case Dali::Actor::Property::COLOR_GREEN:
3506 property = &mNode->mColor;
3509 case Dali::Actor::Property::COLOR_BLUE:
3510 property = &mNode->mColor;
3513 case Dali::Actor::Property::COLOR_ALPHA:
3514 property = &mNode->mColor;
3517 case Dali::Actor::Property::WORLD_COLOR:
3518 property = &mNode->mWorldColor;
3521 case Dali::Actor::Property::WORLD_MATRIX:
3522 property = &mNode->mWorldMatrix;
3533 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3535 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3537 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3539 // check whether the animatable property is registered already, if not then register one.
3540 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3541 if( animatableProperty )
3543 componentIndex = animatableProperty->componentIndex;
3550 case Dali::Actor::Property::PARENT_ORIGIN_X:
3551 case Dali::Actor::Property::ANCHOR_POINT_X:
3552 case Dali::Actor::Property::SIZE_WIDTH:
3553 case Dali::Actor::Property::POSITION_X:
3554 case Dali::Actor::Property::WORLD_POSITION_X:
3555 case Dali::Actor::Property::SCALE_X:
3556 case Dali::Actor::Property::COLOR_RED:
3562 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3563 case Dali::Actor::Property::ANCHOR_POINT_Y:
3564 case Dali::Actor::Property::SIZE_HEIGHT:
3565 case Dali::Actor::Property::POSITION_Y:
3566 case Dali::Actor::Property::WORLD_POSITION_Y:
3567 case Dali::Actor::Property::SCALE_Y:
3568 case Dali::Actor::Property::COLOR_GREEN:
3574 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3575 case Dali::Actor::Property::ANCHOR_POINT_Z:
3576 case Dali::Actor::Property::SIZE_DEPTH:
3577 case Dali::Actor::Property::POSITION_Z:
3578 case Dali::Actor::Property::WORLD_POSITION_Z:
3579 case Dali::Actor::Property::SCALE_Z:
3580 case Dali::Actor::Property::COLOR_BLUE:
3586 case Dali::Actor::Property::COLOR_ALPHA:
3600 return componentIndex;
3603 void Actor::SetParent( Actor* parent )
3607 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3611 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3614 // Instruct each actor to create a corresponding node in the scene graph
3615 ConnectToStage( parent->GetHierarchyDepth() );
3618 // Resolve the name and index for the child properties if any
3619 ResolveChildProperties();
3621 else // parent being set to NULL
3623 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3627 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3630 DALI_ASSERT_ALWAYS( mNode != NULL );
3634 // Disconnect the Node & its children from the scene-graph.
3635 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3638 // Instruct each actor to discard pointers to the scene-graph
3639 DisconnectFromStage();
3644 SceneGraph::Node* Actor::CreateNode() const
3649 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3652 Actor* actor = dynamic_cast< Actor* >( object );
3656 if( 0 == actionName.compare( ACTION_SHOW ) )
3658 actor->SetVisible( true );
3661 else if( 0 == actionName.compare( ACTION_HIDE ) )
3663 actor->SetVisible( false );
3671 void Actor::EnsureRelayoutData()
3673 // Assign relayout data.
3674 if( !mRelayoutData )
3676 mRelayoutData = new RelayoutData();
3680 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3682 // Check if actor is dependent on parent
3683 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3685 if( ( dimension & ( 1 << i ) ) )
3687 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3688 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3698 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3700 // Check if actor is dependent on children
3701 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3703 if( ( dimension & ( 1 << i ) ) )
3705 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3706 switch( resizePolicy )
3708 case ResizePolicy::FIT_TO_CHILDREN:
3709 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3725 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3727 return Actor::RelayoutDependentOnChildren( dimension );
3730 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3732 // Check each possible dimension and see if it is dependent on the input one
3733 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3735 if( dimension & ( 1 << i ) )
3737 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3744 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3746 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3748 if( dimension & ( 1 << i ) )
3750 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3755 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3757 // If more than one dimension is requested, just return the first one found
3758 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3760 if( ( dimension & ( 1 << i ) ) )
3762 return mRelayoutData->negotiatedDimensions[ i ];
3766 return 0.0f; // Default
3769 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3771 EnsureRelayoutData();
3773 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3775 if( dimension & ( 1 << i ) )
3777 mRelayoutData->dimensionPadding[ i ] = padding;
3782 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3784 if ( mRelayoutData )
3786 // If more than one dimension is requested, just return the first one found
3787 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3789 if( ( dimension & ( 1 << i ) ) )
3791 return mRelayoutData->dimensionPadding[ i ];
3796 return GetDefaultDimensionPadding();
3799 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3801 EnsureRelayoutData();
3803 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3805 if( dimension & ( 1 << i ) )
3807 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3812 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3814 if ( mRelayoutData )
3816 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3818 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3828 float Actor::GetHeightForWidthBase( float width )
3830 float height = 0.0f;
3832 const Vector3 naturalSize = GetNaturalSize();
3833 if( naturalSize.width > 0.0f )
3835 height = naturalSize.height * width / naturalSize.width;
3837 else // we treat 0 as 1:1 aspect ratio
3845 float Actor::GetWidthForHeightBase( float height )
3849 const Vector3 naturalSize = GetNaturalSize();
3850 if( naturalSize.height > 0.0f )
3852 width = naturalSize.width * height / naturalSize.height;
3854 else // we treat 0 as 1:1 aspect ratio
3862 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3864 // Fill to parent, taking size mode factor into account
3865 switch( child.GetResizePolicy( dimension ) )
3867 case ResizePolicy::FILL_TO_PARENT:
3869 return GetLatestSize( dimension );
3872 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3874 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3877 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3879 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3884 return GetLatestSize( dimension );
3889 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3891 // Can be overridden in derived class
3892 return CalculateChildSizeBase( child, dimension );
3895 float Actor::GetHeightForWidth( float width )
3897 // Can be overridden in derived class
3898 return GetHeightForWidthBase( width );
3901 float Actor::GetWidthForHeight( float height )
3903 // Can be overridden in derived class
3904 return GetWidthForHeightBase( height );
3907 float Actor::GetLatestSize( Dimension::Type dimension ) const
3909 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3912 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3914 Vector2 padding = GetPadding( dimension );
3916 return GetLatestSize( dimension ) + padding.x + padding.y;
3919 float Actor::NegotiateFromParent( Dimension::Type dimension )
3921 Actor* parent = GetParent();
3924 Vector2 padding( GetPadding( dimension ) );
3925 Vector2 parentPadding( parent->GetPadding( dimension ) );
3926 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3932 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3934 float maxDimensionPoint = 0.0f;
3936 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3938 ActorPtr child = GetChildAt( i );
3940 if( !child->RelayoutDependentOnParent( dimension ) )
3942 // Calculate the min and max points that the children range across
3943 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3944 float dimensionSize = child->GetRelayoutSize( dimension );
3945 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3949 return maxDimensionPoint;
3952 float Actor::GetSize( Dimension::Type dimension ) const
3954 return GetDimensionValue( GetTargetSize(), dimension );
3957 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3959 return GetDimensionValue( GetNaturalSize(), dimension );
3962 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3964 switch( GetResizePolicy( dimension ) )
3966 case ResizePolicy::USE_NATURAL_SIZE:
3968 return GetNaturalSize( dimension );
3971 case ResizePolicy::FIXED:
3973 return GetDimensionValue( GetPreferredSize(), dimension );
3976 case ResizePolicy::USE_ASSIGNED_SIZE:
3978 return GetDimensionValue( maximumSize, dimension );
3981 case ResizePolicy::FILL_TO_PARENT:
3982 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3983 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3985 return NegotiateFromParent( dimension );
3988 case ResizePolicy::FIT_TO_CHILDREN:
3990 return NegotiateFromChildren( dimension );
3993 case ResizePolicy::DIMENSION_DEPENDENCY:
3995 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3998 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4000 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4003 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4005 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4017 return 0.0f; // Default
4020 float Actor::ClampDimension( float size, Dimension::Type dimension )
4022 const float minSize = GetMinimumSize( dimension );
4023 const float maxSize = GetMaximumSize( dimension );
4025 return std::max( minSize, std::min( size, maxSize ) );
4028 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4030 // Check if it needs to be negotiated
4031 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4033 // Check that we havn't gotten into an infinite loop
4034 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4035 bool recursionFound = false;
4036 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4038 if( *it == searchActor )
4040 recursionFound = true;
4045 if( !recursionFound )
4047 // Record the path that we have taken
4048 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4050 // Dimension dependency check
4051 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4053 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4055 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4057 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4061 // Parent dependency check
4062 Actor* parent = GetParent();
4063 if( parent && RelayoutDependentOnParent( dimension ) )
4065 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4068 // Children dependency check
4069 if( RelayoutDependentOnChildren( dimension ) )
4071 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4073 ActorPtr child = GetChildAt( i );
4075 // Only relayout child first if it is not dependent on this actor
4076 if( !child->RelayoutDependentOnParent( dimension ) )
4078 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4083 // For deriving classes
4084 OnCalculateRelayoutSize( dimension );
4086 // All dependencies checked, calculate the size and set negotiated flag
4087 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4089 SetNegotiatedDimension( newSize, dimension );
4090 SetLayoutNegotiated( true, dimension );
4092 // For deriving classes
4093 OnLayoutNegotiated( newSize, dimension );
4095 // This actor has been successfully processed, pop it off the recursion stack
4096 recursionStack.pop_back();
4100 // TODO: Break infinite loop
4101 SetLayoutNegotiated( true, dimension );
4106 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4108 // Negotiate all dimensions that require it
4109 ActorDimensionStack recursionStack;
4111 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4113 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4116 NegotiateDimension( dimension, allocatedSize, recursionStack );
4120 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4122 switch( mRelayoutData->sizeSetPolicy )
4124 case SizeScalePolicy::USE_SIZE_SET:
4129 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4131 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4132 const Vector3 naturalSize = GetNaturalSize();
4133 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4135 const float sizeRatio = size.width / size.height;
4136 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4138 if( naturalSizeRatio < sizeRatio )
4140 return Vector2( naturalSizeRatio * size.height, size.height );
4142 else if( naturalSizeRatio > sizeRatio )
4144 return Vector2( size.width, size.width / naturalSizeRatio );
4155 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4157 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4158 const Vector3 naturalSize = GetNaturalSize();
4159 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4161 const float sizeRatio = size.width / size.height;
4162 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4164 if( naturalSizeRatio < sizeRatio )
4166 return Vector2( size.width, size.width / naturalSizeRatio );
4168 else if( naturalSizeRatio > sizeRatio )
4170 return Vector2( naturalSizeRatio * size.height, size.height );
4189 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4191 // Do the set actor size
4192 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4194 // Adjust for size set policy
4195 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4197 // Lock the flag to stop recursive relayouts on set size
4198 mRelayoutData->insideRelayout = true;
4199 SetSize( negotiatedSize );
4200 mRelayoutData->insideRelayout = false;
4202 // Clear flags for all dimensions
4203 SetLayoutDirty( false );
4205 // Give deriving classes a chance to respond
4206 OnRelayout( negotiatedSize, container );
4208 if( !mOnRelayoutSignal.Empty() )
4210 Dali::Actor handle( this );
4211 mOnRelayoutSignal.Emit( handle );
4215 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4217 // Force a size negotiation for actors that has assigned size during relayout
4218 // This is required as otherwise the flags that force a relayout will not
4219 // necessarilly be set. This will occur if the actor has already been laid out.
4220 // The dirty flags are then cleared. Then if the actor is added back into the
4221 // relayout container afterwards, the dirty flags would still be clear...
4222 // causing a relayout to be skipped. Here we force any actors added to the
4223 // container to be relayed out.
4224 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4226 SetLayoutNegotiated(false, Dimension::WIDTH);
4228 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4230 SetLayoutNegotiated(false, Dimension::HEIGHT);
4233 // Do the negotiation
4234 NegotiateDimensions( allocatedSize );
4236 // Set the actor size
4237 SetNegotiatedSize( container );
4239 // Negotiate down to children
4240 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4242 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4244 ActorPtr child = GetChildAt( i );
4246 // Forces children that have already been laid out to be relayed out
4247 // if they have assigned size during relayout.
4248 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4250 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4251 child->SetLayoutDirty(true, Dimension::WIDTH);
4253 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4255 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4256 child->SetLayoutDirty(true, Dimension::HEIGHT);
4259 // Only relayout if required
4260 if( child->RelayoutRequired() )
4262 container.Add( Dali::Actor( child.Get() ), newBounds );
4267 void Actor::RelayoutRequest( Dimension::Type dimension )
4269 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4270 if( relayoutController )
4272 Dali::Actor self( this );
4273 relayoutController->RequestRelayout( self, dimension );
4277 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4281 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4285 void Actor::SetPreferredSize( const Vector2& size )
4287 EnsureRelayoutData();
4289 if( size.width > 0.0f )
4291 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4294 if( size.height > 0.0f )
4296 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4299 mRelayoutData->preferredSize = size;
4304 Vector2 Actor::GetPreferredSize() const
4306 if ( mRelayoutData )
4308 return Vector2( mRelayoutData->preferredSize );
4311 return GetDefaultPreferredSize();
4314 void Actor::SetMinimumSize( 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->minimumSize[ i ] = size;
4329 float Actor::GetMinimumSize( 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->minimumSize[ i ];
4342 return 0.0f; // Default
4345 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4347 EnsureRelayoutData();
4349 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4351 if( dimension & ( 1 << i ) )
4353 mRelayoutData->maximumSize[ i ] = size;
4360 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4362 if ( mRelayoutData )
4364 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4366 if( dimension & ( 1 << i ) )
4368 return mRelayoutData->maximumSize[ i ];
4373 return FLT_MAX; // Default
4376 Object* Actor::GetParentObject() const
4381 } // namespace Internal