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/public-api/common/dali-common.h>
28 #include <dali/public-api/common/constants.h>
29 #include <dali/public-api/events/touch-data.h>
30 #include <dali/public-api/math/vector2.h>
31 #include <dali/public-api/math/vector3.h>
32 #include <dali/public-api/math/radian.h>
33 #include <dali/public-api/object/type-registry.h>
34 #include <dali/devel-api/scripting/scripting.h>
35 #include <dali/internal/common/internal-constants.h>
36 #include <dali/internal/event/common/event-thread-services.h>
37 #include <dali/internal/event/render-tasks/render-task-impl.h>
38 #include <dali/internal/event/actors/camera-actor-impl.h>
39 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
40 #include <dali/internal/event/common/property-helper.h>
41 #include <dali/internal/event/common/stage-impl.h>
42 #include <dali/internal/event/common/type-info-impl.h>
43 #include <dali/internal/event/animation/constraint-impl.h>
44 #include <dali/internal/event/common/projection.h>
45 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
46 #include <dali/internal/update/common/animatable-property.h>
47 #include <dali/internal/update/nodes/node-messages.h>
48 #include <dali/internal/update/nodes/node-declarations.h>
49 #include <dali/internal/update/animation/scene-graph-constraint.h>
50 #include <dali/internal/event/events/actor-gesture-data.h>
51 #include <dali/internal/common/message.h>
52 #include <dali/integration-api/debug.h>
54 using Dali::Internal::SceneGraph::Node;
55 using Dali::Internal::SceneGraph::AnimatableProperty;
56 using Dali::Internal::SceneGraph::PropertyBase;
64 unsigned int Actor::mActorCounter = 0;
68 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
69 inline const Vector3& GetDefaultSizeModeFactor()
74 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
75 inline const Vector2& GetDefaultPreferredSize()
80 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
81 inline const Vector2& GetDefaultDimensionPadding()
86 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
88 } // unnamed namespace
91 * Struct to collect relayout variables
93 struct Actor::RelayoutData
96 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
98 // Set size negotiation defaults
99 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
101 resizePolicies[ i ] = ResizePolicy::DEFAULT;
102 negotiatedDimensions[ i ] = 0.0f;
103 dimensionNegotiated[ i ] = false;
104 dimensionDirty[ i ] = false;
105 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
106 dimensionPadding[ i ] = GetDefaultDimensionPadding();
107 minimumSize[ i ] = 0.0f;
108 maximumSize[ i ] = FLT_MAX;
112 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
114 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
116 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
118 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
120 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
121 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
123 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
124 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
126 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
128 Vector2 preferredSize; ///< The preferred size of the actor
130 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
132 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
133 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
136 namespace // unnamed namespace
142 * We want to discourage the use of property strings (minimize string comparisons),
143 * particularly for the default properties.
144 * Name Type writable animatable constraint-input enum for index-checking
146 DALI_PROPERTY_TABLE_BEGIN
147 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
148 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
149 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
150 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
151 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
152 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
153 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
154 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
155 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
156 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
157 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
158 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
159 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
160 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
161 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
162 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
163 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
164 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
165 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
166 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
167 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
168 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
169 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
170 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
171 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
172 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
173 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
174 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
175 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
176 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
177 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
178 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
179 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
180 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
181 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
182 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
183 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
184 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
185 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
186 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
187 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
188 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
189 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
190 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
191 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
192 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
193 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
194 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
195 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
196 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
197 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
198 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
199 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
200 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
201 DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::Actor::Property::BATCH_PARENT )
202 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
206 const char* const SIGNAL_TOUCHED = "touched";
207 const char* const SIGNAL_HOVERED = "hovered";
208 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
209 const char* const SIGNAL_ON_STAGE = "onStage";
210 const char* const SIGNAL_OFF_STAGE = "offStage";
211 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
212 const char* const SIGNAL_TOUCH = "touch";
216 const char* const ACTION_SHOW = "show";
217 const char* const ACTION_HIDE = "hide";
219 BaseHandle CreateActor()
221 return Dali::Actor::New();
224 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
226 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
227 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
228 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
229 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
232 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
234 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
235 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
240 const Vector3& value;
243 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
244 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
245 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
246 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
252 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
253 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
255 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
256 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
257 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
258 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
259 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
260 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
262 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
263 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
264 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
265 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
266 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
267 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
269 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
270 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
273 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
275 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
276 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
284 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
286 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
287 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
288 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
289 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
290 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
292 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
295 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
298 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
300 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
302 size_t sizeIgnored = 0;
303 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
305 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
312 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
314 // Values are the same so just use the same table as anchor-point
315 return GetAnchorPointConstant( value, parentOrigin );
319 * @brief Extract a given dimension from a Vector2
321 * @param[in] values The values to extract from
322 * @param[in] dimension The dimension to extract
323 * @return Return the value for the dimension
325 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
329 case Dimension::WIDTH:
333 case Dimension::HEIGHT:
335 return values.height;
346 * @brief Extract a given dimension from a Vector3
348 * @param[in] values The values to extract from
349 * @param[in] dimension The dimension to extract
350 * @return Return the value for the dimension
352 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
354 return GetDimensionValue( values.GetVectorXY(), dimension );
358 } // unnamed namespace
360 ActorPtr Actor::New()
362 ActorPtr actor( new Actor( BASIC ) );
364 // Second-phase construction
370 const std::string& Actor::GetName() const
375 void Actor::SetName( const std::string& name )
381 // ATTENTION: string for debug purposes is not thread safe.
382 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
386 unsigned int Actor::GetId() const
391 bool Actor::OnStage() const
396 Dali::Layer Actor::GetLayer()
400 // Short-circuit for Layer derived actors
403 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
406 // Find the immediate Layer parent
407 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
409 if( parent->IsLayer() )
411 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
418 void Actor::Add( Actor& child )
420 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
421 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
425 mChildren = new ActorContainer;
428 Actor* const oldParent( child.mParent );
430 // child might already be ours
431 if( this != oldParent )
433 // if we already have parent, unparent us first
436 oldParent->Remove( child ); // This causes OnChildRemove callback
438 // Old parent may need to readjust to missing child
439 if( oldParent->RelayoutDependentOnChildren() )
441 oldParent->RelayoutRequest();
445 // Guard against Add() during previous OnChildRemove callback
448 // Do this first, since user callbacks from within SetParent() may need to remove child
449 mChildren->push_back( ActorPtr( &child ) );
451 // SetParent asserts that child can be added
452 child.SetParent( this );
454 // Notification for derived classes
457 // Only put in a relayout request if there is a suitable dependency
458 if( RelayoutDependentOnChildren() )
466 void Actor::Remove( Actor& child )
468 if( (this == &child) || (!mChildren) )
470 // no children or removing itself
476 // Find the child in mChildren, and unparent it
477 ActorIter end = mChildren->end();
478 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
480 ActorPtr actor = (*iter);
482 if( actor.Get() == &child )
484 // Keep handle for OnChildRemove notification
487 // Do this first, since user callbacks from within SetParent() may need to add the child
488 mChildren->erase( iter );
490 DALI_ASSERT_DEBUG( actor->GetParent() == this );
491 actor->SetParent( NULL );
499 // Only put in a relayout request if there is a suitable dependency
500 if( RelayoutDependentOnChildren() )
506 // Notification for derived classes
507 OnChildRemove( child );
510 void Actor::Unparent()
514 // Remove this actor from the parent. The remove will put a relayout request in for
515 // the parent if required
516 mParent->Remove( *this );
517 // mParent is now NULL!
521 unsigned int Actor::GetChildCount() const
523 return ( NULL != mChildren ) ? mChildren->size() : 0;
526 ActorPtr Actor::GetChildAt( unsigned int index ) const
528 DALI_ASSERT_ALWAYS( index < GetChildCount() );
530 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
533 ActorPtr Actor::FindChildByName( const std::string& actorName )
536 if( actorName == mName )
542 ActorIter end = mChildren->end();
543 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
545 child = (*iter)->FindChildByName( actorName );
556 ActorPtr Actor::FindChildById( const unsigned int id )
565 ActorIter end = mChildren->end();
566 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
568 child = (*iter)->FindChildById( id );
579 void Actor::SetParentOrigin( const Vector3& origin )
583 // mNode is being used in a separate thread; queue a message to set the value & base value
584 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
587 // Cache for event-thread access
590 // not allocated, check if different from default
591 if( ParentOrigin::DEFAULT != origin )
593 mParentOrigin = new Vector3( origin );
598 // check if different from current costs more than just set
599 *mParentOrigin = origin;
603 void Actor::SetParentOriginX( float x )
605 const Vector3& current = GetCurrentParentOrigin();
607 SetParentOrigin( Vector3( x, current.y, current.z ) );
610 void Actor::SetParentOriginY( float y )
612 const Vector3& current = GetCurrentParentOrigin();
614 SetParentOrigin( Vector3( current.x, y, current.z ) );
617 void Actor::SetParentOriginZ( float z )
619 const Vector3& current = GetCurrentParentOrigin();
621 SetParentOrigin( Vector3( current.x, current.y, z ) );
624 const Vector3& Actor::GetCurrentParentOrigin() const
626 // Cached for event-thread access
627 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
630 void Actor::SetAnchorPoint( const Vector3& anchor )
634 // mNode is being used in a separate thread; queue a message to set the value & base value
635 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
638 // Cache for event-thread access
641 // not allocated, check if different from default
642 if( AnchorPoint::DEFAULT != anchor )
644 mAnchorPoint = new Vector3( anchor );
649 // check if different from current costs more than just set
650 *mAnchorPoint = anchor;
654 void Actor::SetAnchorPointX( float x )
656 const Vector3& current = GetCurrentAnchorPoint();
658 SetAnchorPoint( Vector3( x, current.y, current.z ) );
661 void Actor::SetAnchorPointY( float y )
663 const Vector3& current = GetCurrentAnchorPoint();
665 SetAnchorPoint( Vector3( current.x, y, current.z ) );
668 void Actor::SetAnchorPointZ( float z )
670 const Vector3& current = GetCurrentAnchorPoint();
672 SetAnchorPoint( Vector3( current.x, current.y, z ) );
675 const Vector3& Actor::GetCurrentAnchorPoint() const
677 // Cached for event-thread access
678 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
681 void Actor::SetPosition( float x, float y )
683 SetPosition( Vector3( x, y, 0.0f ) );
686 void Actor::SetPosition( float x, float y, float z )
688 SetPosition( Vector3( x, y, z ) );
691 void Actor::SetPosition( const Vector3& position )
693 mTargetPosition = position;
697 // mNode is being used in a separate thread; queue a message to set the value & base value
698 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
702 void Actor::SetX( float x )
704 mTargetPosition.x = x;
708 // mNode is being used in a separate thread; queue a message to set the value & base value
709 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
713 void Actor::SetY( float y )
715 mTargetPosition.y = y;
719 // mNode is being used in a separate thread; queue a message to set the value & base value
720 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
724 void Actor::SetZ( float z )
726 mTargetPosition.z = z;
730 // mNode is being used in a separate thread; queue a message to set the value & base value
731 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
735 void Actor::TranslateBy( const Vector3& distance )
737 mTargetPosition += distance;
741 // mNode is being used in a separate thread; queue a message to set the value & base value
742 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
746 const Vector3& Actor::GetCurrentPosition() const
750 // mNode is being used in a separate thread; copy the value from the previous update
751 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
754 return Vector3::ZERO;
757 const Vector3& Actor::GetTargetPosition() const
759 return mTargetPosition;
762 const Vector3& Actor::GetCurrentWorldPosition() const
766 // mNode is being used in a separate thread; copy the value from the previous update
767 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
770 return Vector3::ZERO;
773 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
775 // this flag is not animatable so keep the value
776 mPositionInheritanceMode = mode;
779 // mNode is being used in a separate thread; queue a message to set the value
780 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
784 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
786 // Cached for event-thread access
787 return mPositionInheritanceMode;
790 void Actor::SetInheritPosition( bool inherit )
792 if( mInheritPosition != inherit && NULL != mNode )
794 // non animateable so keep local copy
795 mInheritPosition = inherit;
796 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
800 bool Actor::IsPositionInherited() const
802 return mInheritPosition;
805 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
807 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
808 normalizedAxis.Normalize();
810 Quaternion orientation( angle, normalizedAxis );
812 SetOrientation( orientation );
815 void Actor::SetOrientation( const Quaternion& orientation )
819 // mNode is being used in a separate thread; queue a message to set the value & base value
820 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
824 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
828 // mNode is being used in a separate thread; queue a message to set the value & base value
829 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
833 void Actor::RotateBy( const Quaternion& relativeRotation )
837 // mNode is being used in a separate thread; queue a message to set the value & base value
838 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
842 const Quaternion& Actor::GetCurrentOrientation() const
846 // mNode is being used in a separate thread; copy the value from the previous update
847 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
850 return Quaternion::IDENTITY;
853 const Quaternion& Actor::GetCurrentWorldOrientation() const
857 // mNode is being used in a separate thread; copy the value from the previous update
858 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
861 return Quaternion::IDENTITY;
864 void Actor::SetScale( float scale )
866 SetScale( Vector3( scale, scale, scale ) );
869 void Actor::SetScale( float x, float y, float z )
871 SetScale( Vector3( x, y, z ) );
874 void Actor::SetScale( const Vector3& scale )
878 // mNode is being used in a separate thread; queue a message to set the value & base value
879 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
883 void Actor::SetScaleX( float x )
887 // mNode is being used in a separate thread; queue a message to set the value & base value
888 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
892 void Actor::SetScaleY( float y )
896 // mNode is being used in a separate thread; queue a message to set the value & base value
897 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
901 void Actor::SetScaleZ( float z )
905 // mNode is being used in a separate thread; queue a message to set the value & base value
906 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
910 void Actor::ScaleBy(const Vector3& relativeScale)
914 // mNode is being used in a separate thread; queue a message to set the value & base value
915 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
919 const Vector3& Actor::GetCurrentScale() const
923 // mNode is being used in a separate thread; copy the value from the previous update
924 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
930 const Vector3& Actor::GetCurrentWorldScale() const
934 // mNode is being used in a separate thread; copy the value from the previous update
935 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
941 void Actor::SetInheritScale( bool inherit )
944 if( mInheritScale != inherit && NULL != mNode )
946 // non animateable so keep local copy
947 mInheritScale = inherit;
948 // mNode is being used in a separate thread; queue a message to set the value
949 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
953 bool Actor::IsScaleInherited() const
955 return mInheritScale;
958 Matrix Actor::GetCurrentWorldMatrix() const
962 return mNode->GetWorldMatrix(0);
965 return Matrix::IDENTITY;
968 void Actor::SetVisible( bool visible )
972 // mNode is being used in a separate thread; queue a message to set the value & base value
973 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
977 bool Actor::IsVisible() const
981 // mNode is being used in a separate thread; copy the value from the previous update
982 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
988 void Actor::SetOpacity( float opacity )
992 // mNode is being used in a separate thread; queue a message to set the value & base value
993 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
997 float Actor::GetCurrentOpacity() const
1001 // mNode is being used in a separate thread; copy the value from the previous update
1002 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1008 ClippingMode::Type Actor::GetClippingMode() const
1010 return mClippingMode;
1013 const Vector4& Actor::GetCurrentWorldColor() const
1017 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1020 return Color::WHITE;
1023 void Actor::SetColor( const Vector4& color )
1027 // mNode is being used in a separate thread; queue a message to set the value & base value
1028 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1032 void Actor::SetColorRed( float red )
1036 // mNode is being used in a separate thread; queue a message to set the value & base value
1037 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1041 void Actor::SetColorGreen( float green )
1045 // mNode is being used in a separate thread; queue a message to set the value & base value
1046 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1050 void Actor::SetColorBlue( float blue )
1054 // mNode is being used in a separate thread; queue a message to set the value & base value
1055 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1059 const Vector4& Actor::GetCurrentColor() const
1063 // mNode is being used in a separate thread; copy the value from the previous update
1064 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1067 return Color::WHITE;
1070 void Actor::SetInheritOrientation( bool inherit )
1072 if( mInheritOrientation != inherit && NULL != mNode)
1074 // non animateable so keep local copy
1075 mInheritOrientation = inherit;
1076 // mNode is being used in a separate thread; queue a message to set the value
1077 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1081 bool Actor::IsOrientationInherited() const
1083 return mInheritOrientation;
1086 void Actor::SetSizeModeFactor( const Vector3& factor )
1088 EnsureRelayoutData();
1090 mRelayoutData->sizeModeFactor = factor;
1093 const Vector3& Actor::GetSizeModeFactor() const
1095 if ( mRelayoutData )
1097 return mRelayoutData->sizeModeFactor;
1100 return GetDefaultSizeModeFactor();
1103 void Actor::SetColorMode( ColorMode colorMode )
1105 // non animateable so keep local copy
1106 mColorMode = colorMode;
1109 // mNode is being used in a separate thread; queue a message to set the value
1110 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1114 ColorMode Actor::GetColorMode() const
1116 // we have cached copy
1120 void Actor::SetSize( float width, float height )
1122 SetSize( Vector2( width, height ) );
1125 void Actor::SetSize( float width, float height, float depth )
1127 SetSize( Vector3( width, height, depth ) );
1130 void Actor::SetSize( const Vector2& size )
1132 SetSize( Vector3( size.width, size.height, 0.f ) );
1135 void Actor::SetSizeInternal( const Vector2& size )
1137 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1140 void Actor::SetSize( const Vector3& size )
1142 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1144 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1145 SetPreferredSize( size.GetVectorXY() );
1149 SetSizeInternal( size );
1153 void Actor::SetSizeInternal( const Vector3& size )
1155 // dont allow recursive loop
1156 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1157 // 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
1158 if( ( NULL != mNode )&&
1159 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1160 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1161 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1165 // mNode is being used in a separate thread; queue a message to set the value & base value
1166 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1168 // Notification for derived classes
1169 mInsideOnSizeSet = true;
1170 OnSizeSet( mTargetSize );
1171 mInsideOnSizeSet = false;
1173 // Raise a relayout request if the flag is not locked
1174 if( mRelayoutData && !mRelayoutData->insideRelayout )
1181 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1183 mTargetSize = targetSize;
1185 // Notify deriving classes
1186 OnSizeAnimation( animation, mTargetSize );
1189 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1191 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1193 mTargetSize.width = targetSize;
1195 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1197 mTargetSize.height = targetSize;
1199 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1201 mTargetSize.depth = targetSize;
1203 // Notify deriving classes
1204 OnSizeAnimation( animation, mTargetSize );
1207 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1209 mTargetPosition = targetPosition;
1212 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1214 if ( Dali::Actor::Property::POSITION_X == property )
1216 mTargetPosition.x = targetPosition;
1218 else if ( Dali::Actor::Property::POSITION_Y == property )
1220 mTargetPosition.y = targetPosition;
1222 else if ( Dali::Actor::Property::POSITION_Z == property )
1224 mTargetPosition.z = targetPosition;
1228 void Actor::SetWidth( float width )
1230 mTargetSize.width = width;
1234 // mNode is being used in a separate thread; queue a message to set the value & base value
1235 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1239 void Actor::SetHeight( float height )
1241 mTargetSize.height = height;
1245 // mNode is being used in a separate thread; queue a message to set the value & base value
1246 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1250 void Actor::SetDepth( float depth )
1252 mTargetSize.depth = depth;
1256 // mNode is being used in a separate thread; queue a message to set the value & base value
1257 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1261 const Vector3& Actor::GetTargetSize() const
1266 const Vector3& Actor::GetCurrentSize() const
1270 // mNode is being used in a separate thread; copy the value from the previous update
1271 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1274 return Vector3::ZERO;
1277 Vector3 Actor::GetNaturalSize() const
1279 // It is up to deriving classes to return the appropriate natural size
1280 return Vector3( 0.0f, 0.0f, 0.0f );
1283 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1285 EnsureRelayoutData();
1287 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1289 if( dimension & ( 1 << i ) )
1291 mRelayoutData->resizePolicies[ i ] = policy;
1295 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1297 if( dimension & Dimension::WIDTH )
1299 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1302 if( dimension & Dimension::HEIGHT )
1304 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1308 // If calling SetResizePolicy, assume we want relayout enabled
1309 SetRelayoutEnabled( true );
1311 OnSetResizePolicy( policy, dimension );
1313 // Trigger relayout on this control
1317 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1319 if ( mRelayoutData )
1321 // If more than one dimension is requested, just return the first one found
1322 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1324 if( ( dimension & ( 1 << i ) ) )
1326 return mRelayoutData->resizePolicies[ i ];
1331 return ResizePolicy::DEFAULT;
1334 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1336 EnsureRelayoutData();
1338 mRelayoutData->sizeSetPolicy = policy;
1341 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1343 if ( mRelayoutData )
1345 return mRelayoutData->sizeSetPolicy;
1348 return DEFAULT_SIZE_SCALE_POLICY;
1351 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1353 EnsureRelayoutData();
1355 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1357 if( dimension & ( 1 << i ) )
1359 mRelayoutData->dimensionDependencies[ i ] = dependency;
1364 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1366 if ( mRelayoutData )
1368 // If more than one dimension is requested, just return the first one found
1369 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1371 if( ( dimension & ( 1 << i ) ) )
1373 return mRelayoutData->dimensionDependencies[ i ];
1378 return Dimension::ALL_DIMENSIONS; // Default
1381 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1383 // If relayout data has not been allocated yet and the client is requesting
1384 // to disable it, do nothing
1385 if( mRelayoutData || relayoutEnabled )
1387 EnsureRelayoutData();
1389 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1391 mRelayoutData->relayoutEnabled = relayoutEnabled;
1395 bool Actor::IsRelayoutEnabled() const
1397 // Assume that if relayout data has not been allocated yet then
1398 // relayout is disabled
1399 return mRelayoutData && mRelayoutData->relayoutEnabled;
1402 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1404 EnsureRelayoutData();
1406 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1408 if( dimension & ( 1 << i ) )
1410 mRelayoutData->dimensionDirty[ i ] = dirty;
1415 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1417 if ( mRelayoutData )
1419 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1421 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1431 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1433 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1436 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1438 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1441 unsigned int Actor::AddRenderer( Renderer& renderer )
1445 mRenderers = new RendererContainer;
1448 unsigned int index = mRenderers->size();
1449 RendererPtr rendererPtr = RendererPtr( &renderer );
1450 mRenderers->push_back( rendererPtr );
1451 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1455 rendererPtr->Connect();
1461 unsigned int Actor::GetRendererCount() const
1463 unsigned int rendererCount(0);
1466 rendererCount = mRenderers->size();
1469 return rendererCount;
1472 RendererPtr Actor::GetRendererAt( unsigned int index )
1474 RendererPtr renderer;
1475 if( index < GetRendererCount() )
1477 renderer = ( *mRenderers )[ index ];
1483 void Actor::RemoveRenderer( Renderer& renderer )
1487 RendererIter end = mRenderers->end();
1488 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1490 if( (*iter).Get() == &renderer )
1492 mRenderers->erase( iter );
1493 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1500 void Actor::RemoveRenderer( unsigned int index )
1502 if( index < GetRendererCount() )
1504 RendererPtr renderer = ( *mRenderers )[ index ];
1505 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1506 mRenderers->erase( mRenderers->begin()+index );
1510 bool Actor::IsOverlay() const
1512 return ( DrawMode::OVERLAY_2D == mDrawMode );
1515 void Actor::SetDrawMode( DrawMode::Type drawMode )
1517 // this flag is not animatable so keep the value
1518 mDrawMode = drawMode;
1519 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1521 // mNode is being used in a separate thread; queue a message to set the value
1522 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1526 DrawMode::Type Actor::GetDrawMode() const
1531 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1533 // only valid when on-stage
1534 StagePtr stage = Stage::GetCurrent();
1535 if( stage && OnStage() )
1537 const RenderTaskList& taskList = stage->GetRenderTaskList();
1539 Vector2 converted( screenX, screenY );
1541 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1542 const int taskCount = taskList.GetTaskCount();
1543 for( int i = taskCount - 1; i >= 0; --i )
1545 Dali::RenderTask task = taskList.GetTask( i );
1546 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1548 // found a task where this conversion was ok so return
1556 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1558 bool retval = false;
1559 // only valid when on-stage
1562 CameraActor* camera = renderTask.GetCameraActor();
1566 renderTask.GetViewport( viewport );
1568 // need to translate coordinates to render tasks coordinate space
1569 Vector2 converted( screenX, screenY );
1570 if( renderTask.TranslateCoordinates( converted ) )
1572 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1579 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1581 // Early-out if mNode is NULL
1587 // Get the ModelView matrix
1589 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1591 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1592 Matrix invertedMvp( false/*don't init*/);
1593 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1594 bool success = invertedMvp.Invert();
1596 // Convert to GL coordinates
1597 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1602 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1609 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1615 if( XyPlaneIntersect( nearPos, farPos, local ) )
1617 Vector3 size = GetCurrentSize();
1618 localX = local.x + size.x * 0.5f;
1619 localY = local.y + size.y * 0.5f;
1630 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1633 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1635 Mathematical Formulation
1637 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1639 ( p - c ) dot ( p - c ) = r^2
1641 Given a ray with a point of origin 'o', and a direction vector 'd':
1643 ray(t) = o + td, t >= 0
1645 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1647 (o + td - c ) dot ( o + td - c ) = r^2
1649 To solve for t we first expand the above into a more recognisable quadratic equation form
1651 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1660 B = 2( o - c ) dot d
1661 C = ( o - c ) dot ( o - c ) - r^2
1663 which can be solved using a standard quadratic formula.
1665 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1667 Practical Simplification
1669 In a renderer, we often differentiate between world space and object space. In the object space
1670 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1671 into object space, the mathematical solution presented above can be simplified significantly.
1673 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1677 and we can find the t at which the (transformed) ray intersects the sphere by
1679 ( o + td ) dot ( o + td ) = r^2
1681 According to the reasoning above, we expand the above quadratic equation into the general form
1685 which now has coefficients:
1692 // Early out if mNode is NULL
1698 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1700 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1701 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1702 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1704 // Compute the radius is not needed, square radius it's enough.
1705 const Vector3& size( mNode->GetSize( bufferIndex ) );
1707 // Scale the sphere.
1708 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1710 const float width = size.width * scale.width;
1711 const float height = size.height * scale.height;
1713 float squareSphereRadius = 0.5f * ( width * width + height * height );
1715 float a = rayDir.Dot( rayDir ); // a
1716 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1717 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1719 return ( b2 * b2 - a * c ) >= 0.f;
1722 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1726 if( OnStage() && NULL != mNode )
1728 // Transforms the ray to the local reference system.
1729 // Calculate the inverse of Model matrix
1730 Matrix invModelMatrix( false/*don't init*/);
1732 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1733 invModelMatrix = mNode->GetWorldMatrix(0);
1734 invModelMatrix.Invert();
1736 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1737 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1739 // Test with the actor's XY plane (Normal = 0 0 1 1).
1741 float a = -rayOriginLocal.z;
1742 float b = rayDirLocal.z;
1744 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1746 // Ray travels distance * rayDirLocal to intersect with plane.
1749 const Vector3& size = mNode->GetSize( bufferIndex );
1751 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1752 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1754 // Test with the actor's geometry.
1755 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1762 void Actor::SetLeaveRequired( bool required )
1764 mLeaveRequired = required;
1767 bool Actor::GetLeaveRequired() const
1769 return mLeaveRequired;
1772 void Actor::SetKeyboardFocusable( bool focusable )
1774 mKeyboardFocusable = focusable;
1777 bool Actor::IsKeyboardFocusable() const
1779 return mKeyboardFocusable;
1782 bool Actor::GetTouchRequired() const
1784 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1787 bool Actor::GetHoverRequired() const
1789 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1792 bool Actor::GetWheelEventRequired() const
1794 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1797 bool Actor::IsHittable() const
1799 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1802 ActorGestureData& Actor::GetGestureData()
1804 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1805 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1806 if( NULL == mGestureData )
1808 mGestureData = new ActorGestureData;
1810 return *mGestureData;
1813 bool Actor::IsGestureRequred( Gesture::Type type ) const
1815 return mGestureData && mGestureData->IsGestureRequred( type );
1818 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1820 bool consumed = false;
1822 if( !mTouchSignal.Empty() )
1824 Dali::Actor handle( this );
1825 consumed = mTouchSignal.Emit( handle, touch );
1828 if( !mTouchedSignal.Empty() )
1830 Dali::Actor handle( this );
1831 consumed |= mTouchedSignal.Emit( handle, event );
1836 // Notification for derived classes
1837 consumed = OnTouchEvent( event ); // TODO
1843 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1845 bool consumed = false;
1847 if( !mHoveredSignal.Empty() )
1849 Dali::Actor handle( this );
1850 consumed = mHoveredSignal.Emit( handle, event );
1855 // Notification for derived classes
1856 consumed = OnHoverEvent( event );
1862 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1864 bool consumed = false;
1866 if( !mWheelEventSignal.Empty() )
1868 Dali::Actor handle( this );
1869 consumed = mWheelEventSignal.Emit( handle, event );
1874 // Notification for derived classes
1875 consumed = OnWheelEvent( event );
1881 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1883 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1884 return mTouchedSignal;
1887 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1889 return mTouchSignal;
1892 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1894 return mHoveredSignal;
1897 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1899 return mWheelEventSignal;
1902 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1904 return mOnStageSignal;
1907 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1909 return mOffStageSignal;
1912 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1914 return mOnRelayoutSignal;
1917 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1919 bool connected( true );
1920 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1922 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1924 actor->TouchedSignal().Connect( tracker, functor );
1926 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1928 actor->HoveredSignal().Connect( tracker, functor );
1930 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1932 actor->WheelEventSignal().Connect( tracker, functor );
1934 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1936 actor->OnStageSignal().Connect( tracker, functor );
1938 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1940 actor->OffStageSignal().Connect( tracker, functor );
1942 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1944 actor->OnRelayoutSignal().Connect( tracker, functor );
1946 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1948 actor->TouchSignal().Connect( tracker, functor );
1952 // signalName does not match any signal
1959 Actor::Actor( DerivedType derivedType )
1964 mParentOrigin( NULL ),
1965 mAnchorPoint( NULL ),
1966 mRelayoutData( NULL ),
1967 mGestureData( NULL ),
1968 mTargetSize( 0.0f, 0.0f, 0.0f ),
1970 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1972 mIsRoot( ROOT_LAYER == derivedType ),
1973 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1974 mIsOnStage( false ),
1976 mLeaveRequired( false ),
1977 mKeyboardFocusable( false ),
1978 mDerivedRequiresTouch( false ),
1979 mDerivedRequiresHover( false ),
1980 mDerivedRequiresWheelEvent( false ),
1981 mOnStageSignalled( false ),
1982 mInsideOnSizeSet( false ),
1983 mInheritPosition( true ),
1984 mInheritOrientation( true ),
1985 mInheritScale( true ),
1986 mDrawMode( DrawMode::NORMAL ),
1987 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1988 mColorMode( Node::DEFAULT_COLOR_MODE ),
1989 mClippingMode( ClippingMode::DISABLED ),
1990 mIsBatchParent( false )
1994 void Actor::Initialize()
1997 SceneGraph::Node* node = CreateNode();
1999 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2000 mNode = node; // Keep raw-pointer to Node
2004 GetEventThreadServices().RegisterObject( this );
2009 // Remove mParent pointers from children even if we're destroying core,
2010 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2013 ActorConstIter endIter = mChildren->end();
2014 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2016 (*iter)->SetParent( NULL );
2022 // Guard to allow handle destruction after Core has been destroyed
2023 if( EventThreadServices::IsCoreRunning() )
2027 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2028 mNode = NULL; // Node is about to be destroyed
2031 GetEventThreadServices().UnregisterObject( this );
2034 // Cleanup optional gesture data
2035 delete mGestureData;
2037 // Cleanup optional parent origin and anchor
2038 delete mParentOrigin;
2039 delete mAnchorPoint;
2041 // Delete optional relayout data
2044 delete mRelayoutData;
2048 void Actor::ConnectToStage( unsigned int parentDepth )
2050 // This container is used instead of walking the Actor hierarchy.
2051 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2052 ActorContainer connectionList;
2054 // This stage is atomic i.e. not interrupted by user callbacks.
2055 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2057 // Notify applications about the newly connected actors.
2058 const ActorIter endIter = connectionList.end();
2059 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2061 (*iter)->NotifyStageConnection();
2067 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2069 DALI_ASSERT_ALWAYS( !OnStage() );
2074 ConnectToSceneGraph();
2076 // Notification for internal derived classes
2077 OnStageConnectionInternal();
2079 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2080 connectionList.push_back( ActorPtr( this ) );
2082 // Recursively connect children
2085 ActorConstIter endIter = mChildren->end();
2086 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2088 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2094 * This method is called when the Actor is connected to the Stage.
2095 * The parent must have added its Node to the scene-graph.
2096 * The child must connect its Node to the parent's Node.
2097 * This is recursive; the child calls ConnectToStage() for its children.
2099 void Actor::ConnectToSceneGraph()
2101 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2105 // Reparent Node in next Update
2106 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2109 unsigned int rendererCount( GetRendererCount() );
2110 for( unsigned int i(0); i<rendererCount; ++i )
2112 GetRendererAt(i)->Connect();
2115 // Request relayout on all actors that are added to the scenegraph
2118 // Notification for Object::Observers
2122 void Actor::NotifyStageConnection()
2124 // Actors can be removed (in a callback), before the on-stage stage is reported.
2125 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2126 if( OnStage() && !mOnStageSignalled )
2128 // Notification for external (CustomActor) derived classes
2129 OnStageConnectionExternal( mDepth );
2131 if( !mOnStageSignal.Empty() )
2133 Dali::Actor handle( this );
2134 mOnStageSignal.Emit( handle );
2137 // Guard against Remove during callbacks
2140 mOnStageSignalled = true; // signal required next time Actor is removed
2145 void Actor::DisconnectFromStage()
2147 // This container is used instead of walking the Actor hierachy.
2148 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2149 ActorContainer disconnectionList;
2151 // This stage is atomic i.e. not interrupted by user callbacks
2152 RecursiveDisconnectFromStage( disconnectionList );
2154 // Notify applications about the newly disconnected actors.
2155 const ActorIter endIter = disconnectionList.end();
2156 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2158 (*iter)->NotifyStageDisconnection();
2162 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2164 DALI_ASSERT_ALWAYS( OnStage() );
2166 // Recursively disconnect children
2169 ActorConstIter endIter = mChildren->end();
2170 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2172 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2176 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2177 disconnectionList.push_back( ActorPtr( this ) );
2179 // Notification for internal derived classes
2180 OnStageDisconnectionInternal();
2182 DisconnectFromSceneGraph();
2188 * This method is called by an actor or its parent, before a node removal message is sent.
2189 * This is recursive; the child calls DisconnectFromStage() for its children.
2191 void Actor::DisconnectFromSceneGraph()
2193 // Notification for Object::Observers
2194 OnSceneObjectRemove();
2196 unsigned int rendererCount( GetRendererCount() );
2197 for( unsigned int i(0); i<rendererCount; ++i )
2199 GetRendererAt(i)->Disconnect();
2203 void Actor::NotifyStageDisconnection()
2205 // Actors can be added (in a callback), before the off-stage state is reported.
2206 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2207 // only do this step if there is a stage, i.e. Core is not being shut down
2208 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2210 // Notification for external (CustomeActor) derived classes
2211 OnStageDisconnectionExternal();
2213 if( !mOffStageSignal.Empty() )
2215 Dali::Actor handle( this );
2216 mOffStageSignal.Emit( handle );
2219 // Guard against Add during callbacks
2222 mOnStageSignalled = false; // signal required next time Actor is added
2227 bool Actor::IsNodeConnected() const
2229 bool connected( false );
2231 if( OnStage() && ( NULL != mNode ) )
2233 if( IsRoot() || mNode->GetParent() )
2242 unsigned int Actor::GetDefaultPropertyCount() const
2244 return DEFAULT_PROPERTY_COUNT;
2247 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2249 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2251 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2253 indices.PushBack( i );
2257 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2259 if( index < DEFAULT_PROPERTY_COUNT )
2261 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2267 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2269 Property::Index index = Property::INVALID_INDEX;
2271 // Look for name in default properties
2272 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2274 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2275 if( 0 == name.compare( property->name ) )
2285 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2287 if( index < DEFAULT_PROPERTY_COUNT )
2289 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2295 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2297 if( index < DEFAULT_PROPERTY_COUNT )
2299 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2305 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2307 if( index < DEFAULT_PROPERTY_COUNT )
2309 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2315 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2317 if( index < DEFAULT_PROPERTY_COUNT )
2319 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2322 // index out of range...return Property::NONE
2323 return Property::NONE;
2326 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2330 case Dali::Actor::Property::PARENT_ORIGIN:
2332 Property::Type type = property.GetType();
2333 if( type == Property::VECTOR3 )
2335 SetParentOrigin( property.Get< Vector3 >() );
2337 else if ( type == Property::STRING )
2339 std::string parentOriginString;
2340 property.Get( parentOriginString );
2341 Vector3 parentOrigin;
2342 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2344 SetParentOrigin( parentOrigin );
2350 case Dali::Actor::Property::PARENT_ORIGIN_X:
2352 SetParentOriginX( property.Get< float >() );
2356 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2358 SetParentOriginY( property.Get< float >() );
2362 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2364 SetParentOriginZ( property.Get< float >() );
2368 case Dali::Actor::Property::ANCHOR_POINT:
2370 Property::Type type = property.GetType();
2371 if( type == Property::VECTOR3 )
2373 SetAnchorPoint( property.Get< Vector3 >() );
2375 else if ( type == Property::STRING )
2377 std::string anchorPointString;
2378 property.Get( anchorPointString );
2380 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2382 SetAnchorPoint( anchor );
2388 case Dali::Actor::Property::ANCHOR_POINT_X:
2390 SetAnchorPointX( property.Get< float >() );
2394 case Dali::Actor::Property::ANCHOR_POINT_Y:
2396 SetAnchorPointY( property.Get< float >() );
2400 case Dali::Actor::Property::ANCHOR_POINT_Z:
2402 SetAnchorPointZ( property.Get< float >() );
2406 case Dali::Actor::Property::SIZE:
2408 SetSize( property.Get< Vector3 >() );
2412 case Dali::Actor::Property::SIZE_WIDTH:
2414 SetWidth( property.Get< float >() );
2418 case Dali::Actor::Property::SIZE_HEIGHT:
2420 SetHeight( property.Get< float >() );
2424 case Dali::Actor::Property::SIZE_DEPTH:
2426 SetDepth( property.Get< float >() );
2430 case Dali::Actor::Property::POSITION:
2432 SetPosition( property.Get< Vector3 >() );
2436 case Dali::Actor::Property::POSITION_X:
2438 SetX( property.Get< float >() );
2442 case Dali::Actor::Property::POSITION_Y:
2444 SetY( property.Get< float >() );
2448 case Dali::Actor::Property::POSITION_Z:
2450 SetZ( property.Get< float >() );
2454 case Dali::Actor::Property::ORIENTATION:
2456 SetOrientation( property.Get< Quaternion >() );
2460 case Dali::Actor::Property::SCALE:
2462 SetScale( property.Get< Vector3 >() );
2466 case Dali::Actor::Property::SCALE_X:
2468 SetScaleX( property.Get< float >() );
2472 case Dali::Actor::Property::SCALE_Y:
2474 SetScaleY( property.Get< float >() );
2478 case Dali::Actor::Property::SCALE_Z:
2480 SetScaleZ( property.Get< float >() );
2484 case Dali::Actor::Property::VISIBLE:
2486 SetVisible( property.Get< bool >() );
2490 case Dali::Actor::Property::COLOR:
2492 SetColor( property.Get< Vector4 >() );
2496 case Dali::Actor::Property::COLOR_RED:
2498 SetColorRed( property.Get< float >() );
2502 case Dali::Actor::Property::COLOR_GREEN:
2504 SetColorGreen( property.Get< float >() );
2508 case Dali::Actor::Property::COLOR_BLUE:
2510 SetColorBlue( property.Get< float >() );
2514 case Dali::Actor::Property::COLOR_ALPHA:
2516 SetOpacity( property.Get< float >() );
2520 case Dali::Actor::Property::NAME:
2522 SetName( property.Get< std::string >() );
2526 case Dali::Actor::Property::SENSITIVE:
2528 SetSensitive( property.Get< bool >() );
2532 case Dali::Actor::Property::LEAVE_REQUIRED:
2534 SetLeaveRequired( property.Get< bool >() );
2538 case Dali::Actor::Property::INHERIT_POSITION:
2540 SetInheritPosition( property.Get< bool >() );
2544 case Dali::Actor::Property::INHERIT_ORIENTATION:
2546 SetInheritOrientation( property.Get< bool >() );
2550 case Dali::Actor::Property::INHERIT_SCALE:
2552 SetInheritScale( property.Get< bool >() );
2556 case Dali::Actor::Property::COLOR_MODE:
2559 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2561 SetColorMode( mode );
2566 case Dali::Actor::Property::POSITION_INHERITANCE:
2568 PositionInheritanceMode mode;
2569 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2571 SetPositionInheritanceMode( mode );
2576 case Dali::Actor::Property::DRAW_MODE:
2578 DrawMode::Type mode;
2579 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2581 SetDrawMode( mode );
2586 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2588 SetSizeModeFactor( property.Get< Vector3 >() );
2592 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2594 ResizePolicy::Type type;
2595 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2597 SetResizePolicy( type, Dimension::WIDTH );
2602 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2604 ResizePolicy::Type type;
2605 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2607 SetResizePolicy( type, Dimension::HEIGHT );
2612 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2614 SizeScalePolicy::Type type;
2615 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2617 SetSizeScalePolicy( type );
2622 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2624 if( property.Get< bool >() )
2626 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2631 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2633 if( property.Get< bool >() )
2635 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2640 case Dali::Actor::Property::PADDING:
2642 Vector4 padding = property.Get< Vector4 >();
2643 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2644 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2648 case Dali::Actor::Property::MINIMUM_SIZE:
2650 Vector2 size = property.Get< Vector2 >();
2651 SetMinimumSize( size.x, Dimension::WIDTH );
2652 SetMinimumSize( size.y, Dimension::HEIGHT );
2656 case Dali::Actor::Property::MAXIMUM_SIZE:
2658 Vector2 size = property.Get< Vector2 >();
2659 SetMaximumSize( size.x, Dimension::WIDTH );
2660 SetMaximumSize( size.y, Dimension::HEIGHT );
2664 case Dali::Actor::Property::BATCH_PARENT:
2668 if( property.Get( value ) )
2670 if( value != mIsBatchParent )
2672 mIsBatchParent = value;
2673 SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2679 case Dali::Actor::Property::CLIPPING_MODE:
2681 ClippingMode::Type convertedValue = mClippingMode;
2682 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2684 mClippingMode = convertedValue;
2687 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2695 // this can happen in the case of a non-animatable default property so just do nothing
2701 // TODO: This method needs to be removed
2702 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2704 switch( entry.GetType() )
2706 case Property::BOOLEAN:
2708 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2709 DALI_ASSERT_DEBUG( NULL != property );
2711 // property is being used in a separate thread; queue a message to set the property
2712 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2717 case Property::INTEGER:
2719 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2720 DALI_ASSERT_DEBUG( NULL != property );
2722 // property is being used in a separate thread; queue a message to set the property
2723 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2728 case Property::FLOAT:
2730 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2731 DALI_ASSERT_DEBUG( NULL != property );
2733 // property is being used in a separate thread; queue a message to set the property
2734 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2739 case Property::VECTOR2:
2741 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2742 DALI_ASSERT_DEBUG( NULL != property );
2744 // property is being used in a separate thread; queue a message to set the property
2745 if(entry.componentIndex == 0)
2747 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2749 else if(entry.componentIndex == 1)
2751 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2755 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2761 case Property::VECTOR3:
2763 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2764 DALI_ASSERT_DEBUG( NULL != property );
2766 // property is being used in a separate thread; queue a message to set the property
2767 if(entry.componentIndex == 0)
2769 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2771 else if(entry.componentIndex == 1)
2773 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2775 else if(entry.componentIndex == 2)
2777 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2781 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2787 case Property::VECTOR4:
2789 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( 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<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2797 else if(entry.componentIndex == 1)
2799 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2801 else if(entry.componentIndex == 2)
2803 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2805 else if(entry.componentIndex == 3)
2807 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2811 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2817 case Property::ROTATION:
2819 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2820 DALI_ASSERT_DEBUG( NULL != property );
2822 // property is being used in a separate thread; queue a message to set the property
2823 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2828 case Property::MATRIX:
2830 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2831 DALI_ASSERT_DEBUG( NULL != property );
2833 // property is being used in a separate thread; queue a message to set the property
2834 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2839 case Property::MATRIX3:
2841 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2842 DALI_ASSERT_DEBUG( NULL != property );
2844 // property is being used in a separate thread; queue a message to set the property
2845 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2852 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2858 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2860 Property::Value value;
2864 case Dali::Actor::Property::PARENT_ORIGIN:
2866 value = GetCurrentParentOrigin();
2870 case Dali::Actor::Property::PARENT_ORIGIN_X:
2872 value = GetCurrentParentOrigin().x;
2876 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2878 value = GetCurrentParentOrigin().y;
2882 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2884 value = GetCurrentParentOrigin().z;
2888 case Dali::Actor::Property::ANCHOR_POINT:
2890 value = GetCurrentAnchorPoint();
2894 case Dali::Actor::Property::ANCHOR_POINT_X:
2896 value = GetCurrentAnchorPoint().x;
2900 case Dali::Actor::Property::ANCHOR_POINT_Y:
2902 value = GetCurrentAnchorPoint().y;
2906 case Dali::Actor::Property::ANCHOR_POINT_Z:
2908 value = GetCurrentAnchorPoint().z;
2912 case Dali::Actor::Property::SIZE:
2914 value = GetTargetSize();
2918 case Dali::Actor::Property::SIZE_WIDTH:
2920 value = GetTargetSize().width;
2924 case Dali::Actor::Property::SIZE_HEIGHT:
2926 value = GetTargetSize().height;
2930 case Dali::Actor::Property::SIZE_DEPTH:
2932 value = GetTargetSize().depth;
2936 case Dali::Actor::Property::POSITION:
2938 value = GetTargetPosition();
2942 case Dali::Actor::Property::POSITION_X:
2944 value = GetTargetPosition().x;
2948 case Dali::Actor::Property::POSITION_Y:
2950 value = GetTargetPosition().y;
2954 case Dali::Actor::Property::POSITION_Z:
2956 value = GetTargetPosition().z;
2960 case Dali::Actor::Property::WORLD_POSITION:
2962 value = GetCurrentWorldPosition();
2966 case Dali::Actor::Property::WORLD_POSITION_X:
2968 value = GetCurrentWorldPosition().x;
2972 case Dali::Actor::Property::WORLD_POSITION_Y:
2974 value = GetCurrentWorldPosition().y;
2978 case Dali::Actor::Property::WORLD_POSITION_Z:
2980 value = GetCurrentWorldPosition().z;
2984 case Dali::Actor::Property::ORIENTATION:
2986 value = GetCurrentOrientation();
2990 case Dali::Actor::Property::WORLD_ORIENTATION:
2992 value = GetCurrentWorldOrientation();
2996 case Dali::Actor::Property::SCALE:
2998 value = GetCurrentScale();
3002 case Dali::Actor::Property::SCALE_X:
3004 value = GetCurrentScale().x;
3008 case Dali::Actor::Property::SCALE_Y:
3010 value = GetCurrentScale().y;
3014 case Dali::Actor::Property::SCALE_Z:
3016 value = GetCurrentScale().z;
3020 case Dali::Actor::Property::WORLD_SCALE:
3022 value = GetCurrentWorldScale();
3026 case Dali::Actor::Property::VISIBLE:
3028 value = IsVisible();
3032 case Dali::Actor::Property::COLOR:
3034 value = GetCurrentColor();
3038 case Dali::Actor::Property::COLOR_RED:
3040 value = GetCurrentColor().r;
3044 case Dali::Actor::Property::COLOR_GREEN:
3046 value = GetCurrentColor().g;
3050 case Dali::Actor::Property::COLOR_BLUE:
3052 value = GetCurrentColor().b;
3056 case Dali::Actor::Property::COLOR_ALPHA:
3058 value = GetCurrentColor().a;
3062 case Dali::Actor::Property::WORLD_COLOR:
3064 value = GetCurrentWorldColor();
3068 case Dali::Actor::Property::WORLD_MATRIX:
3070 value = GetCurrentWorldMatrix();
3074 case Dali::Actor::Property::NAME:
3080 case Dali::Actor::Property::SENSITIVE:
3082 value = IsSensitive();
3086 case Dali::Actor::Property::LEAVE_REQUIRED:
3088 value = GetLeaveRequired();
3092 case Dali::Actor::Property::INHERIT_POSITION:
3094 value = IsPositionInherited();
3098 case Dali::Actor::Property::INHERIT_ORIENTATION:
3100 value = IsOrientationInherited();
3104 case Dali::Actor::Property::INHERIT_SCALE:
3106 value = IsScaleInherited();
3110 case Dali::Actor::Property::COLOR_MODE:
3112 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3116 case Dali::Actor::Property::POSITION_INHERITANCE:
3118 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3122 case Dali::Actor::Property::DRAW_MODE:
3124 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3128 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3130 value = GetSizeModeFactor();
3134 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3136 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3140 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3142 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3146 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3148 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3152 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3154 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3158 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3160 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3164 case Dali::Actor::Property::PADDING:
3166 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3167 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3168 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3172 case Dali::Actor::Property::MINIMUM_SIZE:
3174 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3178 case Dali::Actor::Property::MAXIMUM_SIZE:
3180 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3184 case Dali::Actor::Property::BATCH_PARENT:
3186 value = mIsBatchParent;
3190 case Dali::Actor::Property::CLIPPING_MODE:
3192 value = mClippingMode;
3198 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3206 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3211 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3213 // This method should only return an object connected to the scene-graph
3214 return OnStage() ? mNode : NULL;
3217 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3219 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3221 const PropertyBase* property( NULL );
3223 // This method should only return a property of an object connected to the scene-graph
3229 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3231 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3232 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3234 property = animatable->GetSceneGraphProperty();
3236 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3237 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3239 CustomPropertyMetadata* custom = FindCustomProperty( index );
3240 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3242 property = custom->GetSceneGraphProperty();
3244 else if( NULL != mNode )
3248 case Dali::Actor::Property::SIZE:
3249 property = &mNode->mSize;
3252 case Dali::Actor::Property::SIZE_WIDTH:
3253 property = &mNode->mSize;
3256 case Dali::Actor::Property::SIZE_HEIGHT:
3257 property = &mNode->mSize;
3260 case Dali::Actor::Property::SIZE_DEPTH:
3261 property = &mNode->mSize;
3264 case Dali::Actor::Property::POSITION:
3265 property = &mNode->mPosition;
3268 case Dali::Actor::Property::POSITION_X:
3269 property = &mNode->mPosition;
3272 case Dali::Actor::Property::POSITION_Y:
3273 property = &mNode->mPosition;
3276 case Dali::Actor::Property::POSITION_Z:
3277 property = &mNode->mPosition;
3280 case Dali::Actor::Property::ORIENTATION:
3281 property = &mNode->mOrientation;
3284 case Dali::Actor::Property::SCALE:
3285 property = &mNode->mScale;
3288 case Dali::Actor::Property::SCALE_X:
3289 property = &mNode->mScale;
3292 case Dali::Actor::Property::SCALE_Y:
3293 property = &mNode->mScale;
3296 case Dali::Actor::Property::SCALE_Z:
3297 property = &mNode->mScale;
3300 case Dali::Actor::Property::VISIBLE:
3301 property = &mNode->mVisible;
3304 case Dali::Actor::Property::COLOR:
3305 property = &mNode->mColor;
3308 case Dali::Actor::Property::COLOR_RED:
3309 property = &mNode->mColor;
3312 case Dali::Actor::Property::COLOR_GREEN:
3313 property = &mNode->mColor;
3316 case Dali::Actor::Property::COLOR_BLUE:
3317 property = &mNode->mColor;
3320 case Dali::Actor::Property::COLOR_ALPHA:
3321 property = &mNode->mColor;
3332 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3334 const PropertyInputImpl* property( NULL );
3336 // This method should only return a property of an object connected to the scene-graph
3342 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3344 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3345 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3347 property = animatable->GetSceneGraphProperty();
3349 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3350 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3352 CustomPropertyMetadata* custom = FindCustomProperty( index );
3353 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3354 property = custom->GetSceneGraphProperty();
3356 else if( NULL != mNode )
3360 case Dali::Actor::Property::PARENT_ORIGIN:
3361 property = &mNode->mParentOrigin;
3364 case Dali::Actor::Property::PARENT_ORIGIN_X:
3365 property = &mNode->mParentOrigin;
3368 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3369 property = &mNode->mParentOrigin;
3372 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3373 property = &mNode->mParentOrigin;
3376 case Dali::Actor::Property::ANCHOR_POINT:
3377 property = &mNode->mAnchorPoint;
3380 case Dali::Actor::Property::ANCHOR_POINT_X:
3381 property = &mNode->mAnchorPoint;
3384 case Dali::Actor::Property::ANCHOR_POINT_Y:
3385 property = &mNode->mAnchorPoint;
3388 case Dali::Actor::Property::ANCHOR_POINT_Z:
3389 property = &mNode->mAnchorPoint;
3392 case Dali::Actor::Property::SIZE:
3393 property = &mNode->mSize;
3396 case Dali::Actor::Property::SIZE_WIDTH:
3397 property = &mNode->mSize;
3400 case Dali::Actor::Property::SIZE_HEIGHT:
3401 property = &mNode->mSize;
3404 case Dali::Actor::Property::SIZE_DEPTH:
3405 property = &mNode->mSize;
3408 case Dali::Actor::Property::POSITION:
3409 property = &mNode->mPosition;
3412 case Dali::Actor::Property::POSITION_X:
3413 property = &mNode->mPosition;
3416 case Dali::Actor::Property::POSITION_Y:
3417 property = &mNode->mPosition;
3420 case Dali::Actor::Property::POSITION_Z:
3421 property = &mNode->mPosition;
3424 case Dali::Actor::Property::WORLD_POSITION:
3425 property = &mNode->mWorldPosition;
3428 case Dali::Actor::Property::WORLD_POSITION_X:
3429 property = &mNode->mWorldPosition;
3432 case Dali::Actor::Property::WORLD_POSITION_Y:
3433 property = &mNode->mWorldPosition;
3436 case Dali::Actor::Property::WORLD_POSITION_Z:
3437 property = &mNode->mWorldPosition;
3440 case Dali::Actor::Property::ORIENTATION:
3441 property = &mNode->mOrientation;
3444 case Dali::Actor::Property::WORLD_ORIENTATION:
3445 property = &mNode->mWorldOrientation;
3448 case Dali::Actor::Property::SCALE:
3449 property = &mNode->mScale;
3452 case Dali::Actor::Property::SCALE_X:
3453 property = &mNode->mScale;
3456 case Dali::Actor::Property::SCALE_Y:
3457 property = &mNode->mScale;
3460 case Dali::Actor::Property::SCALE_Z:
3461 property = &mNode->mScale;
3464 case Dali::Actor::Property::WORLD_SCALE:
3465 property = &mNode->mWorldScale;
3468 case Dali::Actor::Property::VISIBLE:
3469 property = &mNode->mVisible;
3472 case Dali::Actor::Property::COLOR:
3473 property = &mNode->mColor;
3476 case Dali::Actor::Property::COLOR_RED:
3477 property = &mNode->mColor;
3480 case Dali::Actor::Property::COLOR_GREEN:
3481 property = &mNode->mColor;
3484 case Dali::Actor::Property::COLOR_BLUE:
3485 property = &mNode->mColor;
3488 case Dali::Actor::Property::COLOR_ALPHA:
3489 property = &mNode->mColor;
3492 case Dali::Actor::Property::WORLD_COLOR:
3493 property = &mNode->mWorldColor;
3496 case Dali::Actor::Property::WORLD_MATRIX:
3497 property = &mNode->mWorldMatrix;
3508 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3510 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3512 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3514 // check whether the animatable property is registered already, if not then register one.
3515 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3516 if( animatableProperty )
3518 componentIndex = animatableProperty->componentIndex;
3525 case Dali::Actor::Property::PARENT_ORIGIN_X:
3526 case Dali::Actor::Property::ANCHOR_POINT_X:
3527 case Dali::Actor::Property::SIZE_WIDTH:
3528 case Dali::Actor::Property::POSITION_X:
3529 case Dali::Actor::Property::WORLD_POSITION_X:
3530 case Dali::Actor::Property::SCALE_X:
3531 case Dali::Actor::Property::COLOR_RED:
3537 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3538 case Dali::Actor::Property::ANCHOR_POINT_Y:
3539 case Dali::Actor::Property::SIZE_HEIGHT:
3540 case Dali::Actor::Property::POSITION_Y:
3541 case Dali::Actor::Property::WORLD_POSITION_Y:
3542 case Dali::Actor::Property::SCALE_Y:
3543 case Dali::Actor::Property::COLOR_GREEN:
3549 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3550 case Dali::Actor::Property::ANCHOR_POINT_Z:
3551 case Dali::Actor::Property::SIZE_DEPTH:
3552 case Dali::Actor::Property::POSITION_Z:
3553 case Dali::Actor::Property::WORLD_POSITION_Z:
3554 case Dali::Actor::Property::SCALE_Z:
3555 case Dali::Actor::Property::COLOR_BLUE:
3561 case Dali::Actor::Property::COLOR_ALPHA:
3575 return componentIndex;
3578 void Actor::SetParent( Actor* parent )
3582 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3586 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3589 // Instruct each actor to create a corresponding node in the scene graph
3590 ConnectToStage( parent->GetHierarchyDepth() );
3593 // Resolve the name and index for the child properties if any
3594 ResolveChildProperties();
3596 else // parent being set to NULL
3598 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3602 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3605 DALI_ASSERT_ALWAYS( mNode != NULL );
3609 // Disconnect the Node & its children from the scene-graph.
3610 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3613 // Instruct each actor to discard pointers to the scene-graph
3614 DisconnectFromStage();
3619 SceneGraph::Node* Actor::CreateNode() const
3624 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3627 Actor* actor = dynamic_cast< Actor* >( object );
3631 if( 0 == actionName.compare( ACTION_SHOW ) )
3633 actor->SetVisible( true );
3636 else if( 0 == actionName.compare( ACTION_HIDE ) )
3638 actor->SetVisible( false );
3646 void Actor::EnsureRelayoutData()
3648 // Assign relayout data.
3649 if( !mRelayoutData )
3651 mRelayoutData = new RelayoutData();
3655 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3657 // Check if actor is dependent on parent
3658 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3660 if( ( dimension & ( 1 << i ) ) )
3662 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3663 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3673 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3675 // Check if actor is dependent on children
3676 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3678 if( ( dimension & ( 1 << i ) ) )
3680 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3681 switch( resizePolicy )
3683 case ResizePolicy::FIT_TO_CHILDREN:
3684 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3700 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3702 return Actor::RelayoutDependentOnChildren( dimension );
3705 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3707 // Check each possible dimension and see if it is dependent on the input one
3708 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3710 if( dimension & ( 1 << i ) )
3712 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3719 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3721 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3723 if( dimension & ( 1 << i ) )
3725 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3730 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3732 // If more than one dimension is requested, just return the first one found
3733 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3735 if( ( dimension & ( 1 << i ) ) )
3737 return mRelayoutData->negotiatedDimensions[ i ];
3741 return 0.0f; // Default
3744 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3746 EnsureRelayoutData();
3748 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3750 if( dimension & ( 1 << i ) )
3752 mRelayoutData->dimensionPadding[ i ] = padding;
3757 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3759 if ( mRelayoutData )
3761 // If more than one dimension is requested, just return the first one found
3762 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3764 if( ( dimension & ( 1 << i ) ) )
3766 return mRelayoutData->dimensionPadding[ i ];
3771 return GetDefaultDimensionPadding();
3774 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3776 EnsureRelayoutData();
3778 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3780 if( dimension & ( 1 << i ) )
3782 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3787 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3789 if ( mRelayoutData )
3791 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3793 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3803 float Actor::GetHeightForWidthBase( float width )
3805 float height = 0.0f;
3807 const Vector3 naturalSize = GetNaturalSize();
3808 if( naturalSize.width > 0.0f )
3810 height = naturalSize.height * width / naturalSize.width;
3812 else // we treat 0 as 1:1 aspect ratio
3820 float Actor::GetWidthForHeightBase( float height )
3824 const Vector3 naturalSize = GetNaturalSize();
3825 if( naturalSize.height > 0.0f )
3827 width = naturalSize.width * height / naturalSize.height;
3829 else // we treat 0 as 1:1 aspect ratio
3837 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3839 // Fill to parent, taking size mode factor into account
3840 switch( child.GetResizePolicy( dimension ) )
3842 case ResizePolicy::FILL_TO_PARENT:
3844 return GetLatestSize( dimension );
3847 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3849 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3852 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3854 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3859 return GetLatestSize( dimension );
3864 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3866 // Can be overridden in derived class
3867 return CalculateChildSizeBase( child, dimension );
3870 float Actor::GetHeightForWidth( float width )
3872 // Can be overridden in derived class
3873 return GetHeightForWidthBase( width );
3876 float Actor::GetWidthForHeight( float height )
3878 // Can be overridden in derived class
3879 return GetWidthForHeightBase( height );
3882 float Actor::GetLatestSize( Dimension::Type dimension ) const
3884 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3887 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3889 Vector2 padding = GetPadding( dimension );
3891 return GetLatestSize( dimension ) + padding.x + padding.y;
3894 float Actor::NegotiateFromParent( Dimension::Type dimension )
3896 Actor* parent = GetParent();
3899 Vector2 padding( GetPadding( dimension ) );
3900 Vector2 parentPadding( parent->GetPadding( dimension ) );
3901 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3907 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3909 float maxDimensionPoint = 0.0f;
3911 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3913 ActorPtr child = GetChildAt( i );
3915 if( !child->RelayoutDependentOnParent( dimension ) )
3917 // Calculate the min and max points that the children range across
3918 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3919 float dimensionSize = child->GetRelayoutSize( dimension );
3920 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3924 return maxDimensionPoint;
3927 float Actor::GetSize( Dimension::Type dimension ) const
3929 return GetDimensionValue( GetTargetSize(), dimension );
3932 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3934 return GetDimensionValue( GetNaturalSize(), dimension );
3937 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3939 switch( GetResizePolicy( dimension ) )
3941 case ResizePolicy::USE_NATURAL_SIZE:
3943 return GetNaturalSize( dimension );
3946 case ResizePolicy::FIXED:
3948 return GetDimensionValue( GetPreferredSize(), dimension );
3951 case ResizePolicy::USE_ASSIGNED_SIZE:
3953 return GetDimensionValue( maximumSize, dimension );
3956 case ResizePolicy::FILL_TO_PARENT:
3957 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3958 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3960 return NegotiateFromParent( dimension );
3963 case ResizePolicy::FIT_TO_CHILDREN:
3965 return NegotiateFromChildren( dimension );
3968 case ResizePolicy::DIMENSION_DEPENDENCY:
3970 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3973 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3975 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3978 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3980 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3992 return 0.0f; // Default
3995 float Actor::ClampDimension( float size, Dimension::Type dimension )
3997 const float minSize = GetMinimumSize( dimension );
3998 const float maxSize = GetMaximumSize( dimension );
4000 return std::max( minSize, std::min( size, maxSize ) );
4003 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4005 // Check if it needs to be negotiated
4006 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4008 // Check that we havn't gotten into an infinite loop
4009 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4010 bool recursionFound = false;
4011 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4013 if( *it == searchActor )
4015 recursionFound = true;
4020 if( !recursionFound )
4022 // Record the path that we have taken
4023 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4025 // Dimension dependency check
4026 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4028 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4030 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4032 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4036 // Parent dependency check
4037 Actor* parent = GetParent();
4038 if( parent && RelayoutDependentOnParent( dimension ) )
4040 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4043 // Children dependency check
4044 if( RelayoutDependentOnChildren( dimension ) )
4046 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4048 ActorPtr child = GetChildAt( i );
4050 // Only relayout child first if it is not dependent on this actor
4051 if( !child->RelayoutDependentOnParent( dimension ) )
4053 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4058 // For deriving classes
4059 OnCalculateRelayoutSize( dimension );
4061 // All dependencies checked, calculate the size and set negotiated flag
4062 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4064 SetNegotiatedDimension( newSize, dimension );
4065 SetLayoutNegotiated( true, dimension );
4067 // For deriving classes
4068 OnLayoutNegotiated( newSize, dimension );
4070 // This actor has been successfully processed, pop it off the recursion stack
4071 recursionStack.pop_back();
4075 // TODO: Break infinite loop
4076 SetLayoutNegotiated( true, dimension );
4081 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4083 // Negotiate all dimensions that require it
4084 ActorDimensionStack recursionStack;
4086 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4088 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4091 NegotiateDimension( dimension, allocatedSize, recursionStack );
4095 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4097 switch( mRelayoutData->sizeSetPolicy )
4099 case SizeScalePolicy::USE_SIZE_SET:
4104 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4106 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4107 const Vector3 naturalSize = GetNaturalSize();
4108 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4110 const float sizeRatio = size.width / size.height;
4111 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4113 if( naturalSizeRatio < sizeRatio )
4115 return Vector2( naturalSizeRatio * size.height, size.height );
4117 else if( naturalSizeRatio > sizeRatio )
4119 return Vector2( size.width, size.width / naturalSizeRatio );
4130 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4132 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4133 const Vector3 naturalSize = GetNaturalSize();
4134 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4136 const float sizeRatio = size.width / size.height;
4137 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4139 if( naturalSizeRatio < sizeRatio )
4141 return Vector2( size.width, size.width / naturalSizeRatio );
4143 else if( naturalSizeRatio > sizeRatio )
4145 return Vector2( naturalSizeRatio * size.height, size.height );
4164 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4166 // Do the set actor size
4167 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4169 // Adjust for size set policy
4170 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4172 // Lock the flag to stop recursive relayouts on set size
4173 mRelayoutData->insideRelayout = true;
4174 SetSize( negotiatedSize );
4175 mRelayoutData->insideRelayout = false;
4177 // Clear flags for all dimensions
4178 SetLayoutDirty( false );
4180 // Give deriving classes a chance to respond
4181 OnRelayout( negotiatedSize, container );
4183 if( !mOnRelayoutSignal.Empty() )
4185 Dali::Actor handle( this );
4186 mOnRelayoutSignal.Emit( handle );
4190 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4192 // Force a size negotiation for actors that has assigned size during relayout
4193 // This is required as otherwise the flags that force a relayout will not
4194 // necessarilly be set. This will occur if the actor has already been laid out.
4195 // The dirty flags are then cleared. Then if the actor is added back into the
4196 // relayout container afterwards, the dirty flags would still be clear...
4197 // causing a relayout to be skipped. Here we force any actors added to the
4198 // container to be relayed out.
4199 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4201 SetLayoutNegotiated(false, Dimension::WIDTH);
4203 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4205 SetLayoutNegotiated(false, Dimension::HEIGHT);
4208 // Do the negotiation
4209 NegotiateDimensions( allocatedSize );
4211 // Set the actor size
4212 SetNegotiatedSize( container );
4214 // Negotiate down to children
4215 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4217 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4219 ActorPtr child = GetChildAt( i );
4221 // Forces children that have already been laid out to be relayed out
4222 // if they have assigned size during relayout.
4223 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4225 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4226 child->SetLayoutDirty(true, Dimension::WIDTH);
4228 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4230 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4231 child->SetLayoutDirty(true, Dimension::HEIGHT);
4234 // Only relayout if required
4235 if( child->RelayoutRequired() )
4237 container.Add( Dali::Actor( child.Get() ), newBounds );
4242 void Actor::RelayoutRequest( Dimension::Type dimension )
4244 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4245 if( relayoutController )
4247 Dali::Actor self( this );
4248 relayoutController->RequestRelayout( self, dimension );
4252 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4256 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4260 void Actor::SetPreferredSize( const Vector2& size )
4262 EnsureRelayoutData();
4264 if( size.width > 0.0f )
4266 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4269 if( size.height > 0.0f )
4271 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4274 mRelayoutData->preferredSize = size;
4279 Vector2 Actor::GetPreferredSize() const
4281 if ( mRelayoutData )
4283 return Vector2( mRelayoutData->preferredSize );
4286 return GetDefaultPreferredSize();
4289 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4291 EnsureRelayoutData();
4293 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4295 if( dimension & ( 1 << i ) )
4297 mRelayoutData->minimumSize[ i ] = size;
4304 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4306 if ( mRelayoutData )
4308 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4310 if( dimension & ( 1 << i ) )
4312 return mRelayoutData->minimumSize[ i ];
4317 return 0.0f; // Default
4320 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4322 EnsureRelayoutData();
4324 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4326 if( dimension & ( 1 << i ) )
4328 mRelayoutData->maximumSize[ i ] = size;
4335 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4337 if ( mRelayoutData )
4339 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4341 if( dimension & ( 1 << i ) )
4343 return mRelayoutData->maximumSize[ i ];
4348 return FLT_MAX; // Default
4351 Object* Actor::GetParentObject() const
4356 } // namespace Internal