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/actors/actor-devel.h>
35 #include <dali/devel-api/scripting/scripting.h>
36 #include <dali/internal/common/internal-constants.h>
37 #include <dali/internal/event/common/event-thread-services.h>
38 #include <dali/internal/event/render-tasks/render-task-impl.h>
39 #include <dali/internal/event/actors/camera-actor-impl.h>
40 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
41 #include <dali/internal/event/common/property-helper.h>
42 #include <dali/internal/event/common/stage-impl.h>
43 #include <dali/internal/event/common/type-info-impl.h>
44 #include <dali/internal/event/animation/constraint-impl.h>
45 #include <dali/internal/event/common/projection.h>
46 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
47 #include <dali/internal/update/common/animatable-property.h>
48 #include <dali/internal/update/nodes/node-messages.h>
49 #include <dali/internal/update/nodes/node-declarations.h>
50 #include <dali/internal/update/animation/scene-graph-constraint.h>
51 #include <dali/internal/event/events/actor-gesture-data.h>
52 #include <dali/internal/common/message.h>
53 #include <dali/integration-api/debug.h>
55 using Dali::Internal::SceneGraph::Node;
56 using Dali::Internal::SceneGraph::AnimatableProperty;
57 using Dali::Internal::SceneGraph::PropertyBase;
65 unsigned int Actor::mActorCounter = 0;
69 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
70 inline const Vector3& GetDefaultSizeModeFactor()
75 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
76 inline const Vector2& GetDefaultPreferredSize()
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultDimensionPadding()
87 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
89 } // unnamed namespace
92 * Struct to collect relayout variables
94 struct Actor::RelayoutData
97 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
99 // Set size negotiation defaults
100 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
102 resizePolicies[ i ] = ResizePolicy::DEFAULT;
103 negotiatedDimensions[ i ] = 0.0f;
104 dimensionNegotiated[ i ] = false;
105 dimensionDirty[ i ] = false;
106 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
107 dimensionPadding[ i ] = GetDefaultDimensionPadding();
108 minimumSize[ i ] = 0.0f;
109 maximumSize[ i ] = FLT_MAX;
113 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
115 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
117 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
119 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
121 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
122 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
124 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
125 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
127 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
129 Vector2 preferredSize; ///< The preferred size of the actor
131 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
133 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
134 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
137 namespace // unnamed namespace
143 * We want to discourage the use of property strings (minimize string comparisons),
144 * particularly for the default properties.
145 * Name Type writable animatable constraint-input enum for index-checking
147 DALI_PROPERTY_TABLE_BEGIN
148 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
149 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
150 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
151 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
152 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
153 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
154 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
155 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
156 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
157 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
158 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
159 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
160 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
161 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
162 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
163 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
164 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
165 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
166 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
167 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
168 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
169 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
170 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
171 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
172 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
173 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
174 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
175 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
176 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
177 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
178 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
179 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
180 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
181 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
182 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
183 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
184 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
185 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
186 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
187 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
188 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
189 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
190 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
191 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
192 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
193 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
194 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
195 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
196 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
197 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
198 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
199 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
200 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
201 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
202 DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::DevelActor::Property::BATCH_PARENT )
203 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
207 const char* const SIGNAL_TOUCHED = "touched";
208 const char* const SIGNAL_HOVERED = "hovered";
209 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
210 const char* const SIGNAL_ON_STAGE = "onStage";
211 const char* const SIGNAL_OFF_STAGE = "offStage";
212 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
213 const char* const SIGNAL_TOUCH = "touch";
217 const char* const ACTION_SHOW = "show";
218 const char* const ACTION_HIDE = "hide";
220 BaseHandle CreateActor()
222 return Dali::Actor::New();
225 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
227 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
228 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
229 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
232 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
233 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
235 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
236 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
241 const Vector3& value;
244 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
245 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
246 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
252 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
253 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
254 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
256 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
257 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
258 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
259 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
260 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
261 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
263 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
264 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
265 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
266 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
267 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
268 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
270 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
274 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
276 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
285 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
287 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
288 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
289 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
291 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
293 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
296 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
299 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
301 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
303 size_t sizeIgnored = 0;
304 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
306 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
313 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
315 // Values are the same so just use the same table as anchor-point
316 return GetAnchorPointConstant( value, parentOrigin );
320 * @brief Extract a given dimension from a Vector2
322 * @param[in] values The values to extract from
323 * @param[in] dimension The dimension to extract
324 * @return Return the value for the dimension
326 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
330 case Dimension::WIDTH:
334 case Dimension::HEIGHT:
336 return values.height;
347 * @brief Extract a given dimension from a Vector3
349 * @param[in] values The values to extract from
350 * @param[in] dimension The dimension to extract
351 * @return Return the value for the dimension
353 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
355 return GetDimensionValue( values.GetVectorXY(), dimension );
359 } // unnamed namespace
361 ActorPtr Actor::New()
363 ActorPtr actor( new Actor( BASIC ) );
365 // Second-phase construction
371 const std::string& Actor::GetName() const
376 void Actor::SetName( const std::string& name )
382 // ATTENTION: string for debug purposes is not thread safe.
383 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
387 unsigned int Actor::GetId() const
392 bool Actor::OnStage() const
397 Dali::Layer Actor::GetLayer()
401 // Short-circuit for Layer derived actors
404 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
407 // Find the immediate Layer parent
408 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
410 if( parent->IsLayer() )
412 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
419 void Actor::Add( Actor& child )
421 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
422 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
426 mChildren = new ActorContainer;
429 Actor* const oldParent( child.mParent );
431 // child might already be ours
432 if( this != oldParent )
434 // if we already have parent, unparent us first
437 oldParent->Remove( child ); // This causes OnChildRemove callback
439 // Old parent may need to readjust to missing child
440 if( oldParent->RelayoutDependentOnChildren() )
442 oldParent->RelayoutRequest();
446 // Guard against Add() during previous OnChildRemove callback
449 // Do this first, since user callbacks from within SetParent() may need to remove child
450 mChildren->push_back( ActorPtr( &child ) );
452 // SetParent asserts that child can be added
453 child.SetParent( this );
455 // Notification for derived classes
458 // Only put in a relayout request if there is a suitable dependency
459 if( RelayoutDependentOnChildren() )
467 void Actor::Remove( Actor& child )
469 if( (this == &child) || (!mChildren) )
471 // no children or removing itself
477 // Find the child in mChildren, and unparent it
478 ActorIter end = mChildren->end();
479 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
481 ActorPtr actor = (*iter);
483 if( actor.Get() == &child )
485 // Keep handle for OnChildRemove notification
488 // Do this first, since user callbacks from within SetParent() may need to add the child
489 mChildren->erase( iter );
491 DALI_ASSERT_DEBUG( actor->GetParent() == this );
492 actor->SetParent( NULL );
500 // Only put in a relayout request if there is a suitable dependency
501 if( RelayoutDependentOnChildren() )
507 // Notification for derived classes
508 OnChildRemove( child );
511 void Actor::Unparent()
515 // Remove this actor from the parent. The remove will put a relayout request in for
516 // the parent if required
517 mParent->Remove( *this );
518 // mParent is now NULL!
522 unsigned int Actor::GetChildCount() const
524 return ( NULL != mChildren ) ? mChildren->size() : 0;
527 ActorPtr Actor::GetChildAt( unsigned int index ) const
529 DALI_ASSERT_ALWAYS( index < GetChildCount() );
531 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
534 ActorPtr Actor::FindChildByName( const std::string& actorName )
537 if( actorName == mName )
543 ActorIter end = mChildren->end();
544 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
546 child = (*iter)->FindChildByName( actorName );
557 ActorPtr Actor::FindChildById( const unsigned int id )
566 ActorIter end = mChildren->end();
567 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
569 child = (*iter)->FindChildById( id );
580 void Actor::SetParentOrigin( const Vector3& origin )
584 // mNode is being used in a separate thread; queue a message to set the value & base value
585 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
588 // Cache for event-thread access
591 // not allocated, check if different from default
592 if( ParentOrigin::DEFAULT != origin )
594 mParentOrigin = new Vector3( origin );
599 // check if different from current costs more than just set
600 *mParentOrigin = origin;
604 void Actor::SetParentOriginX( float x )
606 const Vector3& current = GetCurrentParentOrigin();
608 SetParentOrigin( Vector3( x, current.y, current.z ) );
611 void Actor::SetParentOriginY( float y )
613 const Vector3& current = GetCurrentParentOrigin();
615 SetParentOrigin( Vector3( current.x, y, current.z ) );
618 void Actor::SetParentOriginZ( float z )
620 const Vector3& current = GetCurrentParentOrigin();
622 SetParentOrigin( Vector3( current.x, current.y, z ) );
625 const Vector3& Actor::GetCurrentParentOrigin() const
627 // Cached for event-thread access
628 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
631 void Actor::SetAnchorPoint( const Vector3& anchor )
635 // mNode is being used in a separate thread; queue a message to set the value & base value
636 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
639 // Cache for event-thread access
642 // not allocated, check if different from default
643 if( AnchorPoint::DEFAULT != anchor )
645 mAnchorPoint = new Vector3( anchor );
650 // check if different from current costs more than just set
651 *mAnchorPoint = anchor;
655 void Actor::SetAnchorPointX( float x )
657 const Vector3& current = GetCurrentAnchorPoint();
659 SetAnchorPoint( Vector3( x, current.y, current.z ) );
662 void Actor::SetAnchorPointY( float y )
664 const Vector3& current = GetCurrentAnchorPoint();
666 SetAnchorPoint( Vector3( current.x, y, current.z ) );
669 void Actor::SetAnchorPointZ( float z )
671 const Vector3& current = GetCurrentAnchorPoint();
673 SetAnchorPoint( Vector3( current.x, current.y, z ) );
676 const Vector3& Actor::GetCurrentAnchorPoint() const
678 // Cached for event-thread access
679 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
682 void Actor::SetPosition( float x, float y )
684 SetPosition( Vector3( x, y, 0.0f ) );
687 void Actor::SetPosition( float x, float y, float z )
689 SetPosition( Vector3( x, y, z ) );
692 void Actor::SetPosition( const Vector3& position )
694 mTargetPosition = position;
698 // mNode is being used in a separate thread; queue a message to set the value & base value
699 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
703 void Actor::SetX( float x )
705 mTargetPosition.x = x;
709 // mNode is being used in a separate thread; queue a message to set the value & base value
710 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
714 void Actor::SetY( float y )
716 mTargetPosition.y = y;
720 // mNode is being used in a separate thread; queue a message to set the value & base value
721 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
725 void Actor::SetZ( float z )
727 mTargetPosition.z = z;
731 // mNode is being used in a separate thread; queue a message to set the value & base value
732 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
736 void Actor::TranslateBy( const Vector3& distance )
738 mTargetPosition += distance;
742 // mNode is being used in a separate thread; queue a message to set the value & base value
743 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
747 const Vector3& Actor::GetCurrentPosition() const
751 // mNode is being used in a separate thread; copy the value from the previous update
752 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
755 return Vector3::ZERO;
758 const Vector3& Actor::GetTargetPosition() const
760 return mTargetPosition;
763 const Vector3& Actor::GetCurrentWorldPosition() const
767 // mNode is being used in a separate thread; copy the value from the previous update
768 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
771 return Vector3::ZERO;
774 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
776 // this flag is not animatable so keep the value
777 mPositionInheritanceMode = mode;
780 // mNode is being used in a separate thread; queue a message to set the value
781 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
785 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
787 // Cached for event-thread access
788 return mPositionInheritanceMode;
791 void Actor::SetInheritPosition( bool inherit )
793 if( mInheritPosition != inherit && NULL != mNode )
795 // non animateable so keep local copy
796 mInheritPosition = inherit;
797 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
801 bool Actor::IsPositionInherited() const
803 return mInheritPosition;
806 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
808 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
809 normalizedAxis.Normalize();
811 Quaternion orientation( angle, normalizedAxis );
813 SetOrientation( orientation );
816 void Actor::SetOrientation( const Quaternion& orientation )
820 // mNode is being used in a separate thread; queue a message to set the value & base value
821 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
825 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
829 // mNode is being used in a separate thread; queue a message to set the value & base value
830 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
834 void Actor::RotateBy( const Quaternion& relativeRotation )
838 // mNode is being used in a separate thread; queue a message to set the value & base value
839 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
843 const Quaternion& Actor::GetCurrentOrientation() const
847 // mNode is being used in a separate thread; copy the value from the previous update
848 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
851 return Quaternion::IDENTITY;
854 const Quaternion& Actor::GetCurrentWorldOrientation() const
858 // mNode is being used in a separate thread; copy the value from the previous update
859 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
862 return Quaternion::IDENTITY;
865 void Actor::SetScale( float scale )
867 SetScale( Vector3( scale, scale, scale ) );
870 void Actor::SetScale( float x, float y, float z )
872 SetScale( Vector3( x, y, z ) );
875 void Actor::SetScale( const Vector3& scale )
879 // mNode is being used in a separate thread; queue a message to set the value & base value
880 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
884 void Actor::SetScaleX( float x )
888 // mNode is being used in a separate thread; queue a message to set the value & base value
889 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
893 void Actor::SetScaleY( float y )
897 // mNode is being used in a separate thread; queue a message to set the value & base value
898 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
902 void Actor::SetScaleZ( float z )
906 // mNode is being used in a separate thread; queue a message to set the value & base value
907 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
911 void Actor::ScaleBy(const Vector3& relativeScale)
915 // mNode is being used in a separate thread; queue a message to set the value & base value
916 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
920 const Vector3& Actor::GetCurrentScale() const
924 // mNode is being used in a separate thread; copy the value from the previous update
925 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
931 const Vector3& Actor::GetCurrentWorldScale() const
935 // mNode is being used in a separate thread; copy the value from the previous update
936 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
942 void Actor::SetInheritScale( bool inherit )
945 if( mInheritScale != inherit && NULL != mNode )
947 // non animateable so keep local copy
948 mInheritScale = inherit;
949 // mNode is being used in a separate thread; queue a message to set the value
950 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
954 bool Actor::IsScaleInherited() const
956 return mInheritScale;
959 Matrix Actor::GetCurrentWorldMatrix() const
963 return mNode->GetWorldMatrix(0);
966 return Matrix::IDENTITY;
969 void Actor::SetVisible( bool visible )
973 // mNode is being used in a separate thread; queue a message to set the value & base value
974 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
978 bool Actor::IsVisible() const
982 // mNode is being used in a separate thread; copy the value from the previous update
983 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
989 void Actor::SetOpacity( float opacity )
993 // mNode is being used in a separate thread; queue a message to set the value & base value
994 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
998 float Actor::GetCurrentOpacity() const
1002 // mNode is being used in a separate thread; copy the value from the previous update
1003 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1009 ClippingMode::Type Actor::GetClippingMode() const
1011 return mClippingMode;
1014 const Vector4& Actor::GetCurrentWorldColor() const
1018 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1021 return Color::WHITE;
1024 void Actor::SetColor( const Vector4& color )
1028 // mNode is being used in a separate thread; queue a message to set the value & base value
1029 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1033 void Actor::SetColorRed( float red )
1037 // mNode is being used in a separate thread; queue a message to set the value & base value
1038 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1042 void Actor::SetColorGreen( float green )
1046 // mNode is being used in a separate thread; queue a message to set the value & base value
1047 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1051 void Actor::SetColorBlue( float blue )
1055 // mNode is being used in a separate thread; queue a message to set the value & base value
1056 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1060 const Vector4& Actor::GetCurrentColor() const
1064 // mNode is being used in a separate thread; copy the value from the previous update
1065 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1068 return Color::WHITE;
1071 void Actor::SetInheritOrientation( bool inherit )
1073 if( mInheritOrientation != inherit && NULL != mNode)
1075 // non animateable so keep local copy
1076 mInheritOrientation = inherit;
1077 // mNode is being used in a separate thread; queue a message to set the value
1078 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1082 bool Actor::IsOrientationInherited() const
1084 return mInheritOrientation;
1087 void Actor::SetSizeModeFactor( const Vector3& factor )
1089 EnsureRelayoutData();
1091 mRelayoutData->sizeModeFactor = factor;
1094 const Vector3& Actor::GetSizeModeFactor() const
1096 if ( mRelayoutData )
1098 return mRelayoutData->sizeModeFactor;
1101 return GetDefaultSizeModeFactor();
1104 void Actor::SetColorMode( ColorMode colorMode )
1106 // non animateable so keep local copy
1107 mColorMode = colorMode;
1110 // mNode is being used in a separate thread; queue a message to set the value
1111 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1115 ColorMode Actor::GetColorMode() const
1117 // we have cached copy
1121 void Actor::SetSize( float width, float height )
1123 SetSize( Vector2( width, height ) );
1126 void Actor::SetSize( float width, float height, float depth )
1128 SetSize( Vector3( width, height, depth ) );
1131 void Actor::SetSize( const Vector2& size )
1133 SetSize( Vector3( size.width, size.height, 0.f ) );
1136 void Actor::SetSizeInternal( const Vector2& size )
1138 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1141 void Actor::SetSize( const Vector3& size )
1143 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1145 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1146 SetPreferredSize( size.GetVectorXY() );
1150 SetSizeInternal( size );
1154 void Actor::SetSizeInternal( const Vector3& size )
1156 // dont allow recursive loop
1157 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1158 // 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
1159 if( ( NULL != mNode )&&
1160 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1161 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1162 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1166 // mNode is being used in a separate thread; queue a message to set the value & base value
1167 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1169 // Notification for derived classes
1170 mInsideOnSizeSet = true;
1171 OnSizeSet( mTargetSize );
1172 mInsideOnSizeSet = false;
1174 // Raise a relayout request if the flag is not locked
1175 if( mRelayoutData && !mRelayoutData->insideRelayout )
1182 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1184 mTargetSize = targetSize;
1186 // Notify deriving classes
1187 OnSizeAnimation( animation, mTargetSize );
1190 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1192 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1194 mTargetSize.width = targetSize;
1196 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1198 mTargetSize.height = targetSize;
1200 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1202 mTargetSize.depth = targetSize;
1204 // Notify deriving classes
1205 OnSizeAnimation( animation, mTargetSize );
1208 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1210 mTargetPosition = targetPosition;
1213 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1215 if ( Dali::Actor::Property::POSITION_X == property )
1217 mTargetPosition.x = targetPosition;
1219 else if ( Dali::Actor::Property::POSITION_Y == property )
1221 mTargetPosition.y = targetPosition;
1223 else if ( Dali::Actor::Property::POSITION_Z == property )
1225 mTargetPosition.z = targetPosition;
1229 void Actor::SetWidth( float width )
1231 mTargetSize.width = width;
1235 // mNode is being used in a separate thread; queue a message to set the value & base value
1236 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1240 void Actor::SetHeight( float height )
1242 mTargetSize.height = height;
1246 // mNode is being used in a separate thread; queue a message to set the value & base value
1247 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1251 void Actor::SetDepth( float depth )
1253 mTargetSize.depth = depth;
1257 // mNode is being used in a separate thread; queue a message to set the value & base value
1258 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1262 const Vector3& Actor::GetTargetSize() const
1267 const Vector3& Actor::GetCurrentSize() const
1271 // mNode is being used in a separate thread; copy the value from the previous update
1272 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1275 return Vector3::ZERO;
1278 Vector3 Actor::GetNaturalSize() const
1280 // It is up to deriving classes to return the appropriate natural size
1281 return Vector3( 0.0f, 0.0f, 0.0f );
1284 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1286 EnsureRelayoutData();
1288 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1290 if( dimension & ( 1 << i ) )
1292 mRelayoutData->resizePolicies[ i ] = policy;
1296 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1298 if( dimension & Dimension::WIDTH )
1300 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1303 if( dimension & Dimension::HEIGHT )
1305 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1309 // If calling SetResizePolicy, assume we want relayout enabled
1310 SetRelayoutEnabled( true );
1312 OnSetResizePolicy( policy, dimension );
1314 // Trigger relayout on this control
1318 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1320 if ( mRelayoutData )
1322 // If more than one dimension is requested, just return the first one found
1323 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1325 if( ( dimension & ( 1 << i ) ) )
1327 return mRelayoutData->resizePolicies[ i ];
1332 return ResizePolicy::DEFAULT;
1335 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1337 EnsureRelayoutData();
1339 mRelayoutData->sizeSetPolicy = policy;
1342 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1344 if ( mRelayoutData )
1346 return mRelayoutData->sizeSetPolicy;
1349 return DEFAULT_SIZE_SCALE_POLICY;
1352 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1354 EnsureRelayoutData();
1356 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1358 if( dimension & ( 1 << i ) )
1360 mRelayoutData->dimensionDependencies[ i ] = dependency;
1365 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1367 if ( mRelayoutData )
1369 // If more than one dimension is requested, just return the first one found
1370 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1372 if( ( dimension & ( 1 << i ) ) )
1374 return mRelayoutData->dimensionDependencies[ i ];
1379 return Dimension::ALL_DIMENSIONS; // Default
1382 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1384 // If relayout data has not been allocated yet and the client is requesting
1385 // to disable it, do nothing
1386 if( mRelayoutData || relayoutEnabled )
1388 EnsureRelayoutData();
1390 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1392 mRelayoutData->relayoutEnabled = relayoutEnabled;
1396 bool Actor::IsRelayoutEnabled() const
1398 // Assume that if relayout data has not been allocated yet then
1399 // relayout is disabled
1400 return mRelayoutData && mRelayoutData->relayoutEnabled;
1403 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1405 EnsureRelayoutData();
1407 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1409 if( dimension & ( 1 << i ) )
1411 mRelayoutData->dimensionDirty[ i ] = dirty;
1416 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1418 if ( mRelayoutData )
1420 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1422 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1432 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1434 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1437 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1439 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1442 unsigned int Actor::AddRenderer( Renderer& renderer )
1446 mRenderers = new RendererContainer;
1449 unsigned int index = mRenderers->size();
1450 RendererPtr rendererPtr = RendererPtr( &renderer );
1451 mRenderers->push_back( rendererPtr );
1452 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1456 rendererPtr->Connect();
1462 unsigned int Actor::GetRendererCount() const
1464 unsigned int rendererCount(0);
1467 rendererCount = mRenderers->size();
1470 return rendererCount;
1473 RendererPtr Actor::GetRendererAt( unsigned int index )
1475 RendererPtr renderer;
1476 if( index < GetRendererCount() )
1478 renderer = ( *mRenderers )[ index ];
1484 void Actor::RemoveRenderer( Renderer& renderer )
1488 RendererIter end = mRenderers->end();
1489 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1491 if( (*iter).Get() == &renderer )
1493 mRenderers->erase( iter );
1494 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1501 void Actor::RemoveRenderer( unsigned int index )
1503 if( index < GetRendererCount() )
1505 RendererPtr renderer = ( *mRenderers )[ index ];
1506 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1507 mRenderers->erase( mRenderers->begin()+index );
1511 bool Actor::IsOverlay() const
1513 return ( DrawMode::OVERLAY_2D == mDrawMode );
1516 void Actor::SetDrawMode( DrawMode::Type drawMode )
1518 // this flag is not animatable so keep the value
1519 mDrawMode = drawMode;
1520 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1522 // mNode is being used in a separate thread; queue a message to set the value
1523 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1527 DrawMode::Type Actor::GetDrawMode() const
1532 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1534 // only valid when on-stage
1535 StagePtr stage = Stage::GetCurrent();
1536 if( stage && OnStage() )
1538 const RenderTaskList& taskList = stage->GetRenderTaskList();
1540 Vector2 converted( screenX, screenY );
1542 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1543 const int taskCount = taskList.GetTaskCount();
1544 for( int i = taskCount - 1; i >= 0; --i )
1546 Dali::RenderTask task = taskList.GetTask( i );
1547 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1549 // found a task where this conversion was ok so return
1557 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1559 bool retval = false;
1560 // only valid when on-stage
1563 CameraActor* camera = renderTask.GetCameraActor();
1567 renderTask.GetViewport( viewport );
1569 // need to translate coordinates to render tasks coordinate space
1570 Vector2 converted( screenX, screenY );
1571 if( renderTask.TranslateCoordinates( converted ) )
1573 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1580 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1582 // Early-out if mNode is NULL
1588 // Get the ModelView matrix
1590 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1592 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1593 Matrix invertedMvp( false/*don't init*/);
1594 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1595 bool success = invertedMvp.Invert();
1597 // Convert to GL coordinates
1598 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1603 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1610 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1616 if( XyPlaneIntersect( nearPos, farPos, local ) )
1618 Vector3 size = GetCurrentSize();
1619 localX = local.x + size.x * 0.5f;
1620 localY = local.y + size.y * 0.5f;
1631 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1634 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1636 Mathematical Formulation
1638 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1640 ( p - c ) dot ( p - c ) = r^2
1642 Given a ray with a point of origin 'o', and a direction vector 'd':
1644 ray(t) = o + td, t >= 0
1646 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1648 (o + td - c ) dot ( o + td - c ) = r^2
1650 To solve for t we first expand the above into a more recognisable quadratic equation form
1652 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1661 B = 2( o - c ) dot d
1662 C = ( o - c ) dot ( o - c ) - r^2
1664 which can be solved using a standard quadratic formula.
1666 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1668 Practical Simplification
1670 In a renderer, we often differentiate between world space and object space. In the object space
1671 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1672 into object space, the mathematical solution presented above can be simplified significantly.
1674 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1678 and we can find the t at which the (transformed) ray intersects the sphere by
1680 ( o + td ) dot ( o + td ) = r^2
1682 According to the reasoning above, we expand the above quadratic equation into the general form
1686 which now has coefficients:
1693 // Early out if mNode is NULL
1699 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1701 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1702 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1703 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1705 // Compute the radius is not needed, square radius it's enough.
1706 const Vector3& size( mNode->GetSize( bufferIndex ) );
1708 // Scale the sphere.
1709 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1711 const float width = size.width * scale.width;
1712 const float height = size.height * scale.height;
1714 float squareSphereRadius = 0.5f * ( width * width + height * height );
1716 float a = rayDir.Dot( rayDir ); // a
1717 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1718 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1720 return ( b2 * b2 - a * c ) >= 0.f;
1723 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1727 if( OnStage() && NULL != mNode )
1729 // Transforms the ray to the local reference system.
1730 // Calculate the inverse of Model matrix
1731 Matrix invModelMatrix( false/*don't init*/);
1733 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1734 invModelMatrix = mNode->GetWorldMatrix(0);
1735 invModelMatrix.Invert();
1737 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1738 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1740 // Test with the actor's XY plane (Normal = 0 0 1 1).
1742 float a = -rayOriginLocal.z;
1743 float b = rayDirLocal.z;
1745 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1747 // Ray travels distance * rayDirLocal to intersect with plane.
1750 const Vector3& size = mNode->GetSize( bufferIndex );
1752 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1753 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1755 // Test with the actor's geometry.
1756 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1763 void Actor::SetLeaveRequired( bool required )
1765 mLeaveRequired = required;
1768 bool Actor::GetLeaveRequired() const
1770 return mLeaveRequired;
1773 void Actor::SetKeyboardFocusable( bool focusable )
1775 mKeyboardFocusable = focusable;
1778 bool Actor::IsKeyboardFocusable() const
1780 return mKeyboardFocusable;
1783 bool Actor::GetTouchRequired() const
1785 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1788 bool Actor::GetHoverRequired() const
1790 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1793 bool Actor::GetWheelEventRequired() const
1795 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1798 bool Actor::IsHittable() const
1800 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1803 ActorGestureData& Actor::GetGestureData()
1805 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1806 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1807 if( NULL == mGestureData )
1809 mGestureData = new ActorGestureData;
1811 return *mGestureData;
1814 bool Actor::IsGestureRequred( Gesture::Type type ) const
1816 return mGestureData && mGestureData->IsGestureRequred( type );
1819 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1821 bool consumed = false;
1823 if( !mTouchSignal.Empty() )
1825 Dali::Actor handle( this );
1826 consumed = mTouchSignal.Emit( handle, touch );
1829 if( !mTouchedSignal.Empty() )
1831 Dali::Actor handle( this );
1832 consumed |= mTouchedSignal.Emit( handle, event );
1837 // Notification for derived classes
1838 consumed = OnTouchEvent( event ); // TODO
1844 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1846 bool consumed = false;
1848 if( !mHoveredSignal.Empty() )
1850 Dali::Actor handle( this );
1851 consumed = mHoveredSignal.Emit( handle, event );
1856 // Notification for derived classes
1857 consumed = OnHoverEvent( event );
1863 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1865 bool consumed = false;
1867 if( !mWheelEventSignal.Empty() )
1869 Dali::Actor handle( this );
1870 consumed = mWheelEventSignal.Emit( handle, event );
1875 // Notification for derived classes
1876 consumed = OnWheelEvent( event );
1882 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1884 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1885 return mTouchedSignal;
1888 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1890 return mTouchSignal;
1893 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1895 return mHoveredSignal;
1898 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1900 return mWheelEventSignal;
1903 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1905 return mOnStageSignal;
1908 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1910 return mOffStageSignal;
1913 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1915 return mOnRelayoutSignal;
1918 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1920 bool connected( true );
1921 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1923 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1925 actor->TouchedSignal().Connect( tracker, functor );
1927 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1929 actor->HoveredSignal().Connect( tracker, functor );
1931 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1933 actor->WheelEventSignal().Connect( tracker, functor );
1935 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1937 actor->OnStageSignal().Connect( tracker, functor );
1939 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1941 actor->OffStageSignal().Connect( tracker, functor );
1943 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1945 actor->OnRelayoutSignal().Connect( tracker, functor );
1947 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1949 actor->TouchSignal().Connect( tracker, functor );
1953 // signalName does not match any signal
1960 Actor::Actor( DerivedType derivedType )
1965 mParentOrigin( NULL ),
1966 mAnchorPoint( NULL ),
1967 mRelayoutData( NULL ),
1968 mGestureData( NULL ),
1969 mTargetSize( 0.0f, 0.0f, 0.0f ),
1971 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1973 mIsRoot( ROOT_LAYER == derivedType ),
1974 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1975 mIsOnStage( false ),
1977 mLeaveRequired( false ),
1978 mKeyboardFocusable( false ),
1979 mDerivedRequiresTouch( false ),
1980 mDerivedRequiresHover( false ),
1981 mDerivedRequiresWheelEvent( false ),
1982 mOnStageSignalled( false ),
1983 mInsideOnSizeSet( false ),
1984 mInheritPosition( true ),
1985 mInheritOrientation( true ),
1986 mInheritScale( true ),
1987 mDrawMode( DrawMode::NORMAL ),
1988 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1989 mColorMode( Node::DEFAULT_COLOR_MODE ),
1990 mClippingMode( ClippingMode::DISABLED ),
1991 mIsBatchParent( false )
1995 void Actor::Initialize()
1998 SceneGraph::Node* node = CreateNode();
2000 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2001 mNode = node; // Keep raw-pointer to Node
2005 GetEventThreadServices().RegisterObject( this );
2010 // Remove mParent pointers from children even if we're destroying core,
2011 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2014 ActorConstIter endIter = mChildren->end();
2015 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2017 (*iter)->SetParent( NULL );
2023 // Guard to allow handle destruction after Core has been destroyed
2024 if( EventThreadServices::IsCoreRunning() )
2028 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2029 mNode = NULL; // Node is about to be destroyed
2032 GetEventThreadServices().UnregisterObject( this );
2035 // Cleanup optional gesture data
2036 delete mGestureData;
2038 // Cleanup optional parent origin and anchor
2039 delete mParentOrigin;
2040 delete mAnchorPoint;
2042 // Delete optional relayout data
2045 delete mRelayoutData;
2049 void Actor::ConnectToStage( unsigned int parentDepth )
2051 // This container is used instead of walking the Actor hierarchy.
2052 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2053 ActorContainer connectionList;
2055 // This stage is atomic i.e. not interrupted by user callbacks.
2056 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2058 // Notify applications about the newly connected actors.
2059 const ActorIter endIter = connectionList.end();
2060 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2062 (*iter)->NotifyStageConnection();
2068 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2070 DALI_ASSERT_ALWAYS( !OnStage() );
2075 ConnectToSceneGraph();
2077 // Notification for internal derived classes
2078 OnStageConnectionInternal();
2080 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2081 connectionList.push_back( ActorPtr( this ) );
2083 // Recursively connect children
2086 ActorConstIter endIter = mChildren->end();
2087 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2089 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2095 * This method is called when the Actor is connected to the Stage.
2096 * The parent must have added its Node to the scene-graph.
2097 * The child must connect its Node to the parent's Node.
2098 * This is recursive; the child calls ConnectToStage() for its children.
2100 void Actor::ConnectToSceneGraph()
2102 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2106 // Reparent Node in next Update
2107 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2110 unsigned int rendererCount( GetRendererCount() );
2111 for( unsigned int i(0); i<rendererCount; ++i )
2113 GetRendererAt(i)->Connect();
2116 // Request relayout on all actors that are added to the scenegraph
2119 // Notification for Object::Observers
2123 void Actor::NotifyStageConnection()
2125 // Actors can be removed (in a callback), before the on-stage stage is reported.
2126 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2127 if( OnStage() && !mOnStageSignalled )
2129 // Notification for external (CustomActor) derived classes
2130 OnStageConnectionExternal( mDepth );
2132 if( !mOnStageSignal.Empty() )
2134 Dali::Actor handle( this );
2135 mOnStageSignal.Emit( handle );
2138 // Guard against Remove during callbacks
2141 mOnStageSignalled = true; // signal required next time Actor is removed
2146 void Actor::DisconnectFromStage()
2148 // This container is used instead of walking the Actor hierachy.
2149 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2150 ActorContainer disconnectionList;
2152 // This stage is atomic i.e. not interrupted by user callbacks
2153 RecursiveDisconnectFromStage( disconnectionList );
2155 // Notify applications about the newly disconnected actors.
2156 const ActorIter endIter = disconnectionList.end();
2157 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2159 (*iter)->NotifyStageDisconnection();
2163 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2165 DALI_ASSERT_ALWAYS( OnStage() );
2167 // Recursively disconnect children
2170 ActorConstIter endIter = mChildren->end();
2171 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2173 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2177 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2178 disconnectionList.push_back( ActorPtr( this ) );
2180 // Notification for internal derived classes
2181 OnStageDisconnectionInternal();
2183 DisconnectFromSceneGraph();
2189 * This method is called by an actor or its parent, before a node removal message is sent.
2190 * This is recursive; the child calls DisconnectFromStage() for its children.
2192 void Actor::DisconnectFromSceneGraph()
2194 // Notification for Object::Observers
2195 OnSceneObjectRemove();
2197 unsigned int rendererCount( GetRendererCount() );
2198 for( unsigned int i(0); i<rendererCount; ++i )
2200 GetRendererAt(i)->Disconnect();
2204 void Actor::NotifyStageDisconnection()
2206 // Actors can be added (in a callback), before the off-stage state is reported.
2207 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2208 // only do this step if there is a stage, i.e. Core is not being shut down
2209 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2211 // Notification for external (CustomeActor) derived classes
2212 OnStageDisconnectionExternal();
2214 if( !mOffStageSignal.Empty() )
2216 Dali::Actor handle( this );
2217 mOffStageSignal.Emit( handle );
2220 // Guard against Add during callbacks
2223 mOnStageSignalled = false; // signal required next time Actor is added
2228 bool Actor::IsNodeConnected() const
2230 bool connected( false );
2232 if( OnStage() && ( NULL != mNode ) )
2234 if( IsRoot() || mNode->GetParent() )
2243 unsigned int Actor::GetDefaultPropertyCount() const
2245 return DEFAULT_PROPERTY_COUNT;
2248 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2250 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2252 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2254 indices.PushBack( i );
2258 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2260 if( index < DEFAULT_PROPERTY_COUNT )
2262 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2268 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2270 Property::Index index = Property::INVALID_INDEX;
2272 // Look for name in default properties
2273 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2275 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2276 if( 0 == name.compare( property->name ) )
2286 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2288 if( index < DEFAULT_PROPERTY_COUNT )
2290 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2296 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2298 if( index < DEFAULT_PROPERTY_COUNT )
2300 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2306 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2308 if( index < DEFAULT_PROPERTY_COUNT )
2310 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2316 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2318 if( index < DEFAULT_PROPERTY_COUNT )
2320 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2323 // index out of range...return Property::NONE
2324 return Property::NONE;
2327 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2331 case Dali::Actor::Property::PARENT_ORIGIN:
2333 Property::Type type = property.GetType();
2334 if( type == Property::VECTOR3 )
2336 SetParentOrigin( property.Get< Vector3 >() );
2338 else if ( type == Property::STRING )
2340 std::string parentOriginString;
2341 property.Get( parentOriginString );
2342 Vector3 parentOrigin;
2343 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2345 SetParentOrigin( parentOrigin );
2351 case Dali::Actor::Property::PARENT_ORIGIN_X:
2353 SetParentOriginX( property.Get< float >() );
2357 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2359 SetParentOriginY( property.Get< float >() );
2363 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2365 SetParentOriginZ( property.Get< float >() );
2369 case Dali::Actor::Property::ANCHOR_POINT:
2371 Property::Type type = property.GetType();
2372 if( type == Property::VECTOR3 )
2374 SetAnchorPoint( property.Get< Vector3 >() );
2376 else if ( type == Property::STRING )
2378 std::string anchorPointString;
2379 property.Get( anchorPointString );
2381 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2383 SetAnchorPoint( anchor );
2389 case Dali::Actor::Property::ANCHOR_POINT_X:
2391 SetAnchorPointX( property.Get< float >() );
2395 case Dali::Actor::Property::ANCHOR_POINT_Y:
2397 SetAnchorPointY( property.Get< float >() );
2401 case Dali::Actor::Property::ANCHOR_POINT_Z:
2403 SetAnchorPointZ( property.Get< float >() );
2407 case Dali::Actor::Property::SIZE:
2409 SetSize( property.Get< Vector3 >() );
2413 case Dali::Actor::Property::SIZE_WIDTH:
2415 SetWidth( property.Get< float >() );
2419 case Dali::Actor::Property::SIZE_HEIGHT:
2421 SetHeight( property.Get< float >() );
2425 case Dali::Actor::Property::SIZE_DEPTH:
2427 SetDepth( property.Get< float >() );
2431 case Dali::Actor::Property::POSITION:
2433 SetPosition( property.Get< Vector3 >() );
2437 case Dali::Actor::Property::POSITION_X:
2439 SetX( property.Get< float >() );
2443 case Dali::Actor::Property::POSITION_Y:
2445 SetY( property.Get< float >() );
2449 case Dali::Actor::Property::POSITION_Z:
2451 SetZ( property.Get< float >() );
2455 case Dali::Actor::Property::ORIENTATION:
2457 SetOrientation( property.Get< Quaternion >() );
2461 case Dali::Actor::Property::SCALE:
2463 SetScale( property.Get< Vector3 >() );
2467 case Dali::Actor::Property::SCALE_X:
2469 SetScaleX( property.Get< float >() );
2473 case Dali::Actor::Property::SCALE_Y:
2475 SetScaleY( property.Get< float >() );
2479 case Dali::Actor::Property::SCALE_Z:
2481 SetScaleZ( property.Get< float >() );
2485 case Dali::Actor::Property::VISIBLE:
2487 SetVisible( property.Get< bool >() );
2491 case Dali::Actor::Property::COLOR:
2493 SetColor( property.Get< Vector4 >() );
2497 case Dali::Actor::Property::COLOR_RED:
2499 SetColorRed( property.Get< float >() );
2503 case Dali::Actor::Property::COLOR_GREEN:
2505 SetColorGreen( property.Get< float >() );
2509 case Dali::Actor::Property::COLOR_BLUE:
2511 SetColorBlue( property.Get< float >() );
2515 case Dali::Actor::Property::COLOR_ALPHA:
2517 SetOpacity( property.Get< float >() );
2521 case Dali::Actor::Property::NAME:
2523 SetName( property.Get< std::string >() );
2527 case Dali::Actor::Property::SENSITIVE:
2529 SetSensitive( property.Get< bool >() );
2533 case Dali::Actor::Property::LEAVE_REQUIRED:
2535 SetLeaveRequired( property.Get< bool >() );
2539 case Dali::Actor::Property::INHERIT_POSITION:
2541 SetInheritPosition( property.Get< bool >() );
2545 case Dali::Actor::Property::INHERIT_ORIENTATION:
2547 SetInheritOrientation( property.Get< bool >() );
2551 case Dali::Actor::Property::INHERIT_SCALE:
2553 SetInheritScale( property.Get< bool >() );
2557 case Dali::Actor::Property::COLOR_MODE:
2560 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2562 SetColorMode( mode );
2567 case Dali::Actor::Property::POSITION_INHERITANCE:
2569 PositionInheritanceMode mode;
2570 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2572 SetPositionInheritanceMode( mode );
2577 case Dali::Actor::Property::DRAW_MODE:
2579 DrawMode::Type mode;
2580 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2582 SetDrawMode( mode );
2587 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2589 SetSizeModeFactor( property.Get< Vector3 >() );
2593 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2595 ResizePolicy::Type type;
2596 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2598 SetResizePolicy( type, Dimension::WIDTH );
2603 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2605 ResizePolicy::Type type;
2606 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2608 SetResizePolicy( type, Dimension::HEIGHT );
2613 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2615 SizeScalePolicy::Type type;
2616 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2618 SetSizeScalePolicy( type );
2623 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2625 if( property.Get< bool >() )
2627 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2632 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2634 if( property.Get< bool >() )
2636 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2641 case Dali::Actor::Property::PADDING:
2643 Vector4 padding = property.Get< Vector4 >();
2644 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2645 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2649 case Dali::Actor::Property::MINIMUM_SIZE:
2651 Vector2 size = property.Get< Vector2 >();
2652 SetMinimumSize( size.x, Dimension::WIDTH );
2653 SetMinimumSize( size.y, Dimension::HEIGHT );
2657 case Dali::Actor::Property::MAXIMUM_SIZE:
2659 Vector2 size = property.Get< Vector2 >();
2660 SetMaximumSize( size.x, Dimension::WIDTH );
2661 SetMaximumSize( size.y, Dimension::HEIGHT );
2665 case Dali::DevelActor::Property::BATCH_PARENT:
2669 if( property.Get( value ) )
2671 if( value != mIsBatchParent )
2673 mIsBatchParent = value;
2674 SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2680 case Dali::Actor::Property::CLIPPING_MODE:
2682 ClippingMode::Type convertedValue = mClippingMode;
2683 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2685 mClippingMode = convertedValue;
2688 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2696 // this can happen in the case of a non-animatable default property so just do nothing
2702 // TODO: This method needs to be removed
2703 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2705 switch( entry.GetType() )
2707 case Property::BOOLEAN:
2709 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2710 DALI_ASSERT_DEBUG( NULL != property );
2712 // property is being used in a separate thread; queue a message to set the property
2713 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2718 case Property::INTEGER:
2720 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2721 DALI_ASSERT_DEBUG( NULL != property );
2723 // property is being used in a separate thread; queue a message to set the property
2724 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2729 case Property::FLOAT:
2731 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2732 DALI_ASSERT_DEBUG( NULL != property );
2734 // property is being used in a separate thread; queue a message to set the property
2735 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2740 case Property::VECTOR2:
2742 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2743 DALI_ASSERT_DEBUG( NULL != property );
2745 // property is being used in a separate thread; queue a message to set the property
2746 if(entry.componentIndex == 0)
2748 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2750 else if(entry.componentIndex == 1)
2752 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2756 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2762 case Property::VECTOR3:
2764 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2765 DALI_ASSERT_DEBUG( NULL != property );
2767 // property is being used in a separate thread; queue a message to set the property
2768 if(entry.componentIndex == 0)
2770 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2772 else if(entry.componentIndex == 1)
2774 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2776 else if(entry.componentIndex == 2)
2778 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2782 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2788 case Property::VECTOR4:
2790 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2791 DALI_ASSERT_DEBUG( NULL != property );
2793 // property is being used in a separate thread; queue a message to set the property
2794 if(entry.componentIndex == 0)
2796 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2798 else if(entry.componentIndex == 1)
2800 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2802 else if(entry.componentIndex == 2)
2804 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2806 else if(entry.componentIndex == 3)
2808 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2812 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2818 case Property::ROTATION:
2820 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2821 DALI_ASSERT_DEBUG( NULL != property );
2823 // property is being used in a separate thread; queue a message to set the property
2824 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2829 case Property::MATRIX:
2831 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2832 DALI_ASSERT_DEBUG( NULL != property );
2834 // property is being used in a separate thread; queue a message to set the property
2835 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2840 case Property::MATRIX3:
2842 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2843 DALI_ASSERT_DEBUG( NULL != property );
2845 // property is being used in a separate thread; queue a message to set the property
2846 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2853 // nothing to do for other types
2858 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2860 Property::Value value;
2864 case Dali::Actor::Property::PARENT_ORIGIN:
2866 value = GetCurrentParentOrigin();
2870 case Dali::Actor::Property::PARENT_ORIGIN_X:
2872 value = GetCurrentParentOrigin().x;
2876 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2878 value = GetCurrentParentOrigin().y;
2882 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2884 value = GetCurrentParentOrigin().z;
2888 case Dali::Actor::Property::ANCHOR_POINT:
2890 value = GetCurrentAnchorPoint();
2894 case Dali::Actor::Property::ANCHOR_POINT_X:
2896 value = GetCurrentAnchorPoint().x;
2900 case Dali::Actor::Property::ANCHOR_POINT_Y:
2902 value = GetCurrentAnchorPoint().y;
2906 case Dali::Actor::Property::ANCHOR_POINT_Z:
2908 value = GetCurrentAnchorPoint().z;
2912 case Dali::Actor::Property::SIZE:
2914 value = GetTargetSize();
2918 case Dali::Actor::Property::SIZE_WIDTH:
2920 value = GetTargetSize().width;
2924 case Dali::Actor::Property::SIZE_HEIGHT:
2926 value = GetTargetSize().height;
2930 case Dali::Actor::Property::SIZE_DEPTH:
2932 value = GetTargetSize().depth;
2936 case Dali::Actor::Property::POSITION:
2938 value = GetTargetPosition();
2942 case Dali::Actor::Property::POSITION_X:
2944 value = GetTargetPosition().x;
2948 case Dali::Actor::Property::POSITION_Y:
2950 value = GetTargetPosition().y;
2954 case Dali::Actor::Property::POSITION_Z:
2956 value = GetTargetPosition().z;
2960 case Dali::Actor::Property::WORLD_POSITION:
2962 value = GetCurrentWorldPosition();
2966 case Dali::Actor::Property::WORLD_POSITION_X:
2968 value = GetCurrentWorldPosition().x;
2972 case Dali::Actor::Property::WORLD_POSITION_Y:
2974 value = GetCurrentWorldPosition().y;
2978 case Dali::Actor::Property::WORLD_POSITION_Z:
2980 value = GetCurrentWorldPosition().z;
2984 case Dali::Actor::Property::ORIENTATION:
2986 value = GetCurrentOrientation();
2990 case Dali::Actor::Property::WORLD_ORIENTATION:
2992 value = GetCurrentWorldOrientation();
2996 case Dali::Actor::Property::SCALE:
2998 value = GetCurrentScale();
3002 case Dali::Actor::Property::SCALE_X:
3004 value = GetCurrentScale().x;
3008 case Dali::Actor::Property::SCALE_Y:
3010 value = GetCurrentScale().y;
3014 case Dali::Actor::Property::SCALE_Z:
3016 value = GetCurrentScale().z;
3020 case Dali::Actor::Property::WORLD_SCALE:
3022 value = GetCurrentWorldScale();
3026 case Dali::Actor::Property::VISIBLE:
3028 value = IsVisible();
3032 case Dali::Actor::Property::COLOR:
3034 value = GetCurrentColor();
3038 case Dali::Actor::Property::COLOR_RED:
3040 value = GetCurrentColor().r;
3044 case Dali::Actor::Property::COLOR_GREEN:
3046 value = GetCurrentColor().g;
3050 case Dali::Actor::Property::COLOR_BLUE:
3052 value = GetCurrentColor().b;
3056 case Dali::Actor::Property::COLOR_ALPHA:
3058 value = GetCurrentColor().a;
3062 case Dali::Actor::Property::WORLD_COLOR:
3064 value = GetCurrentWorldColor();
3068 case Dali::Actor::Property::WORLD_MATRIX:
3070 value = GetCurrentWorldMatrix();
3074 case Dali::Actor::Property::NAME:
3080 case Dali::Actor::Property::SENSITIVE:
3082 value = IsSensitive();
3086 case Dali::Actor::Property::LEAVE_REQUIRED:
3088 value = GetLeaveRequired();
3092 case Dali::Actor::Property::INHERIT_POSITION:
3094 value = IsPositionInherited();
3098 case Dali::Actor::Property::INHERIT_ORIENTATION:
3100 value = IsOrientationInherited();
3104 case Dali::Actor::Property::INHERIT_SCALE:
3106 value = IsScaleInherited();
3110 case Dali::Actor::Property::COLOR_MODE:
3112 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3116 case Dali::Actor::Property::POSITION_INHERITANCE:
3118 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3122 case Dali::Actor::Property::DRAW_MODE:
3124 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3128 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3130 value = GetSizeModeFactor();
3134 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3136 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3140 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3142 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3146 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3148 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3152 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3154 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3158 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3160 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3164 case Dali::Actor::Property::PADDING:
3166 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3167 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3168 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3172 case Dali::Actor::Property::MINIMUM_SIZE:
3174 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3178 case Dali::Actor::Property::MAXIMUM_SIZE:
3180 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3184 case Dali::DevelActor::Property::BATCH_PARENT:
3186 value = mIsBatchParent;
3190 case Dali::Actor::Property::CLIPPING_MODE:
3192 value = mClippingMode;
3200 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3205 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3207 // This method should only return an object connected to the scene-graph
3208 return OnStage() ? mNode : NULL;
3211 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3213 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3215 const PropertyBase* property( NULL );
3217 // This method should only return a property of an object connected to the scene-graph
3223 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3225 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3226 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3228 property = animatable->GetSceneGraphProperty();
3230 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3231 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3233 CustomPropertyMetadata* custom = FindCustomProperty( index );
3234 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3236 property = custom->GetSceneGraphProperty();
3238 else if( NULL != mNode )
3242 case Dali::Actor::Property::SIZE:
3243 property = &mNode->mSize;
3246 case Dali::Actor::Property::SIZE_WIDTH:
3247 property = &mNode->mSize;
3250 case Dali::Actor::Property::SIZE_HEIGHT:
3251 property = &mNode->mSize;
3254 case Dali::Actor::Property::SIZE_DEPTH:
3255 property = &mNode->mSize;
3258 case Dali::Actor::Property::POSITION:
3259 property = &mNode->mPosition;
3262 case Dali::Actor::Property::POSITION_X:
3263 property = &mNode->mPosition;
3266 case Dali::Actor::Property::POSITION_Y:
3267 property = &mNode->mPosition;
3270 case Dali::Actor::Property::POSITION_Z:
3271 property = &mNode->mPosition;
3274 case Dali::Actor::Property::ORIENTATION:
3275 property = &mNode->mOrientation;
3278 case Dali::Actor::Property::SCALE:
3279 property = &mNode->mScale;
3282 case Dali::Actor::Property::SCALE_X:
3283 property = &mNode->mScale;
3286 case Dali::Actor::Property::SCALE_Y:
3287 property = &mNode->mScale;
3290 case Dali::Actor::Property::SCALE_Z:
3291 property = &mNode->mScale;
3294 case Dali::Actor::Property::VISIBLE:
3295 property = &mNode->mVisible;
3298 case Dali::Actor::Property::COLOR:
3299 property = &mNode->mColor;
3302 case Dali::Actor::Property::COLOR_RED:
3303 property = &mNode->mColor;
3306 case Dali::Actor::Property::COLOR_GREEN:
3307 property = &mNode->mColor;
3310 case Dali::Actor::Property::COLOR_BLUE:
3311 property = &mNode->mColor;
3314 case Dali::Actor::Property::COLOR_ALPHA:
3315 property = &mNode->mColor;
3326 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3328 const PropertyInputImpl* property( NULL );
3330 // This method should only return a property of an object connected to the scene-graph
3336 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3338 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3339 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3341 property = animatable->GetSceneGraphProperty();
3343 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3344 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3346 CustomPropertyMetadata* custom = FindCustomProperty( index );
3347 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3348 property = custom->GetSceneGraphProperty();
3350 else if( NULL != mNode )
3354 case Dali::Actor::Property::PARENT_ORIGIN:
3355 property = &mNode->mParentOrigin;
3358 case Dali::Actor::Property::PARENT_ORIGIN_X:
3359 property = &mNode->mParentOrigin;
3362 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3363 property = &mNode->mParentOrigin;
3366 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3367 property = &mNode->mParentOrigin;
3370 case Dali::Actor::Property::ANCHOR_POINT:
3371 property = &mNode->mAnchorPoint;
3374 case Dali::Actor::Property::ANCHOR_POINT_X:
3375 property = &mNode->mAnchorPoint;
3378 case Dali::Actor::Property::ANCHOR_POINT_Y:
3379 property = &mNode->mAnchorPoint;
3382 case Dali::Actor::Property::ANCHOR_POINT_Z:
3383 property = &mNode->mAnchorPoint;
3386 case Dali::Actor::Property::SIZE:
3387 property = &mNode->mSize;
3390 case Dali::Actor::Property::SIZE_WIDTH:
3391 property = &mNode->mSize;
3394 case Dali::Actor::Property::SIZE_HEIGHT:
3395 property = &mNode->mSize;
3398 case Dali::Actor::Property::SIZE_DEPTH:
3399 property = &mNode->mSize;
3402 case Dali::Actor::Property::POSITION:
3403 property = &mNode->mPosition;
3406 case Dali::Actor::Property::POSITION_X:
3407 property = &mNode->mPosition;
3410 case Dali::Actor::Property::POSITION_Y:
3411 property = &mNode->mPosition;
3414 case Dali::Actor::Property::POSITION_Z:
3415 property = &mNode->mPosition;
3418 case Dali::Actor::Property::WORLD_POSITION:
3419 property = &mNode->mWorldPosition;
3422 case Dali::Actor::Property::WORLD_POSITION_X:
3423 property = &mNode->mWorldPosition;
3426 case Dali::Actor::Property::WORLD_POSITION_Y:
3427 property = &mNode->mWorldPosition;
3430 case Dali::Actor::Property::WORLD_POSITION_Z:
3431 property = &mNode->mWorldPosition;
3434 case Dali::Actor::Property::ORIENTATION:
3435 property = &mNode->mOrientation;
3438 case Dali::Actor::Property::WORLD_ORIENTATION:
3439 property = &mNode->mWorldOrientation;
3442 case Dali::Actor::Property::SCALE:
3443 property = &mNode->mScale;
3446 case Dali::Actor::Property::SCALE_X:
3447 property = &mNode->mScale;
3450 case Dali::Actor::Property::SCALE_Y:
3451 property = &mNode->mScale;
3454 case Dali::Actor::Property::SCALE_Z:
3455 property = &mNode->mScale;
3458 case Dali::Actor::Property::WORLD_SCALE:
3459 property = &mNode->mWorldScale;
3462 case Dali::Actor::Property::VISIBLE:
3463 property = &mNode->mVisible;
3466 case Dali::Actor::Property::COLOR:
3467 property = &mNode->mColor;
3470 case Dali::Actor::Property::COLOR_RED:
3471 property = &mNode->mColor;
3474 case Dali::Actor::Property::COLOR_GREEN:
3475 property = &mNode->mColor;
3478 case Dali::Actor::Property::COLOR_BLUE:
3479 property = &mNode->mColor;
3482 case Dali::Actor::Property::COLOR_ALPHA:
3483 property = &mNode->mColor;
3486 case Dali::Actor::Property::WORLD_COLOR:
3487 property = &mNode->mWorldColor;
3490 case Dali::Actor::Property::WORLD_MATRIX:
3491 property = &mNode->mWorldMatrix;
3502 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3504 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3506 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3508 // check whether the animatable property is registered already, if not then register one.
3509 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3510 if( animatableProperty )
3512 componentIndex = animatableProperty->componentIndex;
3519 case Dali::Actor::Property::PARENT_ORIGIN_X:
3520 case Dali::Actor::Property::ANCHOR_POINT_X:
3521 case Dali::Actor::Property::SIZE_WIDTH:
3522 case Dali::Actor::Property::POSITION_X:
3523 case Dali::Actor::Property::WORLD_POSITION_X:
3524 case Dali::Actor::Property::SCALE_X:
3525 case Dali::Actor::Property::COLOR_RED:
3531 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3532 case Dali::Actor::Property::ANCHOR_POINT_Y:
3533 case Dali::Actor::Property::SIZE_HEIGHT:
3534 case Dali::Actor::Property::POSITION_Y:
3535 case Dali::Actor::Property::WORLD_POSITION_Y:
3536 case Dali::Actor::Property::SCALE_Y:
3537 case Dali::Actor::Property::COLOR_GREEN:
3543 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3544 case Dali::Actor::Property::ANCHOR_POINT_Z:
3545 case Dali::Actor::Property::SIZE_DEPTH:
3546 case Dali::Actor::Property::POSITION_Z:
3547 case Dali::Actor::Property::WORLD_POSITION_Z:
3548 case Dali::Actor::Property::SCALE_Z:
3549 case Dali::Actor::Property::COLOR_BLUE:
3555 case Dali::Actor::Property::COLOR_ALPHA:
3569 return componentIndex;
3572 void Actor::SetParent( Actor* parent )
3576 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3580 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3583 // Instruct each actor to create a corresponding node in the scene graph
3584 ConnectToStage( parent->GetHierarchyDepth() );
3587 // Resolve the name and index for the child properties if any
3588 ResolveChildProperties();
3590 else // parent being set to NULL
3592 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3596 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3599 DALI_ASSERT_ALWAYS( mNode != NULL );
3603 // Disconnect the Node & its children from the scene-graph.
3604 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3607 // Instruct each actor to discard pointers to the scene-graph
3608 DisconnectFromStage();
3613 SceneGraph::Node* Actor::CreateNode() const
3618 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3621 Actor* actor = dynamic_cast< Actor* >( object );
3625 if( 0 == actionName.compare( ACTION_SHOW ) )
3627 actor->SetVisible( true );
3630 else if( 0 == actionName.compare( ACTION_HIDE ) )
3632 actor->SetVisible( false );
3640 void Actor::EnsureRelayoutData()
3642 // Assign relayout data.
3643 if( !mRelayoutData )
3645 mRelayoutData = new RelayoutData();
3649 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3651 // Check if actor is dependent on parent
3652 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3654 if( ( dimension & ( 1 << i ) ) )
3656 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3657 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3667 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3669 // Check if actor is dependent on children
3670 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3672 if( ( dimension & ( 1 << i ) ) )
3674 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3675 switch( resizePolicy )
3677 case ResizePolicy::FIT_TO_CHILDREN:
3678 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3694 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3696 return Actor::RelayoutDependentOnChildren( dimension );
3699 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3701 // Check each possible dimension and see if it is dependent on the input one
3702 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3704 if( dimension & ( 1 << i ) )
3706 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3713 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3715 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3717 if( dimension & ( 1 << i ) )
3719 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3724 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3726 // If more than one dimension is requested, just return the first one found
3727 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3729 if( ( dimension & ( 1 << i ) ) )
3731 return mRelayoutData->negotiatedDimensions[ i ];
3735 return 0.0f; // Default
3738 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3740 EnsureRelayoutData();
3742 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3744 if( dimension & ( 1 << i ) )
3746 mRelayoutData->dimensionPadding[ i ] = padding;
3751 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3753 if ( mRelayoutData )
3755 // If more than one dimension is requested, just return the first one found
3756 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3758 if( ( dimension & ( 1 << i ) ) )
3760 return mRelayoutData->dimensionPadding[ i ];
3765 return GetDefaultDimensionPadding();
3768 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3770 EnsureRelayoutData();
3772 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3774 if( dimension & ( 1 << i ) )
3776 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3781 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3783 if ( mRelayoutData )
3785 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3787 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3797 float Actor::GetHeightForWidthBase( float width )
3799 float height = 0.0f;
3801 const Vector3 naturalSize = GetNaturalSize();
3802 if( naturalSize.width > 0.0f )
3804 height = naturalSize.height * width / naturalSize.width;
3806 else // we treat 0 as 1:1 aspect ratio
3814 float Actor::GetWidthForHeightBase( float height )
3818 const Vector3 naturalSize = GetNaturalSize();
3819 if( naturalSize.height > 0.0f )
3821 width = naturalSize.width * height / naturalSize.height;
3823 else // we treat 0 as 1:1 aspect ratio
3831 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3833 // Fill to parent, taking size mode factor into account
3834 switch( child.GetResizePolicy( dimension ) )
3836 case ResizePolicy::FILL_TO_PARENT:
3838 return GetLatestSize( dimension );
3841 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3843 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3846 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3848 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3853 return GetLatestSize( dimension );
3858 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3860 // Can be overridden in derived class
3861 return CalculateChildSizeBase( child, dimension );
3864 float Actor::GetHeightForWidth( float width )
3866 // Can be overridden in derived class
3867 return GetHeightForWidthBase( width );
3870 float Actor::GetWidthForHeight( float height )
3872 // Can be overridden in derived class
3873 return GetWidthForHeightBase( height );
3876 float Actor::GetLatestSize( Dimension::Type dimension ) const
3878 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3881 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3883 Vector2 padding = GetPadding( dimension );
3885 return GetLatestSize( dimension ) + padding.x + padding.y;
3888 float Actor::NegotiateFromParent( Dimension::Type dimension )
3890 Actor* parent = GetParent();
3893 Vector2 padding( GetPadding( dimension ) );
3894 Vector2 parentPadding( parent->GetPadding( dimension ) );
3895 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3901 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3903 float maxDimensionPoint = 0.0f;
3905 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3907 ActorPtr child = GetChildAt( i );
3909 if( !child->RelayoutDependentOnParent( dimension ) )
3911 // Calculate the min and max points that the children range across
3912 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3913 float dimensionSize = child->GetRelayoutSize( dimension );
3914 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3918 return maxDimensionPoint;
3921 float Actor::GetSize( Dimension::Type dimension ) const
3923 return GetDimensionValue( GetTargetSize(), dimension );
3926 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3928 return GetDimensionValue( GetNaturalSize(), dimension );
3931 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3933 switch( GetResizePolicy( dimension ) )
3935 case ResizePolicy::USE_NATURAL_SIZE:
3937 return GetNaturalSize( dimension );
3940 case ResizePolicy::FIXED:
3942 return GetDimensionValue( GetPreferredSize(), dimension );
3945 case ResizePolicy::USE_ASSIGNED_SIZE:
3947 return GetDimensionValue( maximumSize, dimension );
3950 case ResizePolicy::FILL_TO_PARENT:
3951 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3952 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3954 return NegotiateFromParent( dimension );
3957 case ResizePolicy::FIT_TO_CHILDREN:
3959 return NegotiateFromChildren( dimension );
3962 case ResizePolicy::DIMENSION_DEPENDENCY:
3964 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3967 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3969 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3972 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3974 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3986 return 0.0f; // Default
3989 float Actor::ClampDimension( float size, Dimension::Type dimension )
3991 const float minSize = GetMinimumSize( dimension );
3992 const float maxSize = GetMaximumSize( dimension );
3994 return std::max( minSize, std::min( size, maxSize ) );
3997 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
3999 // Check if it needs to be negotiated
4000 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4002 // Check that we havn't gotten into an infinite loop
4003 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4004 bool recursionFound = false;
4005 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4007 if( *it == searchActor )
4009 recursionFound = true;
4014 if( !recursionFound )
4016 // Record the path that we have taken
4017 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4019 // Dimension dependency check
4020 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4022 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4024 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4026 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4030 // Parent dependency check
4031 Actor* parent = GetParent();
4032 if( parent && RelayoutDependentOnParent( dimension ) )
4034 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4037 // Children dependency check
4038 if( RelayoutDependentOnChildren( dimension ) )
4040 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4042 ActorPtr child = GetChildAt( i );
4044 // Only relayout child first if it is not dependent on this actor
4045 if( !child->RelayoutDependentOnParent( dimension ) )
4047 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4052 // For deriving classes
4053 OnCalculateRelayoutSize( dimension );
4055 // All dependencies checked, calculate the size and set negotiated flag
4056 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4058 SetNegotiatedDimension( newSize, dimension );
4059 SetLayoutNegotiated( true, dimension );
4061 // For deriving classes
4062 OnLayoutNegotiated( newSize, dimension );
4064 // This actor has been successfully processed, pop it off the recursion stack
4065 recursionStack.pop_back();
4069 // TODO: Break infinite loop
4070 SetLayoutNegotiated( true, dimension );
4075 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4077 // Negotiate all dimensions that require it
4078 ActorDimensionStack recursionStack;
4080 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4082 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4085 NegotiateDimension( dimension, allocatedSize, recursionStack );
4089 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4091 switch( mRelayoutData->sizeSetPolicy )
4093 case SizeScalePolicy::USE_SIZE_SET:
4098 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4100 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4101 const Vector3 naturalSize = GetNaturalSize();
4102 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4104 const float sizeRatio = size.width / size.height;
4105 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4107 if( naturalSizeRatio < sizeRatio )
4109 return Vector2( naturalSizeRatio * size.height, size.height );
4111 else if( naturalSizeRatio > sizeRatio )
4113 return Vector2( size.width, size.width / naturalSizeRatio );
4124 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4126 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4127 const Vector3 naturalSize = GetNaturalSize();
4128 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4130 const float sizeRatio = size.width / size.height;
4131 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4133 if( naturalSizeRatio < sizeRatio )
4135 return Vector2( size.width, size.width / naturalSizeRatio );
4137 else if( naturalSizeRatio > sizeRatio )
4139 return Vector2( naturalSizeRatio * size.height, size.height );
4158 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4160 // Do the set actor size
4161 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4163 // Adjust for size set policy
4164 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4166 // Lock the flag to stop recursive relayouts on set size
4167 mRelayoutData->insideRelayout = true;
4168 SetSize( negotiatedSize );
4169 mRelayoutData->insideRelayout = false;
4171 // Clear flags for all dimensions
4172 SetLayoutDirty( false );
4174 // Give deriving classes a chance to respond
4175 OnRelayout( negotiatedSize, container );
4177 if( !mOnRelayoutSignal.Empty() )
4179 Dali::Actor handle( this );
4180 mOnRelayoutSignal.Emit( handle );
4184 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4186 // Force a size negotiation for actors that has assigned size during relayout
4187 // This is required as otherwise the flags that force a relayout will not
4188 // necessarilly be set. This will occur if the actor has already been laid out.
4189 // The dirty flags are then cleared. Then if the actor is added back into the
4190 // relayout container afterwards, the dirty flags would still be clear...
4191 // causing a relayout to be skipped. Here we force any actors added to the
4192 // container to be relayed out.
4193 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4195 SetLayoutNegotiated(false, Dimension::WIDTH);
4197 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4199 SetLayoutNegotiated(false, Dimension::HEIGHT);
4202 // Do the negotiation
4203 NegotiateDimensions( allocatedSize );
4205 // Set the actor size
4206 SetNegotiatedSize( container );
4208 // Negotiate down to children
4209 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4211 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4213 ActorPtr child = GetChildAt( i );
4215 // Forces children that have already been laid out to be relayed out
4216 // if they have assigned size during relayout.
4217 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4219 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4220 child->SetLayoutDirty(true, Dimension::WIDTH);
4222 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4224 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4225 child->SetLayoutDirty(true, Dimension::HEIGHT);
4228 // Only relayout if required
4229 if( child->RelayoutRequired() )
4231 container.Add( Dali::Actor( child.Get() ), newBounds );
4236 void Actor::RelayoutRequest( Dimension::Type dimension )
4238 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4239 if( relayoutController )
4241 Dali::Actor self( this );
4242 relayoutController->RequestRelayout( self, dimension );
4246 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4250 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4254 void Actor::SetPreferredSize( const Vector2& size )
4256 EnsureRelayoutData();
4258 if( size.width > 0.0f )
4260 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4263 if( size.height > 0.0f )
4265 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4268 mRelayoutData->preferredSize = size;
4273 Vector2 Actor::GetPreferredSize() const
4275 if ( mRelayoutData )
4277 return Vector2( mRelayoutData->preferredSize );
4280 return GetDefaultPreferredSize();
4283 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4285 EnsureRelayoutData();
4287 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4289 if( dimension & ( 1 << i ) )
4291 mRelayoutData->minimumSize[ i ] = size;
4298 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4300 if ( mRelayoutData )
4302 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4304 if( dimension & ( 1 << i ) )
4306 return mRelayoutData->minimumSize[ i ];
4311 return 0.0f; // Default
4314 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4316 EnsureRelayoutData();
4318 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4320 if( dimension & ( 1 << i ) )
4322 mRelayoutData->maximumSize[ i ] = size;
4329 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4331 if ( mRelayoutData )
4333 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4335 if( dimension & ( 1 << i ) )
4337 return mRelayoutData->maximumSize[ i ];
4342 return FLT_MAX; // Default
4345 Object* Actor::GetParentObject() const
4350 } // namespace Internal