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 mRelayoutData->relayoutEnabled = relayoutEnabled;
1393 bool Actor::IsRelayoutEnabled() const
1395 // Assume that if relayout data has not been allocated yet then
1396 // relayout is disabled
1397 return mRelayoutData && mRelayoutData->relayoutEnabled;
1400 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1402 EnsureRelayoutData();
1404 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1406 if( dimension & ( 1 << i ) )
1408 mRelayoutData->dimensionDirty[ i ] = dirty;
1413 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1415 if ( mRelayoutData )
1417 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1419 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1429 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1431 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1434 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1436 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1439 unsigned int Actor::AddRenderer( Renderer& renderer )
1443 mRenderers = new RendererContainer;
1446 unsigned int index = mRenderers->size();
1447 RendererPtr rendererPtr = RendererPtr( &renderer );
1448 mRenderers->push_back( rendererPtr );
1449 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1453 rendererPtr->Connect();
1459 unsigned int Actor::GetRendererCount() const
1461 unsigned int rendererCount(0);
1464 rendererCount = mRenderers->size();
1467 return rendererCount;
1470 RendererPtr Actor::GetRendererAt( unsigned int index )
1472 RendererPtr renderer;
1473 if( index < GetRendererCount() )
1475 renderer = ( *mRenderers )[ index ];
1481 void Actor::RemoveRenderer( Renderer& renderer )
1485 RendererIter end = mRenderers->end();
1486 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1488 if( (*iter).Get() == &renderer )
1490 mRenderers->erase( iter );
1491 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1498 void Actor::RemoveRenderer( unsigned int index )
1500 if( index < GetRendererCount() )
1502 RendererPtr renderer = ( *mRenderers )[ index ];
1503 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1504 mRenderers->erase( mRenderers->begin()+index );
1508 bool Actor::IsOverlay() const
1510 return ( DrawMode::OVERLAY_2D == mDrawMode );
1513 void Actor::SetDrawMode( DrawMode::Type drawMode )
1515 // this flag is not animatable so keep the value
1516 mDrawMode = drawMode;
1517 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1519 // mNode is being used in a separate thread; queue a message to set the value
1520 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1524 DrawMode::Type Actor::GetDrawMode() const
1529 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1531 // only valid when on-stage
1532 StagePtr stage = Stage::GetCurrent();
1533 if( stage && OnStage() )
1535 const RenderTaskList& taskList = stage->GetRenderTaskList();
1537 Vector2 converted( screenX, screenY );
1539 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1540 const int taskCount = taskList.GetTaskCount();
1541 for( int i = taskCount - 1; i >= 0; --i )
1543 Dali::RenderTask task = taskList.GetTask( i );
1544 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1546 // found a task where this conversion was ok so return
1554 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1556 bool retval = false;
1557 // only valid when on-stage
1560 CameraActor* camera = renderTask.GetCameraActor();
1564 renderTask.GetViewport( viewport );
1566 // need to translate coordinates to render tasks coordinate space
1567 Vector2 converted( screenX, screenY );
1568 if( renderTask.TranslateCoordinates( converted ) )
1570 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1577 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1579 // Early-out if mNode is NULL
1585 // Get the ModelView matrix
1587 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1589 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1590 Matrix invertedMvp( false/*don't init*/);
1591 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1592 bool success = invertedMvp.Invert();
1594 // Convert to GL coordinates
1595 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1600 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1607 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1613 if( XyPlaneIntersect( nearPos, farPos, local ) )
1615 Vector3 size = GetCurrentSize();
1616 localX = local.x + size.x * 0.5f;
1617 localY = local.y + size.y * 0.5f;
1628 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1631 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1633 Mathematical Formulation
1635 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1637 ( p - c ) dot ( p - c ) = r^2
1639 Given a ray with a point of origin 'o', and a direction vector 'd':
1641 ray(t) = o + td, t >= 0
1643 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1645 (o + td - c ) dot ( o + td - c ) = r^2
1647 To solve for t we first expand the above into a more recognisable quadratic equation form
1649 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1658 B = 2( o - c ) dot d
1659 C = ( o - c ) dot ( o - c ) - r^2
1661 which can be solved using a standard quadratic formula.
1663 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1665 Practical Simplification
1667 In a renderer, we often differentiate between world space and object space. In the object space
1668 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1669 into object space, the mathematical solution presented above can be simplified significantly.
1671 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1675 and we can find the t at which the (transformed) ray intersects the sphere by
1677 ( o + td ) dot ( o + td ) = r^2
1679 According to the reasoning above, we expand the above quadratic equation into the general form
1683 which now has coefficients:
1690 // Early out if mNode is NULL
1696 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1698 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1699 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1700 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1702 // Compute the radius is not needed, square radius it's enough.
1703 const Vector3& size( mNode->GetSize( bufferIndex ) );
1705 // Scale the sphere.
1706 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1708 const float width = size.width * scale.width;
1709 const float height = size.height * scale.height;
1711 float squareSphereRadius = 0.5f * ( width * width + height * height );
1713 float a = rayDir.Dot( rayDir ); // a
1714 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1715 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1717 return ( b2 * b2 - a * c ) >= 0.f;
1720 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1724 if( OnStage() && NULL != mNode )
1726 // Transforms the ray to the local reference system.
1727 // Calculate the inverse of Model matrix
1728 Matrix invModelMatrix( false/*don't init*/);
1730 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1731 invModelMatrix = mNode->GetWorldMatrix(0);
1732 invModelMatrix.Invert();
1734 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1735 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1737 // Test with the actor's XY plane (Normal = 0 0 1 1).
1739 float a = -rayOriginLocal.z;
1740 float b = rayDirLocal.z;
1742 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1744 // Ray travels distance * rayDirLocal to intersect with plane.
1747 const Vector3& size = mNode->GetSize( bufferIndex );
1749 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1750 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1752 // Test with the actor's geometry.
1753 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1760 void Actor::SetLeaveRequired( bool required )
1762 mLeaveRequired = required;
1765 bool Actor::GetLeaveRequired() const
1767 return mLeaveRequired;
1770 void Actor::SetKeyboardFocusable( bool focusable )
1772 mKeyboardFocusable = focusable;
1775 bool Actor::IsKeyboardFocusable() const
1777 return mKeyboardFocusable;
1780 bool Actor::GetTouchRequired() const
1782 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1785 bool Actor::GetHoverRequired() const
1787 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1790 bool Actor::GetWheelEventRequired() const
1792 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1795 bool Actor::IsHittable() const
1797 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1800 ActorGestureData& Actor::GetGestureData()
1802 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1803 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1804 if( NULL == mGestureData )
1806 mGestureData = new ActorGestureData;
1808 return *mGestureData;
1811 bool Actor::IsGestureRequred( Gesture::Type type ) const
1813 return mGestureData && mGestureData->IsGestureRequred( type );
1816 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1818 bool consumed = false;
1820 if( !mTouchSignal.Empty() )
1822 Dali::Actor handle( this );
1823 consumed = mTouchSignal.Emit( handle, touch );
1826 if( !mTouchedSignal.Empty() )
1828 Dali::Actor handle( this );
1829 consumed |= mTouchedSignal.Emit( handle, event );
1834 // Notification for derived classes
1835 consumed = OnTouchEvent( event ); // TODO
1841 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1843 bool consumed = false;
1845 if( !mHoveredSignal.Empty() )
1847 Dali::Actor handle( this );
1848 consumed = mHoveredSignal.Emit( handle, event );
1853 // Notification for derived classes
1854 consumed = OnHoverEvent( event );
1860 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1862 bool consumed = false;
1864 if( !mWheelEventSignal.Empty() )
1866 Dali::Actor handle( this );
1867 consumed = mWheelEventSignal.Emit( handle, event );
1872 // Notification for derived classes
1873 consumed = OnWheelEvent( event );
1879 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1881 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1882 return mTouchedSignal;
1885 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1887 return mTouchSignal;
1890 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1892 return mHoveredSignal;
1895 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1897 return mWheelEventSignal;
1900 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1902 return mOnStageSignal;
1905 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1907 return mOffStageSignal;
1910 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1912 return mOnRelayoutSignal;
1915 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1917 bool connected( true );
1918 Actor* actor = dynamic_cast< Actor* >( object );
1920 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1922 actor->TouchedSignal().Connect( tracker, functor );
1924 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1926 actor->HoveredSignal().Connect( tracker, functor );
1928 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1930 actor->WheelEventSignal().Connect( tracker, functor );
1932 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1934 actor->OnStageSignal().Connect( tracker, functor );
1936 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1938 actor->OffStageSignal().Connect( tracker, functor );
1940 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1942 actor->OnRelayoutSignal().Connect( tracker, functor );
1944 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1946 actor->TouchSignal().Connect( tracker, functor );
1950 // signalName does not match any signal
1957 Actor::Actor( DerivedType derivedType )
1962 mParentOrigin( NULL ),
1963 mAnchorPoint( NULL ),
1964 mRelayoutData( NULL ),
1965 mGestureData( NULL ),
1966 mTargetSize( 0.0f, 0.0f, 0.0f ),
1968 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1970 mIsRoot( ROOT_LAYER == derivedType ),
1971 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1972 mIsOnStage( false ),
1974 mLeaveRequired( false ),
1975 mKeyboardFocusable( false ),
1976 mDerivedRequiresTouch( false ),
1977 mDerivedRequiresHover( false ),
1978 mDerivedRequiresWheelEvent( false ),
1979 mOnStageSignalled( false ),
1980 mInsideOnSizeSet( false ),
1981 mInheritPosition( true ),
1982 mInheritOrientation( true ),
1983 mInheritScale( true ),
1984 mDrawMode( DrawMode::NORMAL ),
1985 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1986 mColorMode( Node::DEFAULT_COLOR_MODE ),
1987 mClippingMode( ClippingMode::DISABLED ),
1988 mIsBatchParent( false )
1992 void Actor::Initialize()
1995 SceneGraph::Node* node = CreateNode();
1997 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
1998 mNode = node; // Keep raw-pointer to Node
2002 GetEventThreadServices().RegisterObject( this );
2007 // Remove mParent pointers from children even if we're destroying core,
2008 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2011 ActorConstIter endIter = mChildren->end();
2012 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2014 (*iter)->SetParent( NULL );
2020 // Guard to allow handle destruction after Core has been destroyed
2021 if( EventThreadServices::IsCoreRunning() )
2025 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2026 mNode = NULL; // Node is about to be destroyed
2029 GetEventThreadServices().UnregisterObject( this );
2032 // Cleanup optional gesture data
2033 delete mGestureData;
2035 // Cleanup optional parent origin and anchor
2036 delete mParentOrigin;
2037 delete mAnchorPoint;
2039 // Delete optional relayout data
2042 delete mRelayoutData;
2046 void Actor::ConnectToStage( unsigned int parentDepth )
2048 // This container is used instead of walking the Actor hierarchy.
2049 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2050 ActorContainer connectionList;
2052 // This stage is atomic i.e. not interrupted by user callbacks.
2053 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2055 // Notify applications about the newly connected actors.
2056 const ActorIter endIter = connectionList.end();
2057 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2059 (*iter)->NotifyStageConnection();
2065 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2067 DALI_ASSERT_ALWAYS( !OnStage() );
2072 ConnectToSceneGraph();
2074 // Notification for internal derived classes
2075 OnStageConnectionInternal();
2077 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2078 connectionList.push_back( ActorPtr( this ) );
2080 // Recursively connect children
2083 ActorConstIter endIter = mChildren->end();
2084 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2086 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2092 * This method is called when the Actor is connected to the Stage.
2093 * The parent must have added its Node to the scene-graph.
2094 * The child must connect its Node to the parent's Node.
2095 * This is recursive; the child calls ConnectToStage() for its children.
2097 void Actor::ConnectToSceneGraph()
2099 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2103 // Reparent Node in next Update
2104 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2107 unsigned int rendererCount( GetRendererCount() );
2108 for( unsigned int i(0); i<rendererCount; ++i )
2110 GetRendererAt(i)->Connect();
2113 // Request relayout on all actors that are added to the scenegraph
2116 // Notification for Object::Observers
2120 void Actor::NotifyStageConnection()
2122 // Actors can be removed (in a callback), before the on-stage stage is reported.
2123 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2124 if( OnStage() && !mOnStageSignalled )
2126 // Notification for external (CustomActor) derived classes
2127 OnStageConnectionExternal( mDepth );
2129 if( !mOnStageSignal.Empty() )
2131 Dali::Actor handle( this );
2132 mOnStageSignal.Emit( handle );
2135 // Guard against Remove during callbacks
2138 mOnStageSignalled = true; // signal required next time Actor is removed
2143 void Actor::DisconnectFromStage()
2145 // This container is used instead of walking the Actor hierachy.
2146 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2147 ActorContainer disconnectionList;
2149 // This stage is atomic i.e. not interrupted by user callbacks
2150 RecursiveDisconnectFromStage( disconnectionList );
2152 // Notify applications about the newly disconnected actors.
2153 const ActorIter endIter = disconnectionList.end();
2154 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2156 (*iter)->NotifyStageDisconnection();
2160 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2162 DALI_ASSERT_ALWAYS( OnStage() );
2164 // Recursively disconnect children
2167 ActorConstIter endIter = mChildren->end();
2168 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2170 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2174 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2175 disconnectionList.push_back( ActorPtr( this ) );
2177 // Notification for internal derived classes
2178 OnStageDisconnectionInternal();
2180 DisconnectFromSceneGraph();
2186 * This method is called by an actor or its parent, before a node removal message is sent.
2187 * This is recursive; the child calls DisconnectFromStage() for its children.
2189 void Actor::DisconnectFromSceneGraph()
2191 // Notification for Object::Observers
2192 OnSceneObjectRemove();
2194 unsigned int rendererCount( GetRendererCount() );
2195 for( unsigned int i(0); i<rendererCount; ++i )
2197 GetRendererAt(i)->Disconnect();
2201 void Actor::NotifyStageDisconnection()
2203 // Actors can be added (in a callback), before the off-stage state is reported.
2204 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2205 // only do this step if there is a stage, i.e. Core is not being shut down
2206 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2208 // Notification for external (CustomeActor) derived classes
2209 OnStageDisconnectionExternal();
2211 if( !mOffStageSignal.Empty() )
2213 Dali::Actor handle( this );
2214 mOffStageSignal.Emit( handle );
2217 // Guard against Add during callbacks
2220 mOnStageSignalled = false; // signal required next time Actor is added
2225 bool Actor::IsNodeConnected() const
2227 bool connected( false );
2229 if( OnStage() && ( NULL != mNode ) )
2231 if( IsRoot() || mNode->GetParent() )
2240 unsigned int Actor::GetDefaultPropertyCount() const
2242 return DEFAULT_PROPERTY_COUNT;
2245 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2247 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2249 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2251 indices.PushBack( i );
2255 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2257 if( index < DEFAULT_PROPERTY_COUNT )
2259 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2265 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2267 Property::Index index = Property::INVALID_INDEX;
2269 // Look for name in default properties
2270 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2272 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2273 if( 0 == name.compare( property->name ) )
2283 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2285 if( index < DEFAULT_PROPERTY_COUNT )
2287 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2293 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2295 if( index < DEFAULT_PROPERTY_COUNT )
2297 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2303 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2305 if( index < DEFAULT_PROPERTY_COUNT )
2307 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2313 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2315 if( index < DEFAULT_PROPERTY_COUNT )
2317 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2320 // index out of range...return Property::NONE
2321 return Property::NONE;
2324 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2328 case Dali::Actor::Property::PARENT_ORIGIN:
2330 Property::Type type = property.GetType();
2331 if( type == Property::VECTOR3 )
2333 SetParentOrigin( property.Get< Vector3 >() );
2335 else if ( type == Property::STRING )
2337 std::string parentOriginString;
2338 property.Get( parentOriginString );
2339 Vector3 parentOrigin;
2340 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2342 SetParentOrigin( parentOrigin );
2348 case Dali::Actor::Property::PARENT_ORIGIN_X:
2350 SetParentOriginX( property.Get< float >() );
2354 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2356 SetParentOriginY( property.Get< float >() );
2360 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2362 SetParentOriginZ( property.Get< float >() );
2366 case Dali::Actor::Property::ANCHOR_POINT:
2368 Property::Type type = property.GetType();
2369 if( type == Property::VECTOR3 )
2371 SetAnchorPoint( property.Get< Vector3 >() );
2373 else if ( type == Property::STRING )
2375 std::string anchorPointString;
2376 property.Get( anchorPointString );
2378 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2380 SetAnchorPoint( anchor );
2386 case Dali::Actor::Property::ANCHOR_POINT_X:
2388 SetAnchorPointX( property.Get< float >() );
2392 case Dali::Actor::Property::ANCHOR_POINT_Y:
2394 SetAnchorPointY( property.Get< float >() );
2398 case Dali::Actor::Property::ANCHOR_POINT_Z:
2400 SetAnchorPointZ( property.Get< float >() );
2404 case Dali::Actor::Property::SIZE:
2406 SetSize( property.Get< Vector3 >() );
2410 case Dali::Actor::Property::SIZE_WIDTH:
2412 SetWidth( property.Get< float >() );
2416 case Dali::Actor::Property::SIZE_HEIGHT:
2418 SetHeight( property.Get< float >() );
2422 case Dali::Actor::Property::SIZE_DEPTH:
2424 SetDepth( property.Get< float >() );
2428 case Dali::Actor::Property::POSITION:
2430 SetPosition( property.Get< Vector3 >() );
2434 case Dali::Actor::Property::POSITION_X:
2436 SetX( property.Get< float >() );
2440 case Dali::Actor::Property::POSITION_Y:
2442 SetY( property.Get< float >() );
2446 case Dali::Actor::Property::POSITION_Z:
2448 SetZ( property.Get< float >() );
2452 case Dali::Actor::Property::ORIENTATION:
2454 SetOrientation( property.Get< Quaternion >() );
2458 case Dali::Actor::Property::SCALE:
2460 SetScale( property.Get< Vector3 >() );
2464 case Dali::Actor::Property::SCALE_X:
2466 SetScaleX( property.Get< float >() );
2470 case Dali::Actor::Property::SCALE_Y:
2472 SetScaleY( property.Get< float >() );
2476 case Dali::Actor::Property::SCALE_Z:
2478 SetScaleZ( property.Get< float >() );
2482 case Dali::Actor::Property::VISIBLE:
2484 SetVisible( property.Get< bool >() );
2488 case Dali::Actor::Property::COLOR:
2490 SetColor( property.Get< Vector4 >() );
2494 case Dali::Actor::Property::COLOR_RED:
2496 SetColorRed( property.Get< float >() );
2500 case Dali::Actor::Property::COLOR_GREEN:
2502 SetColorGreen( property.Get< float >() );
2506 case Dali::Actor::Property::COLOR_BLUE:
2508 SetColorBlue( property.Get< float >() );
2512 case Dali::Actor::Property::COLOR_ALPHA:
2514 SetOpacity( property.Get< float >() );
2518 case Dali::Actor::Property::NAME:
2520 SetName( property.Get< std::string >() );
2524 case Dali::Actor::Property::SENSITIVE:
2526 SetSensitive( property.Get< bool >() );
2530 case Dali::Actor::Property::LEAVE_REQUIRED:
2532 SetLeaveRequired( property.Get< bool >() );
2536 case Dali::Actor::Property::INHERIT_POSITION:
2538 SetInheritPosition( property.Get< bool >() );
2542 case Dali::Actor::Property::INHERIT_ORIENTATION:
2544 SetInheritOrientation( property.Get< bool >() );
2548 case Dali::Actor::Property::INHERIT_SCALE:
2550 SetInheritScale( property.Get< bool >() );
2554 case Dali::Actor::Property::COLOR_MODE:
2557 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2559 SetColorMode( mode );
2564 case Dali::Actor::Property::POSITION_INHERITANCE:
2566 PositionInheritanceMode mode;
2567 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2569 SetPositionInheritanceMode( mode );
2574 case Dali::Actor::Property::DRAW_MODE:
2576 DrawMode::Type mode;
2577 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2579 SetDrawMode( mode );
2584 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2586 SetSizeModeFactor( property.Get< Vector3 >() );
2590 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2592 ResizePolicy::Type type;
2593 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2595 SetResizePolicy( type, Dimension::WIDTH );
2600 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2602 ResizePolicy::Type type;
2603 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2605 SetResizePolicy( type, Dimension::HEIGHT );
2610 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2612 SizeScalePolicy::Type type;
2613 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2615 SetSizeScalePolicy( type );
2620 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2622 if( property.Get< bool >() )
2624 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2629 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2631 if( property.Get< bool >() )
2633 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2638 case Dali::Actor::Property::PADDING:
2640 Vector4 padding = property.Get< Vector4 >();
2641 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2642 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2646 case Dali::Actor::Property::MINIMUM_SIZE:
2648 Vector2 size = property.Get< Vector2 >();
2649 SetMinimumSize( size.x, Dimension::WIDTH );
2650 SetMinimumSize( size.y, Dimension::HEIGHT );
2654 case Dali::Actor::Property::MAXIMUM_SIZE:
2656 Vector2 size = property.Get< Vector2 >();
2657 SetMaximumSize( size.x, Dimension::WIDTH );
2658 SetMaximumSize( size.y, Dimension::HEIGHT );
2662 case Dali::Actor::Property::BATCH_PARENT:
2666 if( property.Get( value ) )
2668 if( value != mIsBatchParent )
2670 mIsBatchParent = value;
2671 SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2677 case Dali::Actor::Property::CLIPPING_MODE:
2679 ClippingMode::Type convertedValue = mClippingMode;
2680 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2682 mClippingMode = convertedValue;
2685 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2693 // this can happen in the case of a non-animatable default property so just do nothing
2699 // TODO: This method needs to be removed
2700 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2702 switch( entry.GetType() )
2704 case Property::BOOLEAN:
2706 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2707 DALI_ASSERT_DEBUG( NULL != property );
2709 // property is being used in a separate thread; queue a message to set the property
2710 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2715 case Property::INTEGER:
2717 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2718 DALI_ASSERT_DEBUG( NULL != property );
2720 // property is being used in a separate thread; queue a message to set the property
2721 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2726 case Property::FLOAT:
2728 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2729 DALI_ASSERT_DEBUG( NULL != property );
2731 // property is being used in a separate thread; queue a message to set the property
2732 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2737 case Property::VECTOR2:
2739 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2740 DALI_ASSERT_DEBUG( NULL != property );
2742 // property is being used in a separate thread; queue a message to set the property
2743 if(entry.componentIndex == 0)
2745 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2747 else if(entry.componentIndex == 1)
2749 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2753 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2759 case Property::VECTOR3:
2761 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2762 DALI_ASSERT_DEBUG( NULL != property );
2764 // property is being used in a separate thread; queue a message to set the property
2765 if(entry.componentIndex == 0)
2767 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2769 else if(entry.componentIndex == 1)
2771 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2773 else if(entry.componentIndex == 2)
2775 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2779 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2785 case Property::VECTOR4:
2787 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2788 DALI_ASSERT_DEBUG( NULL != property );
2790 // property is being used in a separate thread; queue a message to set the property
2791 if(entry.componentIndex == 0)
2793 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2795 else if(entry.componentIndex == 1)
2797 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2799 else if(entry.componentIndex == 2)
2801 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2803 else if(entry.componentIndex == 3)
2805 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2809 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2815 case Property::ROTATION:
2817 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2818 DALI_ASSERT_DEBUG( NULL != property );
2820 // property is being used in a separate thread; queue a message to set the property
2821 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2826 case Property::MATRIX:
2828 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2829 DALI_ASSERT_DEBUG( NULL != property );
2831 // property is being used in a separate thread; queue a message to set the property
2832 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2837 case Property::MATRIX3:
2839 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2840 DALI_ASSERT_DEBUG( NULL != property );
2842 // property is being used in a separate thread; queue a message to set the property
2843 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2850 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2856 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2858 Property::Value value;
2862 case Dali::Actor::Property::PARENT_ORIGIN:
2864 value = GetCurrentParentOrigin();
2868 case Dali::Actor::Property::PARENT_ORIGIN_X:
2870 value = GetCurrentParentOrigin().x;
2874 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2876 value = GetCurrentParentOrigin().y;
2880 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2882 value = GetCurrentParentOrigin().z;
2886 case Dali::Actor::Property::ANCHOR_POINT:
2888 value = GetCurrentAnchorPoint();
2892 case Dali::Actor::Property::ANCHOR_POINT_X:
2894 value = GetCurrentAnchorPoint().x;
2898 case Dali::Actor::Property::ANCHOR_POINT_Y:
2900 value = GetCurrentAnchorPoint().y;
2904 case Dali::Actor::Property::ANCHOR_POINT_Z:
2906 value = GetCurrentAnchorPoint().z;
2910 case Dali::Actor::Property::SIZE:
2912 value = GetTargetSize();
2916 case Dali::Actor::Property::SIZE_WIDTH:
2918 value = GetTargetSize().width;
2922 case Dali::Actor::Property::SIZE_HEIGHT:
2924 value = GetTargetSize().height;
2928 case Dali::Actor::Property::SIZE_DEPTH:
2930 value = GetTargetSize().depth;
2934 case Dali::Actor::Property::POSITION:
2936 value = GetTargetPosition();
2940 case Dali::Actor::Property::POSITION_X:
2942 value = GetTargetPosition().x;
2946 case Dali::Actor::Property::POSITION_Y:
2948 value = GetTargetPosition().y;
2952 case Dali::Actor::Property::POSITION_Z:
2954 value = GetTargetPosition().z;
2958 case Dali::Actor::Property::WORLD_POSITION:
2960 value = GetCurrentWorldPosition();
2964 case Dali::Actor::Property::WORLD_POSITION_X:
2966 value = GetCurrentWorldPosition().x;
2970 case Dali::Actor::Property::WORLD_POSITION_Y:
2972 value = GetCurrentWorldPosition().y;
2976 case Dali::Actor::Property::WORLD_POSITION_Z:
2978 value = GetCurrentWorldPosition().z;
2982 case Dali::Actor::Property::ORIENTATION:
2984 value = GetCurrentOrientation();
2988 case Dali::Actor::Property::WORLD_ORIENTATION:
2990 value = GetCurrentWorldOrientation();
2994 case Dali::Actor::Property::SCALE:
2996 value = GetCurrentScale();
3000 case Dali::Actor::Property::SCALE_X:
3002 value = GetCurrentScale().x;
3006 case Dali::Actor::Property::SCALE_Y:
3008 value = GetCurrentScale().y;
3012 case Dali::Actor::Property::SCALE_Z:
3014 value = GetCurrentScale().z;
3018 case Dali::Actor::Property::WORLD_SCALE:
3020 value = GetCurrentWorldScale();
3024 case Dali::Actor::Property::VISIBLE:
3026 value = IsVisible();
3030 case Dali::Actor::Property::COLOR:
3032 value = GetCurrentColor();
3036 case Dali::Actor::Property::COLOR_RED:
3038 value = GetCurrentColor().r;
3042 case Dali::Actor::Property::COLOR_GREEN:
3044 value = GetCurrentColor().g;
3048 case Dali::Actor::Property::COLOR_BLUE:
3050 value = GetCurrentColor().b;
3054 case Dali::Actor::Property::COLOR_ALPHA:
3056 value = GetCurrentColor().a;
3060 case Dali::Actor::Property::WORLD_COLOR:
3062 value = GetCurrentWorldColor();
3066 case Dali::Actor::Property::WORLD_MATRIX:
3068 value = GetCurrentWorldMatrix();
3072 case Dali::Actor::Property::NAME:
3078 case Dali::Actor::Property::SENSITIVE:
3080 value = IsSensitive();
3084 case Dali::Actor::Property::LEAVE_REQUIRED:
3086 value = GetLeaveRequired();
3090 case Dali::Actor::Property::INHERIT_POSITION:
3092 value = IsPositionInherited();
3096 case Dali::Actor::Property::INHERIT_ORIENTATION:
3098 value = IsOrientationInherited();
3102 case Dali::Actor::Property::INHERIT_SCALE:
3104 value = IsScaleInherited();
3108 case Dali::Actor::Property::COLOR_MODE:
3110 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3114 case Dali::Actor::Property::POSITION_INHERITANCE:
3116 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3120 case Dali::Actor::Property::DRAW_MODE:
3122 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3126 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3128 value = GetSizeModeFactor();
3132 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3134 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3138 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3140 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3144 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3146 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3150 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3152 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3156 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3158 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3162 case Dali::Actor::Property::PADDING:
3164 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3165 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3166 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3170 case Dali::Actor::Property::MINIMUM_SIZE:
3172 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3176 case Dali::Actor::Property::MAXIMUM_SIZE:
3178 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3182 case Dali::Actor::Property::BATCH_PARENT:
3184 value = mIsBatchParent;
3188 case Dali::Actor::Property::CLIPPING_MODE:
3190 value = mClippingMode;
3196 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3204 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3209 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3211 // This method should only return an object connected to the scene-graph
3212 return OnStage() ? mNode : NULL;
3215 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3217 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3219 const PropertyBase* property( NULL );
3221 // This method should only return a property of an object connected to the scene-graph
3227 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3229 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3230 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3232 property = animatable->GetSceneGraphProperty();
3234 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3235 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3237 CustomPropertyMetadata* custom = FindCustomProperty( index );
3238 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3240 property = custom->GetSceneGraphProperty();
3242 else if( NULL != mNode )
3246 case Dali::Actor::Property::SIZE:
3247 property = &mNode->mSize;
3250 case Dali::Actor::Property::SIZE_WIDTH:
3251 property = &mNode->mSize;
3254 case Dali::Actor::Property::SIZE_HEIGHT:
3255 property = &mNode->mSize;
3258 case Dali::Actor::Property::SIZE_DEPTH:
3259 property = &mNode->mSize;
3262 case Dali::Actor::Property::POSITION:
3263 property = &mNode->mPosition;
3266 case Dali::Actor::Property::POSITION_X:
3267 property = &mNode->mPosition;
3270 case Dali::Actor::Property::POSITION_Y:
3271 property = &mNode->mPosition;
3274 case Dali::Actor::Property::POSITION_Z:
3275 property = &mNode->mPosition;
3278 case Dali::Actor::Property::ORIENTATION:
3279 property = &mNode->mOrientation;
3282 case Dali::Actor::Property::SCALE:
3283 property = &mNode->mScale;
3286 case Dali::Actor::Property::SCALE_X:
3287 property = &mNode->mScale;
3290 case Dali::Actor::Property::SCALE_Y:
3291 property = &mNode->mScale;
3294 case Dali::Actor::Property::SCALE_Z:
3295 property = &mNode->mScale;
3298 case Dali::Actor::Property::VISIBLE:
3299 property = &mNode->mVisible;
3302 case Dali::Actor::Property::COLOR:
3303 property = &mNode->mColor;
3306 case Dali::Actor::Property::COLOR_RED:
3307 property = &mNode->mColor;
3310 case Dali::Actor::Property::COLOR_GREEN:
3311 property = &mNode->mColor;
3314 case Dali::Actor::Property::COLOR_BLUE:
3315 property = &mNode->mColor;
3318 case Dali::Actor::Property::COLOR_ALPHA:
3319 property = &mNode->mColor;
3330 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3332 const PropertyInputImpl* property( NULL );
3334 // This method should only return a property of an object connected to the scene-graph
3340 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3342 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3343 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3345 property = animatable->GetSceneGraphProperty();
3347 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3348 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3350 CustomPropertyMetadata* custom = FindCustomProperty( index );
3351 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3352 property = custom->GetSceneGraphProperty();
3354 else if( NULL != mNode )
3358 case Dali::Actor::Property::PARENT_ORIGIN:
3359 property = &mNode->mParentOrigin;
3362 case Dali::Actor::Property::PARENT_ORIGIN_X:
3363 property = &mNode->mParentOrigin;
3366 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3367 property = &mNode->mParentOrigin;
3370 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3371 property = &mNode->mParentOrigin;
3374 case Dali::Actor::Property::ANCHOR_POINT:
3375 property = &mNode->mAnchorPoint;
3378 case Dali::Actor::Property::ANCHOR_POINT_X:
3379 property = &mNode->mAnchorPoint;
3382 case Dali::Actor::Property::ANCHOR_POINT_Y:
3383 property = &mNode->mAnchorPoint;
3386 case Dali::Actor::Property::ANCHOR_POINT_Z:
3387 property = &mNode->mAnchorPoint;
3390 case Dali::Actor::Property::SIZE:
3391 property = &mNode->mSize;
3394 case Dali::Actor::Property::SIZE_WIDTH:
3395 property = &mNode->mSize;
3398 case Dali::Actor::Property::SIZE_HEIGHT:
3399 property = &mNode->mSize;
3402 case Dali::Actor::Property::SIZE_DEPTH:
3403 property = &mNode->mSize;
3406 case Dali::Actor::Property::POSITION:
3407 property = &mNode->mPosition;
3410 case Dali::Actor::Property::POSITION_X:
3411 property = &mNode->mPosition;
3414 case Dali::Actor::Property::POSITION_Y:
3415 property = &mNode->mPosition;
3418 case Dali::Actor::Property::POSITION_Z:
3419 property = &mNode->mPosition;
3422 case Dali::Actor::Property::WORLD_POSITION:
3423 property = &mNode->mWorldPosition;
3426 case Dali::Actor::Property::WORLD_POSITION_X:
3427 property = &mNode->mWorldPosition;
3430 case Dali::Actor::Property::WORLD_POSITION_Y:
3431 property = &mNode->mWorldPosition;
3434 case Dali::Actor::Property::WORLD_POSITION_Z:
3435 property = &mNode->mWorldPosition;
3438 case Dali::Actor::Property::ORIENTATION:
3439 property = &mNode->mOrientation;
3442 case Dali::Actor::Property::WORLD_ORIENTATION:
3443 property = &mNode->mWorldOrientation;
3446 case Dali::Actor::Property::SCALE:
3447 property = &mNode->mScale;
3450 case Dali::Actor::Property::SCALE_X:
3451 property = &mNode->mScale;
3454 case Dali::Actor::Property::SCALE_Y:
3455 property = &mNode->mScale;
3458 case Dali::Actor::Property::SCALE_Z:
3459 property = &mNode->mScale;
3462 case Dali::Actor::Property::WORLD_SCALE:
3463 property = &mNode->mWorldScale;
3466 case Dali::Actor::Property::VISIBLE:
3467 property = &mNode->mVisible;
3470 case Dali::Actor::Property::COLOR:
3471 property = &mNode->mColor;
3474 case Dali::Actor::Property::COLOR_RED:
3475 property = &mNode->mColor;
3478 case Dali::Actor::Property::COLOR_GREEN:
3479 property = &mNode->mColor;
3482 case Dali::Actor::Property::COLOR_BLUE:
3483 property = &mNode->mColor;
3486 case Dali::Actor::Property::COLOR_ALPHA:
3487 property = &mNode->mColor;
3490 case Dali::Actor::Property::WORLD_COLOR:
3491 property = &mNode->mWorldColor;
3494 case Dali::Actor::Property::WORLD_MATRIX:
3495 property = &mNode->mWorldMatrix;
3506 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3508 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3510 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3512 // check whether the animatable property is registered already, if not then register one.
3513 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3514 if( animatableProperty )
3516 componentIndex = animatableProperty->componentIndex;
3523 case Dali::Actor::Property::PARENT_ORIGIN_X:
3524 case Dali::Actor::Property::ANCHOR_POINT_X:
3525 case Dali::Actor::Property::SIZE_WIDTH:
3526 case Dali::Actor::Property::POSITION_X:
3527 case Dali::Actor::Property::WORLD_POSITION_X:
3528 case Dali::Actor::Property::SCALE_X:
3529 case Dali::Actor::Property::COLOR_RED:
3535 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3536 case Dali::Actor::Property::ANCHOR_POINT_Y:
3537 case Dali::Actor::Property::SIZE_HEIGHT:
3538 case Dali::Actor::Property::POSITION_Y:
3539 case Dali::Actor::Property::WORLD_POSITION_Y:
3540 case Dali::Actor::Property::SCALE_Y:
3541 case Dali::Actor::Property::COLOR_GREEN:
3547 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3548 case Dali::Actor::Property::ANCHOR_POINT_Z:
3549 case Dali::Actor::Property::SIZE_DEPTH:
3550 case Dali::Actor::Property::POSITION_Z:
3551 case Dali::Actor::Property::WORLD_POSITION_Z:
3552 case Dali::Actor::Property::SCALE_Z:
3553 case Dali::Actor::Property::COLOR_BLUE:
3559 case Dali::Actor::Property::COLOR_ALPHA:
3573 return componentIndex;
3576 void Actor::SetParent( Actor* parent )
3580 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3584 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3587 // Instruct each actor to create a corresponding node in the scene graph
3588 ConnectToStage( parent->GetHierarchyDepth() );
3591 // Resolve the name and index for the child properties if any
3592 ResolveChildProperties();
3594 else // parent being set to NULL
3596 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3600 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3603 DALI_ASSERT_ALWAYS( mNode != NULL );
3607 // Disconnect the Node & its children from the scene-graph.
3608 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3611 // Instruct each actor to discard pointers to the scene-graph
3612 DisconnectFromStage();
3617 SceneGraph::Node* Actor::CreateNode() const
3622 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3625 Actor* actor = dynamic_cast< Actor* >( object );
3629 if( 0 == actionName.compare( ACTION_SHOW ) )
3631 actor->SetVisible( true );
3634 else if( 0 == actionName.compare( ACTION_HIDE ) )
3636 actor->SetVisible( false );
3644 void Actor::EnsureRelayoutData()
3646 // Assign relayout data.
3647 if( !mRelayoutData )
3649 mRelayoutData = new RelayoutData();
3653 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3655 // Check if actor is dependent on parent
3656 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3658 if( ( dimension & ( 1 << i ) ) )
3660 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3661 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3671 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3673 // Check if actor is dependent on children
3674 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3676 if( ( dimension & ( 1 << i ) ) )
3678 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3679 switch( resizePolicy )
3681 case ResizePolicy::FIT_TO_CHILDREN:
3682 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3698 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3700 return Actor::RelayoutDependentOnChildren( dimension );
3703 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3705 // Check each possible dimension and see if it is dependent on the input one
3706 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3708 if( dimension & ( 1 << i ) )
3710 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3717 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3719 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3721 if( dimension & ( 1 << i ) )
3723 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3728 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3730 // If more than one dimension is requested, just return the first one found
3731 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3733 if( ( dimension & ( 1 << i ) ) )
3735 return mRelayoutData->negotiatedDimensions[ i ];
3739 return 0.0f; // Default
3742 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3744 EnsureRelayoutData();
3746 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3748 if( dimension & ( 1 << i ) )
3750 mRelayoutData->dimensionPadding[ i ] = padding;
3755 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3757 if ( mRelayoutData )
3759 // If more than one dimension is requested, just return the first one found
3760 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3762 if( ( dimension & ( 1 << i ) ) )
3764 return mRelayoutData->dimensionPadding[ i ];
3769 return GetDefaultDimensionPadding();
3772 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3774 EnsureRelayoutData();
3776 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3778 if( dimension & ( 1 << i ) )
3780 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3785 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3787 if ( mRelayoutData )
3789 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3791 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3801 float Actor::GetHeightForWidthBase( float width )
3803 float height = 0.0f;
3805 const Vector3 naturalSize = GetNaturalSize();
3806 if( naturalSize.width > 0.0f )
3808 height = naturalSize.height * width / naturalSize.width;
3810 else // we treat 0 as 1:1 aspect ratio
3818 float Actor::GetWidthForHeightBase( float height )
3822 const Vector3 naturalSize = GetNaturalSize();
3823 if( naturalSize.height > 0.0f )
3825 width = naturalSize.width * height / naturalSize.height;
3827 else // we treat 0 as 1:1 aspect ratio
3835 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3837 // Fill to parent, taking size mode factor into account
3838 switch( child.GetResizePolicy( dimension ) )
3840 case ResizePolicy::FILL_TO_PARENT:
3842 return GetLatestSize( dimension );
3845 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3847 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3850 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3852 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3857 return GetLatestSize( dimension );
3862 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3864 // Can be overridden in derived class
3865 return CalculateChildSizeBase( child, dimension );
3868 float Actor::GetHeightForWidth( float width )
3870 // Can be overridden in derived class
3871 return GetHeightForWidthBase( width );
3874 float Actor::GetWidthForHeight( float height )
3876 // Can be overridden in derived class
3877 return GetWidthForHeightBase( height );
3880 float Actor::GetLatestSize( Dimension::Type dimension ) const
3882 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3885 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3887 Vector2 padding = GetPadding( dimension );
3889 return GetLatestSize( dimension ) + padding.x + padding.y;
3892 float Actor::NegotiateFromParent( Dimension::Type dimension )
3894 Actor* parent = GetParent();
3897 Vector2 padding( GetPadding( dimension ) );
3898 Vector2 parentPadding( parent->GetPadding( dimension ) );
3899 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3905 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3907 float maxDimensionPoint = 0.0f;
3909 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3911 ActorPtr child = GetChildAt( i );
3913 if( !child->RelayoutDependentOnParent( dimension ) )
3915 // Calculate the min and max points that the children range across
3916 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3917 float dimensionSize = child->GetRelayoutSize( dimension );
3918 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3922 return maxDimensionPoint;
3925 float Actor::GetSize( Dimension::Type dimension ) const
3927 return GetDimensionValue( GetTargetSize(), dimension );
3930 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3932 return GetDimensionValue( GetNaturalSize(), dimension );
3935 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3937 switch( GetResizePolicy( dimension ) )
3939 case ResizePolicy::USE_NATURAL_SIZE:
3941 return GetNaturalSize( dimension );
3944 case ResizePolicy::FIXED:
3946 return GetDimensionValue( GetPreferredSize(), dimension );
3949 case ResizePolicy::USE_ASSIGNED_SIZE:
3951 return GetDimensionValue( maximumSize, dimension );
3954 case ResizePolicy::FILL_TO_PARENT:
3955 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3956 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3958 return NegotiateFromParent( dimension );
3961 case ResizePolicy::FIT_TO_CHILDREN:
3963 return NegotiateFromChildren( dimension );
3966 case ResizePolicy::DIMENSION_DEPENDENCY:
3968 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3971 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3973 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3976 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3978 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3990 return 0.0f; // Default
3993 float Actor::ClampDimension( float size, Dimension::Type dimension )
3995 const float minSize = GetMinimumSize( dimension );
3996 const float maxSize = GetMaximumSize( dimension );
3998 return std::max( minSize, std::min( size, maxSize ) );
4001 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4003 // Check if it needs to be negotiated
4004 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4006 // Check that we havn't gotten into an infinite loop
4007 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4008 bool recursionFound = false;
4009 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4011 if( *it == searchActor )
4013 recursionFound = true;
4018 if( !recursionFound )
4020 // Record the path that we have taken
4021 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4023 // Dimension dependency check
4024 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4026 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4028 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4030 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4034 // Parent dependency check
4035 Actor* parent = GetParent();
4036 if( parent && RelayoutDependentOnParent( dimension ) )
4038 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4041 // Children dependency check
4042 if( RelayoutDependentOnChildren( dimension ) )
4044 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4046 ActorPtr child = GetChildAt( i );
4048 // Only relayout child first if it is not dependent on this actor
4049 if( !child->RelayoutDependentOnParent( dimension ) )
4051 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4056 // For deriving classes
4057 OnCalculateRelayoutSize( dimension );
4059 // All dependencies checked, calculate the size and set negotiated flag
4060 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4062 SetNegotiatedDimension( newSize, dimension );
4063 SetLayoutNegotiated( true, dimension );
4065 // For deriving classes
4066 OnLayoutNegotiated( newSize, dimension );
4068 // This actor has been successfully processed, pop it off the recursion stack
4069 recursionStack.pop_back();
4073 // TODO: Break infinite loop
4074 SetLayoutNegotiated( true, dimension );
4079 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4081 // Negotiate all dimensions that require it
4082 ActorDimensionStack recursionStack;
4084 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4086 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4089 NegotiateDimension( dimension, allocatedSize, recursionStack );
4093 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4095 switch( mRelayoutData->sizeSetPolicy )
4097 case SizeScalePolicy::USE_SIZE_SET:
4102 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4104 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4105 const Vector3 naturalSize = GetNaturalSize();
4106 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4108 const float sizeRatio = size.width / size.height;
4109 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4111 if( naturalSizeRatio < sizeRatio )
4113 return Vector2( naturalSizeRatio * size.height, size.height );
4115 else if( naturalSizeRatio > sizeRatio )
4117 return Vector2( size.width, size.width / naturalSizeRatio );
4128 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4130 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4131 const Vector3 naturalSize = GetNaturalSize();
4132 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4134 const float sizeRatio = size.width / size.height;
4135 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4137 if( naturalSizeRatio < sizeRatio )
4139 return Vector2( size.width, size.width / naturalSizeRatio );
4141 else if( naturalSizeRatio > sizeRatio )
4143 return Vector2( naturalSizeRatio * size.height, size.height );
4162 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4164 // Do the set actor size
4165 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4167 // Adjust for size set policy
4168 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4170 // Lock the flag to stop recursive relayouts on set size
4171 mRelayoutData->insideRelayout = true;
4172 SetSize( negotiatedSize );
4173 mRelayoutData->insideRelayout = false;
4175 // Clear flags for all dimensions
4176 SetLayoutDirty( false );
4178 // Give deriving classes a chance to respond
4179 OnRelayout( negotiatedSize, container );
4181 if( !mOnRelayoutSignal.Empty() )
4183 Dali::Actor handle( this );
4184 mOnRelayoutSignal.Emit( handle );
4188 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4190 // Force a size negotiation for actors that has assigned size during relayout
4191 // This is required as otherwise the flags that force a relayout will not
4192 // necessarilly be set. This will occur if the actor has already been laid out.
4193 // The dirty flags are then cleared. Then if the actor is added back into the
4194 // relayout container afterwards, the dirty flags would still be clear...
4195 // causing a relayout to be skipped. Here we force any actors added to the
4196 // container to be relayed out.
4197 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4199 SetLayoutNegotiated(false, Dimension::WIDTH);
4201 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4203 SetLayoutNegotiated(false, Dimension::HEIGHT);
4206 // Do the negotiation
4207 NegotiateDimensions( allocatedSize );
4209 // Set the actor size
4210 SetNegotiatedSize( container );
4212 // Negotiate down to children
4213 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4215 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4217 ActorPtr child = GetChildAt( i );
4219 // Forces children that have already been laid out to be relayed out
4220 // if they have assigned size during relayout.
4221 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4223 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4224 child->SetLayoutDirty(true, Dimension::WIDTH);
4226 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4228 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4229 child->SetLayoutDirty(true, Dimension::HEIGHT);
4232 // Only relayout if required
4233 if( child->RelayoutRequired() )
4235 container.Add( Dali::Actor( child.Get() ), newBounds );
4240 void Actor::RelayoutRequest( Dimension::Type dimension )
4242 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4243 if( relayoutController )
4245 Dali::Actor self( this );
4246 relayoutController->RequestRelayout( self, dimension );
4250 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4254 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4258 void Actor::SetPreferredSize( const Vector2& size )
4260 EnsureRelayoutData();
4262 if( size.width > 0.0f )
4264 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4267 if( size.height > 0.0f )
4269 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4272 mRelayoutData->preferredSize = size;
4277 Vector2 Actor::GetPreferredSize() const
4279 if ( mRelayoutData )
4281 return Vector2( mRelayoutData->preferredSize );
4284 return GetDefaultPreferredSize();
4287 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4289 EnsureRelayoutData();
4291 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4293 if( dimension & ( 1 << i ) )
4295 mRelayoutData->minimumSize[ i ] = size;
4302 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4304 if ( mRelayoutData )
4306 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4308 if( dimension & ( 1 << i ) )
4310 return mRelayoutData->minimumSize[ i ];
4315 return 0.0f; // Default
4318 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4320 EnsureRelayoutData();
4322 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4324 if( dimension & ( 1 << i ) )
4326 mRelayoutData->maximumSize[ i ] = size;
4333 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4335 if ( mRelayoutData )
4337 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4339 if( dimension & ( 1 << i ) )
4341 return mRelayoutData->maximumSize[ i ];
4346 return FLT_MAX; // Default
4349 Object* Actor::GetParentObject() const
4354 } // namespace Internal