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>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
36 #include <dali/devel-api/scripting/scripting.h>
38 #include <dali/internal/common/internal-constants.h>
39 #include <dali/internal/event/common/event-thread-services.h>
40 #include <dali/internal/event/render-tasks/render-task-impl.h>
41 #include <dali/internal/event/actors/camera-actor-impl.h>
42 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
43 #include <dali/internal/event/common/property-helper.h>
44 #include <dali/internal/event/common/stage-impl.h>
45 #include <dali/internal/event/common/type-info-impl.h>
46 #include <dali/internal/event/animation/constraint-impl.h>
47 #include <dali/internal/event/common/projection.h>
48 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
49 #include <dali/internal/update/common/animatable-property.h>
50 #include <dali/internal/update/nodes/node-messages.h>
51 #include <dali/internal/update/nodes/node-declarations.h>
52 #include <dali/internal/update/animation/scene-graph-constraint.h>
53 #include <dali/internal/event/events/actor-gesture-data.h>
54 #include <dali/internal/common/message.h>
55 #include <dali/integration-api/debug.h>
57 using Dali::Internal::SceneGraph::Node;
58 using Dali::Internal::SceneGraph::AnimatableProperty;
59 using Dali::Internal::SceneGraph::PropertyBase;
67 unsigned int Actor::mActorCounter = 0;
71 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
72 inline const Vector3& GetDefaultSizeModeFactor()
77 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
78 inline const Vector2& GetDefaultPreferredSize()
83 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
84 inline const Vector2& GetDefaultDimensionPadding()
89 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
91 } // unnamed namespace
94 * Struct to collect relayout variables
96 struct Actor::RelayoutData
99 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
101 // Set size negotiation defaults
102 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
104 resizePolicies[ i ] = ResizePolicy::DEFAULT;
105 negotiatedDimensions[ i ] = 0.0f;
106 dimensionNegotiated[ i ] = false;
107 dimensionDirty[ i ] = false;
108 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
109 dimensionPadding[ i ] = GetDefaultDimensionPadding();
110 minimumSize[ i ] = 0.0f;
111 maximumSize[ i ] = FLT_MAX;
115 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
117 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
119 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
121 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
123 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
124 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
126 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
127 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
129 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
131 Vector2 preferredSize; ///< The preferred size of the actor
133 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
135 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
136 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
139 namespace // unnamed namespace
145 * We want to discourage the use of property strings (minimize string comparisons),
146 * particularly for the default properties.
147 * Name Type writable animatable constraint-input enum for index-checking
149 DALI_PROPERTY_TABLE_BEGIN
150 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
151 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
152 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
153 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
154 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
155 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
156 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
157 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
158 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
159 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
160 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
161 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
162 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
163 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
164 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
165 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
166 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
167 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
168 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
169 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
170 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
171 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
172 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
173 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
174 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
175 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
176 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
177 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
178 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
179 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
180 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
181 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
182 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
183 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
184 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
185 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
186 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
187 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
188 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
189 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
190 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
191 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
192 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
193 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
194 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
195 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
196 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
197 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
198 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
199 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
200 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
201 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
202 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
203 DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::Actor::Property::BATCH_PARENT )
204 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
208 const char* const SIGNAL_TOUCHED = "touched";
209 const char* const SIGNAL_HOVERED = "hovered";
210 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
211 const char* const SIGNAL_ON_STAGE = "onStage";
212 const char* const SIGNAL_OFF_STAGE = "offStage";
213 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
214 const char* const SIGNAL_TOUCH = "touch";
218 const char* const ACTION_SHOW = "show";
219 const char* const ACTION_HIDE = "hide";
221 BaseHandle CreateActor()
223 return Dali::Actor::New();
226 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
228 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
229 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
230 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
231 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
232 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
233 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
234 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
236 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
237 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
242 const Vector3& value;
245 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
246 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
247 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
248 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
249 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
250 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
251 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
252 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
253 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
254 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
255 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
257 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
258 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
259 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
260 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
261 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
262 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
264 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
265 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
266 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
267 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
268 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
269 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
271 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
275 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
277 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
286 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
288 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
289 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
292 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
294 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
296 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
298 size_t sizeIgnored = 0;
299 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
301 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
308 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
310 // Values are the same so just use the same table as anchor-point
311 return GetAnchorPointConstant( value, parentOrigin );
315 * @brief Extract a given dimension from a Vector2
317 * @param[in] values The values to extract from
318 * @param[in] dimension The dimension to extract
319 * @return Return the value for the dimension
321 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
325 case Dimension::WIDTH:
329 case Dimension::HEIGHT:
331 return values.height;
342 * @brief Extract a given dimension from a Vector3
344 * @param[in] values The values to extract from
345 * @param[in] dimension The dimension to extract
346 * @return Return the value for the dimension
348 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
350 return GetDimensionValue( values.GetVectorXY(), dimension );
354 } // unnamed namespace
356 ActorPtr Actor::New()
358 ActorPtr actor( new Actor( BASIC ) );
360 // Second-phase construction
366 const std::string& Actor::GetName() const
371 void Actor::SetName( const std::string& name )
377 // ATTENTION: string for debug purposes is not thread safe.
378 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
382 unsigned int Actor::GetId() const
387 bool Actor::OnStage() const
392 Dali::Layer Actor::GetLayer()
396 // Short-circuit for Layer derived actors
399 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
402 // Find the immediate Layer parent
403 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
405 if( parent->IsLayer() )
407 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
414 void Actor::Add( Actor& child )
416 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
417 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
421 mChildren = new ActorContainer;
424 Actor* const oldParent( child.mParent );
426 // child might already be ours
427 if( this != oldParent )
429 // if we already have parent, unparent us first
432 oldParent->Remove( child ); // This causes OnChildRemove callback
434 // Old parent may need to readjust to missing child
435 if( oldParent->RelayoutDependentOnChildren() )
437 oldParent->RelayoutRequest();
441 // Guard against Add() during previous OnChildRemove callback
444 // Do this first, since user callbacks from within SetParent() may need to remove child
445 mChildren->push_back( ActorPtr( &child ) );
447 // SetParent asserts that child can be added
448 child.SetParent( this );
450 // Notification for derived classes
453 // Only put in a relayout request if there is a suitable dependency
454 if( RelayoutDependentOnChildren() )
462 void Actor::Remove( Actor& child )
464 if( (this == &child) || (!mChildren) )
466 // no children or removing itself
472 // Find the child in mChildren, and unparent it
473 ActorIter end = mChildren->end();
474 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
476 ActorPtr actor = (*iter);
478 if( actor.Get() == &child )
480 // Keep handle for OnChildRemove notification
483 // Do this first, since user callbacks from within SetParent() may need to add the child
484 mChildren->erase( iter );
486 DALI_ASSERT_DEBUG( actor->GetParent() == this );
487 actor->SetParent( NULL );
495 // Only put in a relayout request if there is a suitable dependency
496 if( RelayoutDependentOnChildren() )
502 // Notification for derived classes
503 OnChildRemove( child );
506 void Actor::Unparent()
510 // Remove this actor from the parent. The remove will put a relayout request in for
511 // the parent if required
512 mParent->Remove( *this );
513 // mParent is now NULL!
517 unsigned int Actor::GetChildCount() const
519 return ( NULL != mChildren ) ? mChildren->size() : 0;
522 ActorPtr Actor::GetChildAt( unsigned int index ) const
524 DALI_ASSERT_ALWAYS( index < GetChildCount() );
526 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
529 ActorPtr Actor::FindChildByName( const std::string& actorName )
532 if( actorName == mName )
538 ActorIter end = mChildren->end();
539 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
541 child = (*iter)->FindChildByName( actorName );
552 ActorPtr Actor::FindChildById( const unsigned int id )
561 ActorIter end = mChildren->end();
562 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
564 child = (*iter)->FindChildById( id );
575 void Actor::SetParentOrigin( const Vector3& origin )
579 // mNode is being used in a separate thread; queue a message to set the value & base value
580 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
583 // Cache for event-thread access
586 // not allocated, check if different from default
587 if( ParentOrigin::DEFAULT != origin )
589 mParentOrigin = new Vector3( origin );
594 // check if different from current costs more than just set
595 *mParentOrigin = origin;
599 void Actor::SetParentOriginX( float x )
601 const Vector3& current = GetCurrentParentOrigin();
603 SetParentOrigin( Vector3( x, current.y, current.z ) );
606 void Actor::SetParentOriginY( float y )
608 const Vector3& current = GetCurrentParentOrigin();
610 SetParentOrigin( Vector3( current.x, y, current.z ) );
613 void Actor::SetParentOriginZ( float z )
615 const Vector3& current = GetCurrentParentOrigin();
617 SetParentOrigin( Vector3( current.x, current.y, z ) );
620 const Vector3& Actor::GetCurrentParentOrigin() const
622 // Cached for event-thread access
623 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
626 void Actor::SetAnchorPoint( const Vector3& anchor )
630 // mNode is being used in a separate thread; queue a message to set the value & base value
631 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
634 // Cache for event-thread access
637 // not allocated, check if different from default
638 if( AnchorPoint::DEFAULT != anchor )
640 mAnchorPoint = new Vector3( anchor );
645 // check if different from current costs more than just set
646 *mAnchorPoint = anchor;
650 void Actor::SetAnchorPointX( float x )
652 const Vector3& current = GetCurrentAnchorPoint();
654 SetAnchorPoint( Vector3( x, current.y, current.z ) );
657 void Actor::SetAnchorPointY( float y )
659 const Vector3& current = GetCurrentAnchorPoint();
661 SetAnchorPoint( Vector3( current.x, y, current.z ) );
664 void Actor::SetAnchorPointZ( float z )
666 const Vector3& current = GetCurrentAnchorPoint();
668 SetAnchorPoint( Vector3( current.x, current.y, z ) );
671 const Vector3& Actor::GetCurrentAnchorPoint() const
673 // Cached for event-thread access
674 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
677 void Actor::SetPosition( float x, float y )
679 SetPosition( Vector3( x, y, 0.0f ) );
682 void Actor::SetPosition( float x, float y, float z )
684 SetPosition( Vector3( x, y, z ) );
687 void Actor::SetPosition( const Vector3& position )
689 mTargetPosition = position;
693 // mNode is being used in a separate thread; queue a message to set the value & base value
694 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
698 void Actor::SetX( float x )
700 mTargetPosition.x = x;
704 // mNode is being used in a separate thread; queue a message to set the value & base value
705 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
709 void Actor::SetY( float y )
711 mTargetPosition.y = y;
715 // mNode is being used in a separate thread; queue a message to set the value & base value
716 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
720 void Actor::SetZ( float z )
722 mTargetPosition.z = z;
726 // mNode is being used in a separate thread; queue a message to set the value & base value
727 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
731 void Actor::TranslateBy( const Vector3& distance )
733 mTargetPosition += distance;
737 // mNode is being used in a separate thread; queue a message to set the value & base value
738 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
742 const Vector3& Actor::GetCurrentPosition() const
746 // mNode is being used in a separate thread; copy the value from the previous update
747 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
750 return Vector3::ZERO;
753 const Vector3& Actor::GetTargetPosition() const
755 return mTargetPosition;
758 const Vector3& Actor::GetCurrentWorldPosition() const
762 // mNode is being used in a separate thread; copy the value from the previous update
763 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
766 return Vector3::ZERO;
769 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
771 // this flag is not animatable so keep the value
772 mPositionInheritanceMode = mode;
775 // mNode is being used in a separate thread; queue a message to set the value
776 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
780 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
782 // Cached for event-thread access
783 return mPositionInheritanceMode;
786 void Actor::SetInheritPosition( bool inherit )
788 if( mInheritPosition != inherit && NULL != mNode )
790 // non animateable so keep local copy
791 mInheritPosition = inherit;
792 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
796 bool Actor::IsPositionInherited() const
798 return mInheritPosition;
801 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
803 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
804 normalizedAxis.Normalize();
806 Quaternion orientation( angle, normalizedAxis );
808 SetOrientation( orientation );
811 void Actor::SetOrientation( const Quaternion& orientation )
815 // mNode is being used in a separate thread; queue a message to set the value & base value
816 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
820 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
824 // mNode is being used in a separate thread; queue a message to set the value & base value
825 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
829 void Actor::RotateBy( const Quaternion& relativeRotation )
833 // mNode is being used in a separate thread; queue a message to set the value & base value
834 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
838 const Quaternion& Actor::GetCurrentOrientation() const
842 // mNode is being used in a separate thread; copy the value from the previous update
843 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
846 return Quaternion::IDENTITY;
849 const Quaternion& Actor::GetCurrentWorldOrientation() const
853 // mNode is being used in a separate thread; copy the value from the previous update
854 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
857 return Quaternion::IDENTITY;
860 void Actor::SetScale( float scale )
862 SetScale( Vector3( scale, scale, scale ) );
865 void Actor::SetScale( float x, float y, float z )
867 SetScale( Vector3( x, y, z ) );
870 void Actor::SetScale( const Vector3& scale )
874 // mNode is being used in a separate thread; queue a message to set the value & base value
875 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
879 void Actor::SetScaleX( float x )
883 // mNode is being used in a separate thread; queue a message to set the value & base value
884 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
888 void Actor::SetScaleY( float y )
892 // mNode is being used in a separate thread; queue a message to set the value & base value
893 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
897 void Actor::SetScaleZ( float z )
901 // mNode is being used in a separate thread; queue a message to set the value & base value
902 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
906 void Actor::ScaleBy(const Vector3& relativeScale)
910 // mNode is being used in a separate thread; queue a message to set the value & base value
911 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
915 const Vector3& Actor::GetCurrentScale() const
919 // mNode is being used in a separate thread; copy the value from the previous update
920 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
926 const Vector3& Actor::GetCurrentWorldScale() const
930 // mNode is being used in a separate thread; copy the value from the previous update
931 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
937 void Actor::SetInheritScale( bool inherit )
940 if( mInheritScale != inherit && NULL != mNode )
942 // non animateable so keep local copy
943 mInheritScale = inherit;
944 // mNode is being used in a separate thread; queue a message to set the value
945 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
949 bool Actor::IsScaleInherited() const
951 return mInheritScale;
954 Matrix Actor::GetCurrentWorldMatrix() const
958 return mNode->GetWorldMatrix(0);
961 return Matrix::IDENTITY;
964 void Actor::SetVisible( bool visible )
968 // mNode is being used in a separate thread; queue a message to set the value & base value
969 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
973 bool Actor::IsVisible() const
977 // mNode is being used in a separate thread; copy the value from the previous update
978 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
984 void Actor::SetOpacity( float opacity )
988 // mNode is being used in a separate thread; queue a message to set the value & base value
989 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
993 float Actor::GetCurrentOpacity() const
997 // mNode is being used in a separate thread; copy the value from the previous update
998 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1004 const Vector4& Actor::GetCurrentWorldColor() const
1008 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1011 return Color::WHITE;
1014 void Actor::SetColor( const Vector4& color )
1018 // mNode is being used in a separate thread; queue a message to set the value & base value
1019 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1023 void Actor::SetColorRed( float red )
1027 // mNode is being used in a separate thread; queue a message to set the value & base value
1028 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1032 void Actor::SetColorGreen( float green )
1036 // mNode is being used in a separate thread; queue a message to set the value & base value
1037 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1041 void Actor::SetColorBlue( float blue )
1045 // mNode is being used in a separate thread; queue a message to set the value & base value
1046 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1050 const Vector4& Actor::GetCurrentColor() const
1054 // mNode is being used in a separate thread; copy the value from the previous update
1055 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1058 return Color::WHITE;
1061 void Actor::SetInheritOrientation( bool inherit )
1063 if( mInheritOrientation != inherit && NULL != mNode)
1065 // non animateable so keep local copy
1066 mInheritOrientation = inherit;
1067 // mNode is being used in a separate thread; queue a message to set the value
1068 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1072 bool Actor::IsOrientationInherited() const
1074 return mInheritOrientation;
1077 void Actor::SetSizeModeFactor( const Vector3& factor )
1079 EnsureRelayoutData();
1081 mRelayoutData->sizeModeFactor = factor;
1084 const Vector3& Actor::GetSizeModeFactor() const
1086 if ( mRelayoutData )
1088 return mRelayoutData->sizeModeFactor;
1091 return GetDefaultSizeModeFactor();
1094 void Actor::SetColorMode( ColorMode colorMode )
1096 // non animateable so keep local copy
1097 mColorMode = colorMode;
1100 // mNode is being used in a separate thread; queue a message to set the value
1101 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1105 ColorMode Actor::GetColorMode() const
1107 // we have cached copy
1111 void Actor::SetSize( float width, float height )
1113 SetSize( Vector2( width, height ) );
1116 void Actor::SetSize( float width, float height, float depth )
1118 SetSize( Vector3( width, height, depth ) );
1121 void Actor::SetSize( const Vector2& size )
1123 SetSize( Vector3( size.width, size.height, 0.f ) );
1126 void Actor::SetSizeInternal( const Vector2& size )
1128 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1131 void Actor::SetSize( const Vector3& size )
1133 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1135 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1136 SetPreferredSize( size.GetVectorXY() );
1140 SetSizeInternal( size );
1144 void Actor::SetSizeInternal( const Vector3& size )
1146 // dont allow recursive loop
1147 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1148 // 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
1149 if( ( NULL != mNode )&&
1150 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1151 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1152 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1156 // mNode is being used in a separate thread; queue a message to set the value & base value
1157 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1159 // Notification for derived classes
1160 mInsideOnSizeSet = true;
1161 OnSizeSet( mTargetSize );
1162 mInsideOnSizeSet = false;
1164 // Raise a relayout request if the flag is not locked
1165 if( mRelayoutData && !mRelayoutData->insideRelayout )
1172 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1174 mTargetSize = targetSize;
1176 // Notify deriving classes
1177 OnSizeAnimation( animation, mTargetSize );
1180 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1182 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1184 mTargetSize.width = targetSize;
1186 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1188 mTargetSize.height = targetSize;
1190 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1192 mTargetSize.depth = targetSize;
1194 // Notify deriving classes
1195 OnSizeAnimation( animation, mTargetSize );
1198 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1200 mTargetPosition = targetPosition;
1203 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1205 if ( Dali::Actor::Property::POSITION_X == property )
1207 mTargetPosition.x = targetPosition;
1209 else if ( Dali::Actor::Property::POSITION_Y == property )
1211 mTargetPosition.y = targetPosition;
1213 else if ( Dali::Actor::Property::POSITION_Z == property )
1215 mTargetPosition.z = targetPosition;
1219 void Actor::SetWidth( float width )
1221 mTargetSize.width = width;
1225 // mNode is being used in a separate thread; queue a message to set the value & base value
1226 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1230 void Actor::SetHeight( float height )
1232 mTargetSize.height = height;
1236 // mNode is being used in a separate thread; queue a message to set the value & base value
1237 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1241 void Actor::SetDepth( float depth )
1243 mTargetSize.depth = depth;
1247 // mNode is being used in a separate thread; queue a message to set the value & base value
1248 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1252 const Vector3& Actor::GetTargetSize() const
1257 const Vector3& Actor::GetCurrentSize() const
1261 // mNode is being used in a separate thread; copy the value from the previous update
1262 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1265 return Vector3::ZERO;
1268 Vector3 Actor::GetNaturalSize() const
1270 // It is up to deriving classes to return the appropriate natural size
1271 return Vector3( 0.0f, 0.0f, 0.0f );
1274 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1276 EnsureRelayoutData();
1278 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1280 if( dimension & ( 1 << i ) )
1282 mRelayoutData->resizePolicies[ i ] = policy;
1286 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1288 if( dimension & Dimension::WIDTH )
1290 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1293 if( dimension & Dimension::HEIGHT )
1295 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1299 // If calling SetResizePolicy, assume we want relayout enabled
1300 SetRelayoutEnabled( true );
1302 OnSetResizePolicy( policy, dimension );
1304 // Trigger relayout on this control
1308 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1310 if ( mRelayoutData )
1312 // If more than one dimension is requested, just return the first one found
1313 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1315 if( ( dimension & ( 1 << i ) ) )
1317 return mRelayoutData->resizePolicies[ i ];
1322 return ResizePolicy::DEFAULT;
1325 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1327 EnsureRelayoutData();
1329 mRelayoutData->sizeSetPolicy = policy;
1332 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1334 if ( mRelayoutData )
1336 return mRelayoutData->sizeSetPolicy;
1339 return DEFAULT_SIZE_SCALE_POLICY;
1342 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1344 EnsureRelayoutData();
1346 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1348 if( dimension & ( 1 << i ) )
1350 mRelayoutData->dimensionDependencies[ i ] = dependency;
1355 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1357 if ( mRelayoutData )
1359 // If more than one dimension is requested, just return the first one found
1360 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1362 if( ( dimension & ( 1 << i ) ) )
1364 return mRelayoutData->dimensionDependencies[ i ];
1369 return Dimension::ALL_DIMENSIONS; // Default
1372 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1374 // If relayout data has not been allocated yet and the client is requesting
1375 // to disable it, do nothing
1376 if( mRelayoutData || relayoutEnabled )
1378 EnsureRelayoutData();
1380 mRelayoutData->relayoutEnabled = relayoutEnabled;
1384 bool Actor::IsRelayoutEnabled() const
1386 // Assume that if relayout data has not been allocated yet then
1387 // relayout is disabled
1388 return mRelayoutData && mRelayoutData->relayoutEnabled;
1391 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1393 EnsureRelayoutData();
1395 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1397 if( dimension & ( 1 << i ) )
1399 mRelayoutData->dimensionDirty[ i ] = dirty;
1404 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1406 if ( mRelayoutData )
1408 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1410 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1420 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1422 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1425 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1427 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1430 unsigned int Actor::AddRenderer( Renderer& renderer )
1434 mRenderers = new RendererContainer;
1437 unsigned int index = mRenderers->size();
1438 RendererPtr rendererPtr = RendererPtr( &renderer );
1439 mRenderers->push_back( rendererPtr );
1440 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1444 rendererPtr->Connect();
1450 unsigned int Actor::GetRendererCount() const
1452 unsigned int rendererCount(0);
1455 rendererCount = mRenderers->size();
1458 return rendererCount;
1461 RendererPtr Actor::GetRendererAt( unsigned int index )
1463 RendererPtr renderer;
1464 if( index < GetRendererCount() )
1466 renderer = ( *mRenderers )[ index ];
1472 void Actor::RemoveRenderer( Renderer& renderer )
1476 RendererIter end = mRenderers->end();
1477 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1479 if( (*iter).Get() == &renderer )
1481 mRenderers->erase( iter );
1482 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1489 void Actor::RemoveRenderer( unsigned int index )
1491 if( index < GetRendererCount() )
1493 RendererPtr renderer = ( *mRenderers )[ index ];
1494 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1495 mRenderers->erase( mRenderers->begin()+index );
1499 bool Actor::IsOverlay() const
1501 return ( DrawMode::OVERLAY_2D == mDrawMode );
1504 void Actor::SetDrawMode( DrawMode::Type drawMode )
1506 // this flag is not animatable so keep the value
1507 mDrawMode = drawMode;
1510 // mNode is being used in a separate thread; queue a message to set the value
1511 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1515 DrawMode::Type Actor::GetDrawMode() const
1520 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1522 // only valid when on-stage
1523 StagePtr stage = Stage::GetCurrent();
1524 if( stage && OnStage() )
1526 const RenderTaskList& taskList = stage->GetRenderTaskList();
1528 Vector2 converted( screenX, screenY );
1530 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1531 const int taskCount = taskList.GetTaskCount();
1532 for( int i = taskCount - 1; i >= 0; --i )
1534 Dali::RenderTask task = taskList.GetTask( i );
1535 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1537 // found a task where this conversion was ok so return
1545 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1547 bool retval = false;
1548 // only valid when on-stage
1551 CameraActor* camera = renderTask.GetCameraActor();
1555 renderTask.GetViewport( viewport );
1557 // need to translate coordinates to render tasks coordinate space
1558 Vector2 converted( screenX, screenY );
1559 if( renderTask.TranslateCoordinates( converted ) )
1561 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1568 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1570 // Early-out if mNode is NULL
1576 // Get the ModelView matrix
1578 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1580 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1581 Matrix invertedMvp( false/*don't init*/);
1582 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1583 bool success = invertedMvp.Invert();
1585 // Convert to GL coordinates
1586 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1591 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1598 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1604 if( XyPlaneIntersect( nearPos, farPos, local ) )
1606 Vector3 size = GetCurrentSize();
1607 localX = local.x + size.x * 0.5f;
1608 localY = local.y + size.y * 0.5f;
1619 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1622 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1624 Mathematical Formulation
1626 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1628 ( p - c ) dot ( p - c ) = r^2
1630 Given a ray with a point of origin 'o', and a direction vector 'd':
1632 ray(t) = o + td, t >= 0
1634 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1636 (o + td - c ) dot ( o + td - c ) = r^2
1638 To solve for t we first expand the above into a more recognisable quadratic equation form
1640 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1649 B = 2( o - c ) dot d
1650 C = ( o - c ) dot ( o - c ) - r^2
1652 which can be solved using a standard quadratic formula.
1654 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1656 Practical Simplification
1658 In a renderer, we often differentiate between world space and object space. In the object space
1659 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1660 into object space, the mathematical solution presented above can be simplified significantly.
1662 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1666 and we can find the t at which the (transformed) ray intersects the sphere by
1668 ( o + td ) dot ( o + td ) = r^2
1670 According to the reasoning above, we expand the above quadratic equation into the general form
1674 which now has coefficients:
1681 // Early out if mNode is NULL
1687 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1689 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1690 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1691 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1693 // Compute the radius is not needed, square radius it's enough.
1694 const Vector3& size( mNode->GetSize( bufferIndex ) );
1696 // Scale the sphere.
1697 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1699 const float width = size.width * scale.width;
1700 const float height = size.height * scale.height;
1702 float squareSphereRadius = 0.5f * ( width * width + height * height );
1704 float a = rayDir.Dot( rayDir ); // a
1705 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1706 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1708 return ( b2 * b2 - a * c ) >= 0.f;
1711 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1718 // Transforms the ray to the local reference system.
1719 // Calculate the inverse of Model matrix
1720 Matrix invModelMatrix( false/*don't init*/);
1722 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1723 invModelMatrix = mNode->GetWorldMatrix(0);
1724 invModelMatrix.Invert();
1726 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1727 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1729 // Test with the actor's XY plane (Normal = 0 0 1 1).
1731 float a = -rayOriginLocal.z;
1732 float b = rayDirLocal.z;
1734 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1736 // Ray travels distance * rayDirLocal to intersect with plane.
1739 const Vector3& size = mNode->GetSize( bufferIndex );
1741 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1742 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1744 // Test with the actor's geometry.
1745 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1752 void Actor::SetLeaveRequired( bool required )
1754 mLeaveRequired = required;
1757 bool Actor::GetLeaveRequired() const
1759 return mLeaveRequired;
1762 void Actor::SetKeyboardFocusable( bool focusable )
1764 mKeyboardFocusable = focusable;
1767 bool Actor::IsKeyboardFocusable() const
1769 return mKeyboardFocusable;
1772 bool Actor::GetTouchRequired() const
1774 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1777 bool Actor::GetHoverRequired() const
1779 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1782 bool Actor::GetWheelEventRequired() const
1784 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1787 bool Actor::IsHittable() const
1789 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1792 ActorGestureData& Actor::GetGestureData()
1794 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1795 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1796 if( NULL == mGestureData )
1798 mGestureData = new ActorGestureData;
1800 return *mGestureData;
1803 bool Actor::IsGestureRequred( Gesture::Type type ) const
1805 return mGestureData && mGestureData->IsGestureRequred( type );
1808 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1810 bool consumed = false;
1812 if( !mTouchSignal.Empty() )
1814 Dali::Actor handle( this );
1815 consumed = mTouchSignal.Emit( handle, touch );
1818 if( !mTouchedSignal.Empty() )
1820 Dali::Actor handle( this );
1821 consumed |= mTouchedSignal.Emit( handle, event );
1826 // Notification for derived classes
1827 consumed = OnTouchEvent( event ); // TODO
1833 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1835 bool consumed = false;
1837 if( !mHoveredSignal.Empty() )
1839 Dali::Actor handle( this );
1840 consumed = mHoveredSignal.Emit( handle, event );
1845 // Notification for derived classes
1846 consumed = OnHoverEvent( event );
1852 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1854 bool consumed = false;
1856 if( !mWheelEventSignal.Empty() )
1858 Dali::Actor handle( this );
1859 consumed = mWheelEventSignal.Emit( handle, event );
1864 // Notification for derived classes
1865 consumed = OnWheelEvent( event );
1871 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1873 DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
1874 return mTouchedSignal;
1877 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1879 return mTouchSignal;
1882 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1884 return mHoveredSignal;
1887 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1889 return mWheelEventSignal;
1892 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1894 return mOnStageSignal;
1897 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1899 return mOffStageSignal;
1902 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1904 return mOnRelayoutSignal;
1907 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1909 bool connected( true );
1910 Actor* actor = dynamic_cast< Actor* >( object );
1912 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1914 actor->TouchedSignal().Connect( tracker, functor );
1916 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1918 actor->HoveredSignal().Connect( tracker, functor );
1920 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1922 actor->WheelEventSignal().Connect( tracker, functor );
1924 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1926 actor->OnStageSignal().Connect( tracker, functor );
1928 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1930 actor->OffStageSignal().Connect( tracker, functor );
1932 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1934 actor->OnRelayoutSignal().Connect( tracker, functor );
1936 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1938 actor->TouchSignal().Connect( tracker, functor );
1942 // signalName does not match any signal
1949 Actor::Actor( DerivedType derivedType )
1954 mParentOrigin( NULL ),
1955 mAnchorPoint( NULL ),
1956 mRelayoutData( NULL ),
1957 mGestureData( NULL ),
1958 mTargetSize( 0.0f, 0.0f, 0.0f ),
1960 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1962 mIsRoot( ROOT_LAYER == derivedType ),
1963 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1964 mIsOnStage( false ),
1966 mLeaveRequired( false ),
1967 mKeyboardFocusable( false ),
1968 mDerivedRequiresTouch( false ),
1969 mDerivedRequiresHover( false ),
1970 mDerivedRequiresWheelEvent( false ),
1971 mOnStageSignalled( false ),
1972 mInsideOnSizeSet( false ),
1973 mInheritPosition( true ),
1974 mInheritOrientation( true ),
1975 mInheritScale( true ),
1976 mDrawMode( DrawMode::NORMAL ),
1977 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1978 mColorMode( Node::DEFAULT_COLOR_MODE ),
1979 mIsBatchParent( false )
1983 void Actor::Initialize()
1986 SceneGraph::Node* node = CreateNode();
1988 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
1989 mNode = node; // Keep raw-pointer to Node
1993 GetEventThreadServices().RegisterObject( this );
1998 // Remove mParent pointers from children even if we're destroying core,
1999 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2002 ActorConstIter endIter = mChildren->end();
2003 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2005 (*iter)->SetParent( NULL );
2011 // Guard to allow handle destruction after Core has been destroyed
2012 if( EventThreadServices::IsCoreRunning() )
2016 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2017 mNode = NULL; // Node is about to be destroyed
2020 GetEventThreadServices().UnregisterObject( this );
2023 // Cleanup optional gesture data
2024 delete mGestureData;
2026 // Cleanup optional parent origin and anchor
2027 delete mParentOrigin;
2028 delete mAnchorPoint;
2030 // Delete optional relayout data
2033 delete mRelayoutData;
2037 void Actor::ConnectToStage( unsigned int parentDepth )
2039 // This container is used instead of walking the Actor hierarchy.
2040 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2041 ActorContainer connectionList;
2043 // This stage is atomic i.e. not interrupted by user callbacks.
2044 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2046 // Notify applications about the newly connected actors.
2047 const ActorIter endIter = connectionList.end();
2048 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2050 (*iter)->NotifyStageConnection();
2056 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2058 DALI_ASSERT_ALWAYS( !OnStage() );
2063 ConnectToSceneGraph();
2065 // Notification for internal derived classes
2066 OnStageConnectionInternal();
2068 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2069 connectionList.push_back( ActorPtr( this ) );
2071 // Recursively connect children
2074 ActorConstIter endIter = mChildren->end();
2075 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2077 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2083 * This method is called when the Actor is connected to the Stage.
2084 * The parent must have added its Node to the scene-graph.
2085 * The child must connect its Node to the parent's Node.
2086 * This is recursive; the child calls ConnectToStage() for its children.
2088 void Actor::ConnectToSceneGraph()
2090 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2094 // Reparent Node in next Update
2095 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2098 unsigned int rendererCount( GetRendererCount() );
2099 for( unsigned int i(0); i<rendererCount; ++i )
2101 GetRendererAt(i)->Connect();
2104 // Request relayout on all actors that are added to the scenegraph
2107 // Notification for Object::Observers
2111 void Actor::NotifyStageConnection()
2113 // Actors can be removed (in a callback), before the on-stage stage is reported.
2114 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2115 if( OnStage() && !mOnStageSignalled )
2117 // Notification for external (CustomActor) derived classes
2118 OnStageConnectionExternal( mDepth );
2120 if( !mOnStageSignal.Empty() )
2122 Dali::Actor handle( this );
2123 mOnStageSignal.Emit( handle );
2126 // Guard against Remove during callbacks
2129 mOnStageSignalled = true; // signal required next time Actor is removed
2134 void Actor::DisconnectFromStage()
2136 // This container is used instead of walking the Actor hierachy.
2137 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2138 ActorContainer disconnectionList;
2140 // This stage is atomic i.e. not interrupted by user callbacks
2141 RecursiveDisconnectFromStage( disconnectionList );
2143 // Notify applications about the newly disconnected actors.
2144 const ActorIter endIter = disconnectionList.end();
2145 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2147 (*iter)->NotifyStageDisconnection();
2151 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2153 DALI_ASSERT_ALWAYS( OnStage() );
2155 // Recursively disconnect children
2158 ActorConstIter endIter = mChildren->end();
2159 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2161 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2165 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2166 disconnectionList.push_back( ActorPtr( this ) );
2168 // Notification for internal derived classes
2169 OnStageDisconnectionInternal();
2171 DisconnectFromSceneGraph();
2177 * This method is called by an actor or its parent, before a node removal message is sent.
2178 * This is recursive; the child calls DisconnectFromStage() for its children.
2180 void Actor::DisconnectFromSceneGraph()
2182 // Notification for Object::Observers
2183 OnSceneObjectRemove();
2185 unsigned int rendererCount( GetRendererCount() );
2186 for( unsigned int i(0); i<rendererCount; ++i )
2188 GetRendererAt(i)->Disconnect();
2192 void Actor::NotifyStageDisconnection()
2194 // Actors can be added (in a callback), before the off-stage state is reported.
2195 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2196 // only do this step if there is a stage, i.e. Core is not being shut down
2197 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2199 // Notification for external (CustomeActor) derived classes
2200 OnStageDisconnectionExternal();
2202 if( !mOffStageSignal.Empty() )
2204 Dali::Actor handle( this );
2205 mOffStageSignal.Emit( handle );
2208 // Guard against Add during callbacks
2211 mOnStageSignalled = false; // signal required next time Actor is added
2216 bool Actor::IsNodeConnected() const
2218 bool connected( false );
2220 if( OnStage() && ( NULL != mNode ) )
2222 if( IsRoot() || mNode->GetParent() )
2231 unsigned int Actor::GetDefaultPropertyCount() const
2233 return DEFAULT_PROPERTY_COUNT;
2236 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2238 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2240 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2242 indices.PushBack( i );
2246 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2248 if( index < DEFAULT_PROPERTY_COUNT )
2250 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2256 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2258 Property::Index index = Property::INVALID_INDEX;
2260 // Look for name in default properties
2261 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2263 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2264 if( 0 == name.compare( property->name ) )
2274 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2276 if( index < DEFAULT_PROPERTY_COUNT )
2278 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2284 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2286 if( index < DEFAULT_PROPERTY_COUNT )
2288 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2294 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2296 if( index < DEFAULT_PROPERTY_COUNT )
2298 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2304 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2306 if( index < DEFAULT_PROPERTY_COUNT )
2308 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2311 // index out of range...return Property::NONE
2312 return Property::NONE;
2315 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2319 case Dali::Actor::Property::PARENT_ORIGIN:
2321 Property::Type type = property.GetType();
2322 if( type == Property::VECTOR3 )
2324 SetParentOrigin( property.Get< Vector3 >() );
2326 else if ( type == Property::STRING )
2328 std::string parentOriginString;
2329 property.Get( parentOriginString );
2330 Vector3 parentOrigin;
2331 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2333 SetParentOrigin( parentOrigin );
2339 case Dali::Actor::Property::PARENT_ORIGIN_X:
2341 SetParentOriginX( property.Get< float >() );
2345 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2347 SetParentOriginY( property.Get< float >() );
2351 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2353 SetParentOriginZ( property.Get< float >() );
2357 case Dali::Actor::Property::ANCHOR_POINT:
2359 Property::Type type = property.GetType();
2360 if( type == Property::VECTOR3 )
2362 SetAnchorPoint( property.Get< Vector3 >() );
2364 else if ( type == Property::STRING )
2366 std::string anchorPointString;
2367 property.Get( anchorPointString );
2369 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2371 SetAnchorPoint( anchor );
2377 case Dali::Actor::Property::ANCHOR_POINT_X:
2379 SetAnchorPointX( property.Get< float >() );
2383 case Dali::Actor::Property::ANCHOR_POINT_Y:
2385 SetAnchorPointY( property.Get< float >() );
2389 case Dali::Actor::Property::ANCHOR_POINT_Z:
2391 SetAnchorPointZ( property.Get< float >() );
2395 case Dali::Actor::Property::SIZE:
2397 SetSize( property.Get< Vector3 >() );
2401 case Dali::Actor::Property::SIZE_WIDTH:
2403 SetWidth( property.Get< float >() );
2407 case Dali::Actor::Property::SIZE_HEIGHT:
2409 SetHeight( property.Get< float >() );
2413 case Dali::Actor::Property::SIZE_DEPTH:
2415 SetDepth( property.Get< float >() );
2419 case Dali::Actor::Property::POSITION:
2421 SetPosition( property.Get< Vector3 >() );
2425 case Dali::Actor::Property::POSITION_X:
2427 SetX( property.Get< float >() );
2431 case Dali::Actor::Property::POSITION_Y:
2433 SetY( property.Get< float >() );
2437 case Dali::Actor::Property::POSITION_Z:
2439 SetZ( property.Get< float >() );
2443 case Dali::Actor::Property::ORIENTATION:
2445 SetOrientation( property.Get< Quaternion >() );
2449 case Dali::Actor::Property::SCALE:
2451 SetScale( property.Get< Vector3 >() );
2455 case Dali::Actor::Property::SCALE_X:
2457 SetScaleX( property.Get< float >() );
2461 case Dali::Actor::Property::SCALE_Y:
2463 SetScaleY( property.Get< float >() );
2467 case Dali::Actor::Property::SCALE_Z:
2469 SetScaleZ( property.Get< float >() );
2473 case Dali::Actor::Property::VISIBLE:
2475 SetVisible( property.Get< bool >() );
2479 case Dali::Actor::Property::COLOR:
2481 SetColor( property.Get< Vector4 >() );
2485 case Dali::Actor::Property::COLOR_RED:
2487 SetColorRed( property.Get< float >() );
2491 case Dali::Actor::Property::COLOR_GREEN:
2493 SetColorGreen( property.Get< float >() );
2497 case Dali::Actor::Property::COLOR_BLUE:
2499 SetColorBlue( property.Get< float >() );
2503 case Dali::Actor::Property::COLOR_ALPHA:
2505 SetOpacity( property.Get< float >() );
2509 case Dali::Actor::Property::NAME:
2511 SetName( property.Get< std::string >() );
2515 case Dali::Actor::Property::SENSITIVE:
2517 SetSensitive( property.Get< bool >() );
2521 case Dali::Actor::Property::LEAVE_REQUIRED:
2523 SetLeaveRequired( property.Get< bool >() );
2527 case Dali::Actor::Property::INHERIT_POSITION:
2529 SetInheritPosition( property.Get< bool >() );
2533 case Dali::Actor::Property::INHERIT_ORIENTATION:
2535 SetInheritOrientation( property.Get< bool >() );
2539 case Dali::Actor::Property::INHERIT_SCALE:
2541 SetInheritScale( property.Get< bool >() );
2545 case Dali::Actor::Property::COLOR_MODE:
2548 if ( Scripting::GetEnumeration< ColorMode >( property.Get< std::string >().c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2550 SetColorMode( mode );
2555 case Dali::Actor::Property::POSITION_INHERITANCE:
2557 PositionInheritanceMode mode;
2558 if( Scripting::GetEnumeration< PositionInheritanceMode >( property.Get< std::string >().c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2560 SetPositionInheritanceMode( mode );
2565 case Dali::Actor::Property::DRAW_MODE:
2567 DrawMode::Type mode;
2568 if( Scripting::GetEnumeration< DrawMode::Type >( property.Get< std::string >().c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2570 SetDrawMode( mode );
2575 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2577 SetSizeModeFactor( property.Get< Vector3 >() );
2581 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2583 ResizePolicy::Type type;
2584 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2586 SetResizePolicy( type, Dimension::WIDTH );
2591 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2593 ResizePolicy::Type type;
2594 if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2596 SetResizePolicy( type, Dimension::HEIGHT );
2601 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2603 SizeScalePolicy::Type type;
2604 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2606 SetSizeScalePolicy( type );
2611 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2613 if( property.Get< bool >() )
2615 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2620 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2622 if( property.Get< bool >() )
2624 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2629 case Dali::Actor::Property::PADDING:
2631 Vector4 padding = property.Get< Vector4 >();
2632 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2633 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2637 case Dali::Actor::Property::MINIMUM_SIZE:
2639 Vector2 size = property.Get< Vector2 >();
2640 SetMinimumSize( size.x, Dimension::WIDTH );
2641 SetMinimumSize( size.y, Dimension::HEIGHT );
2645 case Dali::Actor::Property::MAXIMUM_SIZE:
2647 Vector2 size = property.Get< Vector2 >();
2648 SetMaximumSize( size.x, Dimension::WIDTH );
2649 SetMaximumSize( size.y, Dimension::HEIGHT );
2653 case Dali::Actor::Property::BATCH_PARENT:
2657 if( property.Get( value ) )
2659 if( value != mIsBatchParent )
2661 mIsBatchParent = value;
2662 SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
2669 // this can happen in the case of a non-animatable default property so just do nothing
2675 // TODO: This method needs to be removed
2676 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2678 switch( entry.GetType() )
2680 case Property::BOOLEAN:
2682 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2683 DALI_ASSERT_DEBUG( NULL != property );
2685 // property is being used in a separate thread; queue a message to set the property
2686 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2691 case Property::INTEGER:
2693 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2694 DALI_ASSERT_DEBUG( NULL != property );
2696 // property is being used in a separate thread; queue a message to set the property
2697 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2702 case Property::FLOAT:
2704 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2705 DALI_ASSERT_DEBUG( NULL != property );
2707 // property is being used in a separate thread; queue a message to set the property
2708 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2713 case Property::VECTOR2:
2715 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2716 DALI_ASSERT_DEBUG( NULL != property );
2718 // property is being used in a separate thread; queue a message to set the property
2719 if(entry.componentIndex == 0)
2721 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2723 else if(entry.componentIndex == 1)
2725 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2729 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2735 case Property::VECTOR3:
2737 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2738 DALI_ASSERT_DEBUG( NULL != property );
2740 // property is being used in a separate thread; queue a message to set the property
2741 if(entry.componentIndex == 0)
2743 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2745 else if(entry.componentIndex == 1)
2747 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2749 else if(entry.componentIndex == 2)
2751 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2755 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2761 case Property::VECTOR4:
2763 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2764 DALI_ASSERT_DEBUG( NULL != property );
2766 // property is being used in a separate thread; queue a message to set the property
2767 if(entry.componentIndex == 0)
2769 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2771 else if(entry.componentIndex == 1)
2773 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2775 else if(entry.componentIndex == 2)
2777 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2779 else if(entry.componentIndex == 3)
2781 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2785 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2791 case Property::ROTATION:
2793 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2794 DALI_ASSERT_DEBUG( NULL != property );
2796 // property is being used in a separate thread; queue a message to set the property
2797 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2802 case Property::MATRIX:
2804 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2805 DALI_ASSERT_DEBUG( NULL != property );
2807 // property is being used in a separate thread; queue a message to set the property
2808 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2813 case Property::MATRIX3:
2815 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2816 DALI_ASSERT_DEBUG( NULL != property );
2818 // property is being used in a separate thread; queue a message to set the property
2819 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2826 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2832 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2834 Property::Value value;
2838 case Dali::Actor::Property::PARENT_ORIGIN:
2840 value = GetCurrentParentOrigin();
2844 case Dali::Actor::Property::PARENT_ORIGIN_X:
2846 value = GetCurrentParentOrigin().x;
2850 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2852 value = GetCurrentParentOrigin().y;
2856 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2858 value = GetCurrentParentOrigin().z;
2862 case Dali::Actor::Property::ANCHOR_POINT:
2864 value = GetCurrentAnchorPoint();
2868 case Dali::Actor::Property::ANCHOR_POINT_X:
2870 value = GetCurrentAnchorPoint().x;
2874 case Dali::Actor::Property::ANCHOR_POINT_Y:
2876 value = GetCurrentAnchorPoint().y;
2880 case Dali::Actor::Property::ANCHOR_POINT_Z:
2882 value = GetCurrentAnchorPoint().z;
2886 case Dali::Actor::Property::SIZE:
2888 value = GetTargetSize();
2892 case Dali::Actor::Property::SIZE_WIDTH:
2894 value = GetTargetSize().width;
2898 case Dali::Actor::Property::SIZE_HEIGHT:
2900 value = GetTargetSize().height;
2904 case Dali::Actor::Property::SIZE_DEPTH:
2906 value = GetTargetSize().depth;
2910 case Dali::Actor::Property::POSITION:
2912 value = GetTargetPosition();
2916 case Dali::Actor::Property::POSITION_X:
2918 value = GetTargetPosition().x;
2922 case Dali::Actor::Property::POSITION_Y:
2924 value = GetTargetPosition().y;
2928 case Dali::Actor::Property::POSITION_Z:
2930 value = GetTargetPosition().z;
2934 case Dali::Actor::Property::WORLD_POSITION:
2936 value = GetCurrentWorldPosition();
2940 case Dali::Actor::Property::WORLD_POSITION_X:
2942 value = GetCurrentWorldPosition().x;
2946 case Dali::Actor::Property::WORLD_POSITION_Y:
2948 value = GetCurrentWorldPosition().y;
2952 case Dali::Actor::Property::WORLD_POSITION_Z:
2954 value = GetCurrentWorldPosition().z;
2958 case Dali::Actor::Property::ORIENTATION:
2960 value = GetCurrentOrientation();
2964 case Dali::Actor::Property::WORLD_ORIENTATION:
2966 value = GetCurrentWorldOrientation();
2970 case Dali::Actor::Property::SCALE:
2972 value = GetCurrentScale();
2976 case Dali::Actor::Property::SCALE_X:
2978 value = GetCurrentScale().x;
2982 case Dali::Actor::Property::SCALE_Y:
2984 value = GetCurrentScale().y;
2988 case Dali::Actor::Property::SCALE_Z:
2990 value = GetCurrentScale().z;
2994 case Dali::Actor::Property::WORLD_SCALE:
2996 value = GetCurrentWorldScale();
3000 case Dali::Actor::Property::VISIBLE:
3002 value = IsVisible();
3006 case Dali::Actor::Property::COLOR:
3008 value = GetCurrentColor();
3012 case Dali::Actor::Property::COLOR_RED:
3014 value = GetCurrentColor().r;
3018 case Dali::Actor::Property::COLOR_GREEN:
3020 value = GetCurrentColor().g;
3024 case Dali::Actor::Property::COLOR_BLUE:
3026 value = GetCurrentColor().b;
3030 case Dali::Actor::Property::COLOR_ALPHA:
3032 value = GetCurrentColor().a;
3036 case Dali::Actor::Property::WORLD_COLOR:
3038 value = GetCurrentWorldColor();
3042 case Dali::Actor::Property::WORLD_MATRIX:
3044 value = GetCurrentWorldMatrix();
3048 case Dali::Actor::Property::NAME:
3054 case Dali::Actor::Property::SENSITIVE:
3056 value = IsSensitive();
3060 case Dali::Actor::Property::LEAVE_REQUIRED:
3062 value = GetLeaveRequired();
3066 case Dali::Actor::Property::INHERIT_POSITION:
3068 value = IsPositionInherited();
3072 case Dali::Actor::Property::INHERIT_ORIENTATION:
3074 value = IsOrientationInherited();
3078 case Dali::Actor::Property::INHERIT_SCALE:
3080 value = IsScaleInherited();
3084 case Dali::Actor::Property::COLOR_MODE:
3086 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3090 case Dali::Actor::Property::POSITION_INHERITANCE:
3092 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3096 case Dali::Actor::Property::DRAW_MODE:
3098 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3102 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3104 value = GetSizeModeFactor();
3108 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3110 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3114 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3116 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3120 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3122 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3126 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3128 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3132 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3134 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3138 case Dali::Actor::Property::PADDING:
3140 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3141 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3142 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3146 case Dali::Actor::Property::MINIMUM_SIZE:
3148 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3152 case Dali::Actor::Property::MAXIMUM_SIZE:
3154 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3158 case Dali::Actor::Property::BATCH_PARENT:
3160 value = mIsBatchParent;
3166 DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
3174 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3179 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3181 // This method should only return an object connected to the scene-graph
3182 return OnStage() ? mNode : NULL;
3185 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3187 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3189 const PropertyBase* property( NULL );
3191 // This method should only return a property of an object connected to the scene-graph
3197 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3199 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3200 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3202 property = animatable->GetSceneGraphProperty();
3204 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3205 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3207 CustomPropertyMetadata* custom = FindCustomProperty( index );
3208 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3210 property = custom->GetSceneGraphProperty();
3212 else if( NULL != mNode )
3216 case Dali::Actor::Property::SIZE:
3217 property = &mNode->mSize;
3220 case Dali::Actor::Property::SIZE_WIDTH:
3221 property = &mNode->mSize;
3224 case Dali::Actor::Property::SIZE_HEIGHT:
3225 property = &mNode->mSize;
3228 case Dali::Actor::Property::SIZE_DEPTH:
3229 property = &mNode->mSize;
3232 case Dali::Actor::Property::POSITION:
3233 property = &mNode->mPosition;
3236 case Dali::Actor::Property::POSITION_X:
3237 property = &mNode->mPosition;
3240 case Dali::Actor::Property::POSITION_Y:
3241 property = &mNode->mPosition;
3244 case Dali::Actor::Property::POSITION_Z:
3245 property = &mNode->mPosition;
3248 case Dali::Actor::Property::ORIENTATION:
3249 property = &mNode->mOrientation;
3252 case Dali::Actor::Property::SCALE:
3253 property = &mNode->mScale;
3256 case Dali::Actor::Property::SCALE_X:
3257 property = &mNode->mScale;
3260 case Dali::Actor::Property::SCALE_Y:
3261 property = &mNode->mScale;
3264 case Dali::Actor::Property::SCALE_Z:
3265 property = &mNode->mScale;
3268 case Dali::Actor::Property::VISIBLE:
3269 property = &mNode->mVisible;
3272 case Dali::Actor::Property::COLOR:
3273 property = &mNode->mColor;
3276 case Dali::Actor::Property::COLOR_RED:
3277 property = &mNode->mColor;
3280 case Dali::Actor::Property::COLOR_GREEN:
3281 property = &mNode->mColor;
3284 case Dali::Actor::Property::COLOR_BLUE:
3285 property = &mNode->mColor;
3288 case Dali::Actor::Property::COLOR_ALPHA:
3289 property = &mNode->mColor;
3300 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3302 const PropertyInputImpl* property( NULL );
3304 // This method should only return a property of an object connected to the scene-graph
3310 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3312 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3313 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3315 property = animatable->GetSceneGraphProperty();
3317 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3318 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3320 CustomPropertyMetadata* custom = FindCustomProperty( index );
3321 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3322 property = custom->GetSceneGraphProperty();
3324 else if( NULL != mNode )
3328 case Dali::Actor::Property::PARENT_ORIGIN:
3329 property = &mNode->mParentOrigin;
3332 case Dali::Actor::Property::PARENT_ORIGIN_X:
3333 property = &mNode->mParentOrigin;
3336 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3337 property = &mNode->mParentOrigin;
3340 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3341 property = &mNode->mParentOrigin;
3344 case Dali::Actor::Property::ANCHOR_POINT:
3345 property = &mNode->mAnchorPoint;
3348 case Dali::Actor::Property::ANCHOR_POINT_X:
3349 property = &mNode->mAnchorPoint;
3352 case Dali::Actor::Property::ANCHOR_POINT_Y:
3353 property = &mNode->mAnchorPoint;
3356 case Dali::Actor::Property::ANCHOR_POINT_Z:
3357 property = &mNode->mAnchorPoint;
3360 case Dali::Actor::Property::SIZE:
3361 property = &mNode->mSize;
3364 case Dali::Actor::Property::SIZE_WIDTH:
3365 property = &mNode->mSize;
3368 case Dali::Actor::Property::SIZE_HEIGHT:
3369 property = &mNode->mSize;
3372 case Dali::Actor::Property::SIZE_DEPTH:
3373 property = &mNode->mSize;
3376 case Dali::Actor::Property::POSITION:
3377 property = &mNode->mPosition;
3380 case Dali::Actor::Property::POSITION_X:
3381 property = &mNode->mPosition;
3384 case Dali::Actor::Property::POSITION_Y:
3385 property = &mNode->mPosition;
3388 case Dali::Actor::Property::POSITION_Z:
3389 property = &mNode->mPosition;
3392 case Dali::Actor::Property::WORLD_POSITION:
3393 property = &mNode->mWorldPosition;
3396 case Dali::Actor::Property::WORLD_POSITION_X:
3397 property = &mNode->mWorldPosition;
3400 case Dali::Actor::Property::WORLD_POSITION_Y:
3401 property = &mNode->mWorldPosition;
3404 case Dali::Actor::Property::WORLD_POSITION_Z:
3405 property = &mNode->mWorldPosition;
3408 case Dali::Actor::Property::ORIENTATION:
3409 property = &mNode->mOrientation;
3412 case Dali::Actor::Property::WORLD_ORIENTATION:
3413 property = &mNode->mWorldOrientation;
3416 case Dali::Actor::Property::SCALE:
3417 property = &mNode->mScale;
3420 case Dali::Actor::Property::SCALE_X:
3421 property = &mNode->mScale;
3424 case Dali::Actor::Property::SCALE_Y:
3425 property = &mNode->mScale;
3428 case Dali::Actor::Property::SCALE_Z:
3429 property = &mNode->mScale;
3432 case Dali::Actor::Property::WORLD_SCALE:
3433 property = &mNode->mWorldScale;
3436 case Dali::Actor::Property::VISIBLE:
3437 property = &mNode->mVisible;
3440 case Dali::Actor::Property::COLOR:
3441 property = &mNode->mColor;
3444 case Dali::Actor::Property::COLOR_RED:
3445 property = &mNode->mColor;
3448 case Dali::Actor::Property::COLOR_GREEN:
3449 property = &mNode->mColor;
3452 case Dali::Actor::Property::COLOR_BLUE:
3453 property = &mNode->mColor;
3456 case Dali::Actor::Property::COLOR_ALPHA:
3457 property = &mNode->mColor;
3460 case Dali::Actor::Property::WORLD_COLOR:
3461 property = &mNode->mWorldColor;
3464 case Dali::Actor::Property::WORLD_MATRIX:
3465 property = &mNode->mWorldMatrix;
3476 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3478 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3480 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3482 // check whether the animatable property is registered already, if not then register one.
3483 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3484 if( animatableProperty )
3486 componentIndex = animatableProperty->componentIndex;
3493 case Dali::Actor::Property::PARENT_ORIGIN_X:
3494 case Dali::Actor::Property::ANCHOR_POINT_X:
3495 case Dali::Actor::Property::SIZE_WIDTH:
3496 case Dali::Actor::Property::POSITION_X:
3497 case Dali::Actor::Property::WORLD_POSITION_X:
3498 case Dali::Actor::Property::SCALE_X:
3499 case Dali::Actor::Property::COLOR_RED:
3505 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3506 case Dali::Actor::Property::ANCHOR_POINT_Y:
3507 case Dali::Actor::Property::SIZE_HEIGHT:
3508 case Dali::Actor::Property::POSITION_Y:
3509 case Dali::Actor::Property::WORLD_POSITION_Y:
3510 case Dali::Actor::Property::SCALE_Y:
3511 case Dali::Actor::Property::COLOR_GREEN:
3517 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3518 case Dali::Actor::Property::ANCHOR_POINT_Z:
3519 case Dali::Actor::Property::SIZE_DEPTH:
3520 case Dali::Actor::Property::POSITION_Z:
3521 case Dali::Actor::Property::WORLD_POSITION_Z:
3522 case Dali::Actor::Property::SCALE_Z:
3523 case Dali::Actor::Property::COLOR_BLUE:
3529 case Dali::Actor::Property::COLOR_ALPHA:
3543 return componentIndex;
3546 void Actor::SetParent( Actor* parent )
3550 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3554 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3557 // Instruct each actor to create a corresponding node in the scene graph
3558 ConnectToStage( parent->GetHierarchyDepth() );
3561 // Resolve the name and index for the child properties if any
3562 ResolveChildProperties();
3564 else // parent being set to NULL
3566 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3570 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3573 DALI_ASSERT_ALWAYS( mNode != NULL );
3577 // Disconnect the Node & its children from the scene-graph.
3578 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3581 // Instruct each actor to discard pointers to the scene-graph
3582 DisconnectFromStage();
3587 SceneGraph::Node* Actor::CreateNode() const
3592 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3595 Actor* actor = dynamic_cast< Actor* >( object );
3599 if( 0 == actionName.compare( ACTION_SHOW ) )
3601 actor->SetVisible( true );
3604 else if( 0 == actionName.compare( ACTION_HIDE ) )
3606 actor->SetVisible( false );
3614 void Actor::EnsureRelayoutData()
3616 // Assign relayout data.
3617 if( !mRelayoutData )
3619 mRelayoutData = new RelayoutData();
3623 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3625 // Check if actor is dependent on parent
3626 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3628 if( ( dimension & ( 1 << i ) ) )
3630 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3631 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3641 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3643 // Check if actor is dependent on children
3644 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3646 if( ( dimension & ( 1 << i ) ) )
3648 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3649 switch( resizePolicy )
3651 case ResizePolicy::FIT_TO_CHILDREN:
3652 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3668 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3670 return Actor::RelayoutDependentOnChildren( dimension );
3673 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3675 // Check each possible dimension and see if it is dependent on the input one
3676 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3678 if( dimension & ( 1 << i ) )
3680 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3687 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3689 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3691 if( dimension & ( 1 << i ) )
3693 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3698 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3700 // If more than one dimension is requested, just return the first one found
3701 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3703 if( ( dimension & ( 1 << i ) ) )
3705 return mRelayoutData->negotiatedDimensions[ i ];
3709 return 0.0f; // Default
3712 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3714 EnsureRelayoutData();
3716 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3718 if( dimension & ( 1 << i ) )
3720 mRelayoutData->dimensionPadding[ i ] = padding;
3725 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3727 if ( mRelayoutData )
3729 // If more than one dimension is requested, just return the first one found
3730 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3732 if( ( dimension & ( 1 << i ) ) )
3734 return mRelayoutData->dimensionPadding[ i ];
3739 return GetDefaultDimensionPadding();
3742 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3744 EnsureRelayoutData();
3746 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3748 if( dimension & ( 1 << i ) )
3750 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3755 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3757 if ( mRelayoutData )
3759 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3761 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3771 float Actor::GetHeightForWidthBase( float width )
3773 float height = 0.0f;
3775 const Vector3 naturalSize = GetNaturalSize();
3776 if( naturalSize.width > 0.0f )
3778 height = naturalSize.height * width / naturalSize.width;
3780 else // we treat 0 as 1:1 aspect ratio
3788 float Actor::GetWidthForHeightBase( float height )
3792 const Vector3 naturalSize = GetNaturalSize();
3793 if( naturalSize.height > 0.0f )
3795 width = naturalSize.width * height / naturalSize.height;
3797 else // we treat 0 as 1:1 aspect ratio
3805 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3807 // Fill to parent, taking size mode factor into account
3808 switch( child.GetResizePolicy( dimension ) )
3810 case ResizePolicy::FILL_TO_PARENT:
3812 return GetLatestSize( dimension );
3815 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3817 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3820 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3822 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3827 return GetLatestSize( dimension );
3832 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
3834 // Can be overridden in derived class
3835 return CalculateChildSizeBase( child, dimension );
3838 float Actor::GetHeightForWidth( float width )
3840 // Can be overridden in derived class
3841 return GetHeightForWidthBase( width );
3844 float Actor::GetWidthForHeight( float height )
3846 // Can be overridden in derived class
3847 return GetWidthForHeightBase( height );
3850 float Actor::GetLatestSize( Dimension::Type dimension ) const
3852 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
3855 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
3857 Vector2 padding = GetPadding( dimension );
3859 return GetLatestSize( dimension ) + padding.x + padding.y;
3862 float Actor::NegotiateFromParent( Dimension::Type dimension )
3864 Actor* parent = GetParent();
3867 Vector2 padding( GetPadding( dimension ) );
3868 Vector2 parentPadding( parent->GetPadding( dimension ) );
3869 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
3875 float Actor::NegotiateFromChildren( Dimension::Type dimension )
3877 float maxDimensionPoint = 0.0f;
3879 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
3881 ActorPtr child = GetChildAt( i );
3883 if( !child->RelayoutDependentOnParent( dimension ) )
3885 // Calculate the min and max points that the children range across
3886 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
3887 float dimensionSize = child->GetRelayoutSize( dimension );
3888 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
3892 return maxDimensionPoint;
3895 float Actor::GetSize( Dimension::Type dimension ) const
3897 return GetDimensionValue( GetTargetSize(), dimension );
3900 float Actor::GetNaturalSize( Dimension::Type dimension ) const
3902 return GetDimensionValue( GetNaturalSize(), dimension );
3905 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
3907 switch( GetResizePolicy( dimension ) )
3909 case ResizePolicy::USE_NATURAL_SIZE:
3911 return GetNaturalSize( dimension );
3914 case ResizePolicy::FIXED:
3916 return GetDimensionValue( GetPreferredSize(), dimension );
3919 case ResizePolicy::USE_ASSIGNED_SIZE:
3921 return GetDimensionValue( maximumSize, dimension );
3924 case ResizePolicy::FILL_TO_PARENT:
3925 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3926 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3928 return NegotiateFromParent( dimension );
3931 case ResizePolicy::FIT_TO_CHILDREN:
3933 return NegotiateFromChildren( dimension );
3936 case ResizePolicy::DIMENSION_DEPENDENCY:
3938 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
3941 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
3943 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
3946 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
3948 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
3960 return 0.0f; // Default
3963 float Actor::ClampDimension( float size, Dimension::Type dimension )
3965 const float minSize = GetMinimumSize( dimension );
3966 const float maxSize = GetMaximumSize( dimension );
3968 return std::max( minSize, std::min( size, maxSize ) );
3971 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
3973 // Check if it needs to be negotiated
3974 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
3976 // Check that we havn't gotten into an infinite loop
3977 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
3978 bool recursionFound = false;
3979 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
3981 if( *it == searchActor )
3983 recursionFound = true;
3988 if( !recursionFound )
3990 // Record the path that we have taken
3991 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
3993 // Dimension dependency check
3994 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3996 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
3998 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4000 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4004 // Parent dependency check
4005 Actor* parent = GetParent();
4006 if( parent && RelayoutDependentOnParent( dimension ) )
4008 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4011 // Children dependency check
4012 if( RelayoutDependentOnChildren( dimension ) )
4014 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4016 ActorPtr child = GetChildAt( i );
4018 // Only relayout child first if it is not dependent on this actor
4019 if( !child->RelayoutDependentOnParent( dimension ) )
4021 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4026 // For deriving classes
4027 OnCalculateRelayoutSize( dimension );
4029 // All dependencies checked, calculate the size and set negotiated flag
4030 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4032 SetNegotiatedDimension( newSize, dimension );
4033 SetLayoutNegotiated( true, dimension );
4035 // For deriving classes
4036 OnLayoutNegotiated( newSize, dimension );
4038 // This actor has been successfully processed, pop it off the recursion stack
4039 recursionStack.pop_back();
4043 // TODO: Break infinite loop
4044 SetLayoutNegotiated( true, dimension );
4049 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4051 // Negotiate all dimensions that require it
4052 ActorDimensionStack recursionStack;
4054 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4056 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4059 NegotiateDimension( dimension, allocatedSize, recursionStack );
4063 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4065 switch( mRelayoutData->sizeSetPolicy )
4067 case SizeScalePolicy::USE_SIZE_SET:
4072 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4074 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4075 const Vector3 naturalSize = GetNaturalSize();
4076 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4078 const float sizeRatio = size.width / size.height;
4079 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4081 if( naturalSizeRatio < sizeRatio )
4083 return Vector2( naturalSizeRatio * size.height, size.height );
4085 else if( naturalSizeRatio > sizeRatio )
4087 return Vector2( size.width, size.width / naturalSizeRatio );
4098 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4100 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
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( size.width, size.width / naturalSizeRatio );
4111 else if( naturalSizeRatio > sizeRatio )
4113 return Vector2( naturalSizeRatio * size.height, size.height );
4132 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4134 // Do the set actor size
4135 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4137 // Adjust for size set policy
4138 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4140 // Lock the flag to stop recursive relayouts on set size
4141 mRelayoutData->insideRelayout = true;
4142 SetSize( negotiatedSize );
4143 mRelayoutData->insideRelayout = false;
4145 // Clear flags for all dimensions
4146 SetLayoutDirty( false );
4148 // Give deriving classes a chance to respond
4149 OnRelayout( negotiatedSize, container );
4151 if( !mOnRelayoutSignal.Empty() )
4153 Dali::Actor handle( this );
4154 mOnRelayoutSignal.Emit( handle );
4158 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4160 // Force a size negotiation for actors that has assigned size during relayout
4161 // This is required as otherwise the flags that force a relayout will not
4162 // necessarilly be set. This will occur if the actor has already been laid out.
4163 // The dirty flags are then cleared. Then if the actor is added back into the
4164 // relayout container afterwards, the dirty flags would still be clear...
4165 // causing a relayout to be skipped. Here we force any actors added to the
4166 // container to be relayed out.
4167 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4169 SetLayoutNegotiated(false, Dimension::WIDTH);
4171 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4173 SetLayoutNegotiated(false, Dimension::HEIGHT);
4176 // Do the negotiation
4177 NegotiateDimensions( allocatedSize );
4179 // Set the actor size
4180 SetNegotiatedSize( container );
4182 // Negotiate down to children
4183 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4185 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4187 ActorPtr child = GetChildAt( i );
4189 // Forces children that have already been laid out to be relayed out
4190 // if they have assigned size during relayout.
4191 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4193 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4194 child->SetLayoutDirty(true, Dimension::WIDTH);
4196 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4198 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4199 child->SetLayoutDirty(true, Dimension::HEIGHT);
4202 // Only relayout if required
4203 if( child->RelayoutRequired() )
4205 container.Add( Dali::Actor( child.Get() ), newBounds );
4210 void Actor::RelayoutRequest( Dimension::Type dimension )
4212 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4213 if( relayoutController )
4215 Dali::Actor self( this );
4216 relayoutController->RequestRelayout( self, dimension );
4220 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4224 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4228 void Actor::SetPreferredSize( const Vector2& size )
4230 EnsureRelayoutData();
4232 if( size.width > 0.0f )
4234 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4237 if( size.height > 0.0f )
4239 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4242 mRelayoutData->preferredSize = size;
4247 Vector2 Actor::GetPreferredSize() const
4249 if ( mRelayoutData )
4251 return Vector2( mRelayoutData->preferredSize );
4254 return GetDefaultPreferredSize();
4257 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4259 EnsureRelayoutData();
4261 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4263 if( dimension & ( 1 << i ) )
4265 mRelayoutData->minimumSize[ i ] = size;
4272 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4274 if ( mRelayoutData )
4276 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4278 if( dimension & ( 1 << i ) )
4280 return mRelayoutData->minimumSize[ i ];
4285 return 0.0f; // Default
4288 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4290 EnsureRelayoutData();
4292 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4294 if( dimension & ( 1 << i ) )
4296 mRelayoutData->maximumSize[ i ] = size;
4303 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4305 if ( mRelayoutData )
4307 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4309 if( dimension & ( 1 << i ) )
4311 return mRelayoutData->maximumSize[ i ];
4316 return FLT_MAX; // Default
4319 Object* Actor::GetParentObject() const
4324 } // namespace Internal