2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/common/animatable-property.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/nodes/node-declarations.h>
51 #include <dali/internal/update/animation/scene-graph-constraint.h>
52 #include <dali/internal/event/events/actor-gesture-data.h>
53 #include <dali/internal/common/message.h>
54 #include <dali/integration-api/debug.h>
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::PropertyBase;
66 unsigned int Actor::mActorCounter = 0;
70 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
71 inline const Vector3& GetDefaultSizeModeFactor()
76 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
77 inline const Vector2& GetDefaultPreferredSize()
82 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
83 inline const Vector2& GetDefaultDimensionPadding()
88 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
90 int GetSiblingOrder( ActorPtr actor )
92 Property::Value value = actor->GetProperty(Dali::DevelActor::Property::SIBLING_ORDER );
98 bool ValidateActors( const Internal::Actor& actor, const Internal::Actor& target )
100 bool validTarget = true;
102 if( &actor == &target )
104 DALI_LOG_WARNING( "Source actor and target actor can not be the same, Sibling order not changed.\n" );
107 else if( actor.GetParent() != target.GetParent() )
109 DALI_LOG_WARNING( "Source actor and target actor need to have common parent, Sibling order not changed.\n" );
116 } // unnamed namespace
119 * Struct to collect relayout variables
121 struct Actor::RelayoutData
124 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
126 // Set size negotiation defaults
127 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
129 resizePolicies[ i ] = ResizePolicy::DEFAULT;
130 negotiatedDimensions[ i ] = 0.0f;
131 dimensionNegotiated[ i ] = false;
132 dimensionDirty[ i ] = false;
133 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
134 dimensionPadding[ i ] = GetDefaultDimensionPadding();
135 minimumSize[ i ] = 0.0f;
136 maximumSize[ i ] = FLT_MAX;
140 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
142 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
144 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
146 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
148 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
149 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
151 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
152 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
154 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
156 Vector2 preferredSize; ///< The preferred size of the actor
158 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
160 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
161 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
164 namespace // unnamed namespace
170 * We want to discourage the use of property strings (minimize string comparisons),
171 * particularly for the default properties.
172 * Name Type writable animatable constraint-input enum for index-checking
174 DALI_PROPERTY_TABLE_BEGIN
175 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
176 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
177 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
178 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
179 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
180 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
181 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
182 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
183 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
184 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
185 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
186 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
187 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
188 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
189 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
190 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
191 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
192 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
193 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
194 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
195 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
196 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
197 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
198 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
199 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
200 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
201 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
202 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
203 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
204 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
205 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
206 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
207 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
208 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
209 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
210 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
211 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
212 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
213 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
214 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
215 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
216 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
217 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
218 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
219 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
220 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
221 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
222 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
223 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
224 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
225 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
226 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
227 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
228 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
229 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
230 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
231 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
232 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
233 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
237 const char* const SIGNAL_TOUCHED = "touched";
238 const char* const SIGNAL_HOVERED = "hovered";
239 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
240 const char* const SIGNAL_ON_STAGE = "onStage";
241 const char* const SIGNAL_OFF_STAGE = "offStage";
242 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
243 const char* const SIGNAL_TOUCH = "touch";
247 const char* const ACTION_SHOW = "show";
248 const char* const ACTION_HIDE = "hide";
250 BaseHandle CreateActor()
252 return Dali::Actor::New();
255 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
257 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
258 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
259 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
260 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
261 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
262 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
263 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
265 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
266 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
271 const Vector3& value;
274 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
276 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
284 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
286 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
287 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
288 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
289 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
290 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
291 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
293 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
294 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
295 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
296 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
297 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
298 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
300 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
304 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
306 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
307 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
310 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
311 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
312 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
315 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
317 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
318 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
319 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
320 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
321 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
323 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
324 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
325 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
326 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
329 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
331 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
333 size_t sizeIgnored = 0;
334 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
336 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
343 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
345 // Values are the same so just use the same table as anchor-point
346 return GetAnchorPointConstant( value, parentOrigin );
350 * @brief Extract a given dimension from a Vector2
352 * @param[in] values The values to extract from
353 * @param[in] dimension The dimension to extract
354 * @return Return the value for the dimension
356 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
360 case Dimension::WIDTH:
364 case Dimension::HEIGHT:
366 return values.height;
377 * @brief Extract a given dimension from a Vector3
379 * @param[in] values The values to extract from
380 * @param[in] dimension The dimension to extract
381 * @return Return the value for the dimension
383 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
385 return GetDimensionValue( values.GetVectorXY(), dimension );
388 unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder )
390 return depth * Dali::DevelLayer::ACTOR_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
393 } // unnamed namespace
395 ActorPtr Actor::New()
397 ActorPtr actor( new Actor( BASIC ) );
399 // Second-phase construction
405 const std::string& Actor::GetName() const
410 void Actor::SetName( const std::string& name )
416 // ATTENTION: string for debug purposes is not thread safe.
417 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
421 unsigned int Actor::GetId() const
426 bool Actor::OnStage() const
431 Dali::Layer Actor::GetLayer()
435 // Short-circuit for Layer derived actors
438 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
441 // Find the immediate Layer parent
442 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
444 if( parent->IsLayer() )
446 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
453 void Actor::Add( Actor& child )
455 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
456 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
460 mChildren = new ActorContainer;
463 Actor* const oldParent( child.mParent );
465 // child might already be ours
466 if( this != oldParent )
468 // if we already have parent, unparent us first
471 oldParent->Remove( child ); // This causes OnChildRemove callback
473 // Old parent may need to readjust to missing child
474 if( oldParent->RelayoutDependentOnChildren() )
476 oldParent->RelayoutRequest();
480 // Guard against Add() during previous OnChildRemove callback
483 // Do this first, since user callbacks from within SetParent() may need to remove child
484 mChildren->push_back( ActorPtr( &child ) );
486 // SetParent asserts that child can be added
487 child.SetParent( this );
489 // Notification for derived classes
492 // Only put in a relayout request if there is a suitable dependency
493 if( RelayoutDependentOnChildren() )
501 void Actor::Remove( Actor& child )
503 if( (this == &child) || (!mChildren) )
505 // no children or removing itself
511 // Find the child in mChildren, and unparent it
512 ActorIter end = mChildren->end();
513 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
515 ActorPtr actor = (*iter);
517 if( actor.Get() == &child )
519 // Keep handle for OnChildRemove notification
522 // Do this first, since user callbacks from within SetParent() may need to add the child
523 mChildren->erase( iter );
525 DALI_ASSERT_DEBUG( actor->GetParent() == this );
526 actor->SetParent( NULL );
534 // Only put in a relayout request if there is a suitable dependency
535 if( RelayoutDependentOnChildren() )
541 // Notification for derived classes
542 OnChildRemove( child );
545 void Actor::Unparent()
549 // Remove this actor from the parent. The remove will put a relayout request in for
550 // the parent if required
551 mParent->Remove( *this );
552 // mParent is now NULL!
556 unsigned int Actor::GetChildCount() const
558 return ( NULL != mChildren ) ? mChildren->size() : 0;
561 ActorPtr Actor::GetChildAt( unsigned int index ) const
563 DALI_ASSERT_ALWAYS( index < GetChildCount() );
565 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
568 ActorPtr Actor::FindChildByName( const std::string& actorName )
571 if( actorName == mName )
577 ActorIter end = mChildren->end();
578 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
580 child = (*iter)->FindChildByName( actorName );
591 ActorPtr Actor::FindChildById( const unsigned int id )
600 ActorIter end = mChildren->end();
601 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
603 child = (*iter)->FindChildById( id );
614 void Actor::SetParentOrigin( const Vector3& origin )
618 // mNode is being used in a separate thread; queue a message to set the value & base value
619 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
622 // Cache for event-thread access
625 // not allocated, check if different from default
626 if( ParentOrigin::DEFAULT != origin )
628 mParentOrigin = new Vector3( origin );
633 // check if different from current costs more than just set
634 *mParentOrigin = origin;
638 void Actor::SetParentOriginX( float x )
640 const Vector3& current = GetCurrentParentOrigin();
642 SetParentOrigin( Vector3( x, current.y, current.z ) );
645 void Actor::SetParentOriginY( float y )
647 const Vector3& current = GetCurrentParentOrigin();
649 SetParentOrigin( Vector3( current.x, y, current.z ) );
652 void Actor::SetParentOriginZ( float z )
654 const Vector3& current = GetCurrentParentOrigin();
656 SetParentOrigin( Vector3( current.x, current.y, z ) );
659 const Vector3& Actor::GetCurrentParentOrigin() const
661 // Cached for event-thread access
662 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
665 void Actor::SetAnchorPoint( const Vector3& anchor )
669 // mNode is being used in a separate thread; queue a message to set the value & base value
670 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
673 // Cache for event-thread access
676 // not allocated, check if different from default
677 if( AnchorPoint::DEFAULT != anchor )
679 mAnchorPoint = new Vector3( anchor );
684 // check if different from current costs more than just set
685 *mAnchorPoint = anchor;
689 void Actor::SetAnchorPointX( float x )
691 const Vector3& current = GetCurrentAnchorPoint();
693 SetAnchorPoint( Vector3( x, current.y, current.z ) );
696 void Actor::SetAnchorPointY( float y )
698 const Vector3& current = GetCurrentAnchorPoint();
700 SetAnchorPoint( Vector3( current.x, y, current.z ) );
703 void Actor::SetAnchorPointZ( float z )
705 const Vector3& current = GetCurrentAnchorPoint();
707 SetAnchorPoint( Vector3( current.x, current.y, z ) );
710 const Vector3& Actor::GetCurrentAnchorPoint() const
712 // Cached for event-thread access
713 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
716 void Actor::SetPosition( float x, float y )
718 SetPosition( Vector3( x, y, 0.0f ) );
721 void Actor::SetPosition( float x, float y, float z )
723 SetPosition( Vector3( x, y, z ) );
726 void Actor::SetPosition( const Vector3& position )
728 mTargetPosition = position;
732 // mNode is being used in a separate thread; queue a message to set the value & base value
733 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
737 void Actor::SetX( float x )
739 mTargetPosition.x = x;
743 // mNode is being used in a separate thread; queue a message to set the value & base value
744 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
748 void Actor::SetY( float y )
750 mTargetPosition.y = y;
754 // mNode is being used in a separate thread; queue a message to set the value & base value
755 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
759 void Actor::SetZ( float z )
761 mTargetPosition.z = z;
765 // mNode is being used in a separate thread; queue a message to set the value & base value
766 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
770 void Actor::TranslateBy( const Vector3& distance )
772 mTargetPosition += distance;
776 // mNode is being used in a separate thread; queue a message to set the value & base value
777 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
781 const Vector3& Actor::GetCurrentPosition() const
785 // mNode is being used in a separate thread; copy the value from the previous update
786 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
789 return Vector3::ZERO;
792 const Vector3& Actor::GetTargetPosition() const
794 return mTargetPosition;
797 const Vector3& Actor::GetCurrentWorldPosition() const
801 // mNode is being used in a separate thread; copy the value from the previous update
802 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
805 return Vector3::ZERO;
808 const Vector2 Actor::GetCurrentScreenPosition() const
810 if( OnStage() && NULL != mNode )
812 StagePtr stage = Stage::GetCurrent();
813 Vector3 worldPosition = mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
814 Vector3 actorSize = GetCurrentSize() * GetCurrentScale();
815 Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
816 Vector3 halfActorSize( actorSize * 0.5f );
817 // Anchor point offset first set to TOP_LEFT (0,0.5) then moved to required anchor point.
818 Vector3 anchorPointOffSet = halfActorSize - actorSize * GetCurrentAnchorPoint();
820 return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
821 halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
824 return Vector2::ZERO;
827 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
829 // this flag is not animatable so keep the value
830 mPositionInheritanceMode = mode;
833 // mNode is being used in a separate thread; queue a message to set the value
834 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
838 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
840 // Cached for event-thread access
841 return mPositionInheritanceMode;
844 void Actor::SetInheritPosition( bool inherit )
846 if( mInheritPosition != inherit && NULL != mNode )
848 // non animateable so keep local copy
849 mInheritPosition = inherit;
850 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
854 bool Actor::IsPositionInherited() const
856 return mInheritPosition;
859 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
861 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
862 normalizedAxis.Normalize();
864 Quaternion orientation( angle, normalizedAxis );
866 SetOrientation( orientation );
869 void Actor::SetOrientation( const Quaternion& orientation )
873 // mNode is being used in a separate thread; queue a message to set the value & base value
874 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
878 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
882 // mNode is being used in a separate thread; queue a message to set the value & base value
883 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
887 void Actor::RotateBy( const Quaternion& relativeRotation )
891 // mNode is being used in a separate thread; queue a message to set the value & base value
892 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
896 const Quaternion& Actor::GetCurrentOrientation() const
900 // mNode is being used in a separate thread; copy the value from the previous update
901 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
904 return Quaternion::IDENTITY;
907 const Quaternion& Actor::GetCurrentWorldOrientation() const
911 // mNode is being used in a separate thread; copy the value from the previous update
912 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
915 return Quaternion::IDENTITY;
918 void Actor::SetScale( float scale )
920 SetScale( Vector3( scale, scale, scale ) );
923 void Actor::SetScale( float x, float y, float z )
925 SetScale( Vector3( x, y, z ) );
928 void Actor::SetScale( const Vector3& scale )
932 // mNode is being used in a separate thread; queue a message to set the value & base value
933 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
937 void Actor::SetScaleX( float x )
941 // mNode is being used in a separate thread; queue a message to set the value & base value
942 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
946 void Actor::SetScaleY( float y )
950 // mNode is being used in a separate thread; queue a message to set the value & base value
951 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
955 void Actor::SetScaleZ( float z )
959 // mNode is being used in a separate thread; queue a message to set the value & base value
960 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
964 void Actor::ScaleBy(const Vector3& relativeScale)
968 // mNode is being used in a separate thread; queue a message to set the value & base value
969 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
973 const Vector3& Actor::GetCurrentScale() const
977 // mNode is being used in a separate thread; copy the value from the previous update
978 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
984 const Vector3& Actor::GetCurrentWorldScale() const
988 // mNode is being used in a separate thread; copy the value from the previous update
989 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
995 void Actor::SetInheritScale( bool inherit )
998 if( mInheritScale != inherit && NULL != mNode )
1000 // non animateable so keep local copy
1001 mInheritScale = inherit;
1002 // mNode is being used in a separate thread; queue a message to set the value
1003 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
1007 bool Actor::IsScaleInherited() const
1009 return mInheritScale;
1012 Matrix Actor::GetCurrentWorldMatrix() const
1016 return mNode->GetWorldMatrix(0);
1019 return Matrix::IDENTITY;
1022 void Actor::SetVisible( bool visible )
1026 // mNode is being used in a separate thread; queue a message to set the value & base value
1027 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
1031 bool Actor::IsVisible() const
1035 // mNode is being used in a separate thread; copy the value from the previous update
1036 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1042 void Actor::SetOpacity( float opacity )
1046 // mNode is being used in a separate thread; queue a message to set the value & base value
1047 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1051 float Actor::GetCurrentOpacity() const
1055 // mNode is being used in a separate thread; copy the value from the previous update
1056 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1062 ClippingMode::Type Actor::GetClippingMode() const
1064 return mClippingMode;
1067 unsigned int Actor::GetSortingDepth()
1069 return GetDepthIndex( mDepth, mSiblingOrder );
1072 const Vector4& Actor::GetCurrentWorldColor() const
1076 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1079 return Color::WHITE;
1082 void Actor::SetColor( const Vector4& color )
1086 // mNode is being used in a separate thread; queue a message to set the value & base value
1087 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1091 void Actor::SetColorRed( float red )
1095 // mNode is being used in a separate thread; queue a message to set the value & base value
1096 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1100 void Actor::SetColorGreen( float green )
1104 // mNode is being used in a separate thread; queue a message to set the value & base value
1105 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1109 void Actor::SetColorBlue( float blue )
1113 // mNode is being used in a separate thread; queue a message to set the value & base value
1114 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1118 const Vector4& Actor::GetCurrentColor() const
1122 // mNode is being used in a separate thread; copy the value from the previous update
1123 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1126 return Color::WHITE;
1129 void Actor::SetInheritOrientation( bool inherit )
1131 if( mInheritOrientation != inherit && NULL != mNode)
1133 // non animateable so keep local copy
1134 mInheritOrientation = inherit;
1135 // mNode is being used in a separate thread; queue a message to set the value
1136 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1140 bool Actor::IsOrientationInherited() const
1142 return mInheritOrientation;
1145 void Actor::SetSizeModeFactor( const Vector3& factor )
1147 EnsureRelayoutData();
1149 mRelayoutData->sizeModeFactor = factor;
1152 const Vector3& Actor::GetSizeModeFactor() const
1154 if ( mRelayoutData )
1156 return mRelayoutData->sizeModeFactor;
1159 return GetDefaultSizeModeFactor();
1162 void Actor::SetColorMode( ColorMode colorMode )
1164 // non animateable so keep local copy
1165 mColorMode = colorMode;
1168 // mNode is being used in a separate thread; queue a message to set the value
1169 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1173 ColorMode Actor::GetColorMode() const
1175 // we have cached copy
1179 void Actor::SetSize( float width, float height )
1181 SetSize( Vector2( width, height ) );
1184 void Actor::SetSize( float width, float height, float depth )
1186 SetSize( Vector3( width, height, depth ) );
1189 void Actor::SetSize( const Vector2& size )
1191 SetSize( Vector3( size.width, size.height, 0.f ) );
1194 void Actor::SetSizeInternal( const Vector2& size )
1196 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1199 void Actor::SetSize( const Vector3& size )
1201 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1203 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1204 SetPreferredSize( size.GetVectorXY() );
1208 SetSizeInternal( size );
1212 void Actor::SetSizeInternal( const Vector3& size )
1214 // dont allow recursive loop
1215 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1216 // 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
1217 if( ( NULL != mNode )&&
1218 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1219 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1220 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1224 // mNode is being used in a separate thread; queue a message to set the value & base value
1225 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1227 // Notification for derived classes
1228 mInsideOnSizeSet = true;
1229 OnSizeSet( mTargetSize );
1230 mInsideOnSizeSet = false;
1232 // Raise a relayout request if the flag is not locked
1233 if( mRelayoutData && !mRelayoutData->insideRelayout )
1240 void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
1242 mTargetSize = targetSize;
1244 // Notify deriving classes
1245 OnSizeAnimation( animation, mTargetSize );
1248 void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
1250 if ( Dali::Actor::Property::SIZE_WIDTH == property )
1252 mTargetSize.width = targetSize;
1254 else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
1256 mTargetSize.height = targetSize;
1258 else if ( Dali::Actor::Property::SIZE_DEPTH == property )
1260 mTargetSize.depth = targetSize;
1262 // Notify deriving classes
1263 OnSizeAnimation( animation, mTargetSize );
1266 void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition )
1268 mTargetPosition = targetPosition;
1271 void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property )
1273 if ( Dali::Actor::Property::POSITION_X == property )
1275 mTargetPosition.x = targetPosition;
1277 else if ( Dali::Actor::Property::POSITION_Y == property )
1279 mTargetPosition.y = targetPosition;
1281 else if ( Dali::Actor::Property::POSITION_Z == property )
1283 mTargetPosition.z = targetPosition;
1287 void Actor::SetWidth( float width )
1289 mTargetSize.width = width;
1293 // mNode is being used in a separate thread; queue a message to set the value & base value
1294 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1298 void Actor::SetHeight( float height )
1300 mTargetSize.height = height;
1304 // mNode is being used in a separate thread; queue a message to set the value & base value
1305 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1309 void Actor::SetDepth( float depth )
1311 mTargetSize.depth = depth;
1315 // mNode is being used in a separate thread; queue a message to set the value & base value
1316 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1320 const Vector3& Actor::GetTargetSize() const
1325 const Vector3& Actor::GetCurrentSize() const
1329 // mNode is being used in a separate thread; copy the value from the previous update
1330 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1333 return Vector3::ZERO;
1336 Vector3 Actor::GetNaturalSize() const
1338 // It is up to deriving classes to return the appropriate natural size
1339 return Vector3( 0.0f, 0.0f, 0.0f );
1342 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1344 EnsureRelayoutData();
1346 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1347 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1349 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1351 if( dimension & ( 1 << i ) )
1353 mRelayoutData->resizePolicies[ i ] = policy;
1357 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1359 if( dimension & Dimension::WIDTH )
1361 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1364 if( dimension & Dimension::HEIGHT )
1366 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1370 // If calling SetResizePolicy, assume we want relayout enabled
1371 SetRelayoutEnabled( true );
1373 // If the resize policy is set to be FIXED, the preferred size
1374 // should be overrided by the target size. Otherwise the target
1375 // size should be overrided by the preferred size.
1377 if( dimension & Dimension::WIDTH )
1379 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1381 mRelayoutData->preferredSize.width = mTargetSize.width;
1383 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1385 mTargetSize.width = mRelayoutData->preferredSize.width;
1389 if( dimension & Dimension::HEIGHT )
1391 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1393 mRelayoutData->preferredSize.height = mTargetSize.height;
1395 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1397 mTargetSize.height = mRelayoutData->preferredSize.height;
1401 OnSetResizePolicy( policy, dimension );
1403 // Trigger relayout on this control
1407 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1409 if ( mRelayoutData )
1411 // If more than one dimension is requested, just return the first one found
1412 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1414 if( ( dimension & ( 1 << i ) ) )
1416 return mRelayoutData->resizePolicies[ i ];
1421 return ResizePolicy::DEFAULT;
1424 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1426 EnsureRelayoutData();
1428 mRelayoutData->sizeSetPolicy = policy;
1431 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1433 if ( mRelayoutData )
1435 return mRelayoutData->sizeSetPolicy;
1438 return DEFAULT_SIZE_SCALE_POLICY;
1441 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1443 EnsureRelayoutData();
1445 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1447 if( dimension & ( 1 << i ) )
1449 mRelayoutData->dimensionDependencies[ i ] = dependency;
1454 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1456 if ( mRelayoutData )
1458 // If more than one dimension is requested, just return the first one found
1459 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1461 if( ( dimension & ( 1 << i ) ) )
1463 return mRelayoutData->dimensionDependencies[ i ];
1468 return Dimension::ALL_DIMENSIONS; // Default
1471 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1473 // If relayout data has not been allocated yet and the client is requesting
1474 // to disable it, do nothing
1475 if( mRelayoutData || relayoutEnabled )
1477 EnsureRelayoutData();
1479 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1481 mRelayoutData->relayoutEnabled = relayoutEnabled;
1485 bool Actor::IsRelayoutEnabled() const
1487 // Assume that if relayout data has not been allocated yet then
1488 // relayout is disabled
1489 return mRelayoutData && mRelayoutData->relayoutEnabled;
1492 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1494 EnsureRelayoutData();
1496 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1498 if( dimension & ( 1 << i ) )
1500 mRelayoutData->dimensionDirty[ i ] = dirty;
1505 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1507 if ( mRelayoutData )
1509 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1511 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1521 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1523 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1526 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1528 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1531 unsigned int Actor::AddRenderer( Renderer& renderer )
1535 mRenderers = new RendererContainer;
1538 unsigned int index = mRenderers->size();
1539 RendererPtr rendererPtr = RendererPtr( &renderer );
1540 mRenderers->push_back( rendererPtr );
1541 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1545 unsigned int Actor::GetRendererCount() const
1547 unsigned int rendererCount(0);
1550 rendererCount = mRenderers->size();
1553 return rendererCount;
1556 RendererPtr Actor::GetRendererAt( unsigned int index )
1558 RendererPtr renderer;
1559 if( index < GetRendererCount() )
1561 renderer = ( *mRenderers )[ index ];
1567 void Actor::RemoveRenderer( Renderer& renderer )
1571 RendererIter end = mRenderers->end();
1572 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1574 if( (*iter).Get() == &renderer )
1576 mRenderers->erase( iter );
1577 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1584 void Actor::RemoveRenderer( unsigned int index )
1586 if( index < GetRendererCount() )
1588 RendererPtr renderer = ( *mRenderers )[ index ];
1589 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1590 mRenderers->erase( mRenderers->begin()+index );
1594 bool Actor::IsOverlay() const
1596 return ( DrawMode::OVERLAY_2D == mDrawMode );
1599 void Actor::SetDrawMode( DrawMode::Type drawMode )
1601 // this flag is not animatable so keep the value
1602 mDrawMode = drawMode;
1603 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1605 // mNode is being used in a separate thread; queue a message to set the value
1606 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1610 DrawMode::Type Actor::GetDrawMode() const
1615 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1617 // only valid when on-stage
1618 StagePtr stage = Stage::GetCurrent();
1619 if( stage && OnStage() )
1621 const RenderTaskList& taskList = stage->GetRenderTaskList();
1623 Vector2 converted( screenX, screenY );
1625 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1626 const int taskCount = taskList.GetTaskCount();
1627 for( int i = taskCount - 1; i >= 0; --i )
1629 Dali::RenderTask task = taskList.GetTask( i );
1630 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1632 // found a task where this conversion was ok so return
1640 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1642 bool retval = false;
1643 // only valid when on-stage
1646 CameraActor* camera = renderTask.GetCameraActor();
1650 renderTask.GetViewport( viewport );
1652 // need to translate coordinates to render tasks coordinate space
1653 Vector2 converted( screenX, screenY );
1654 if( renderTask.TranslateCoordinates( converted ) )
1656 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1663 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1665 // Early-out if mNode is NULL
1671 // Get the ModelView matrix
1673 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1675 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1676 Matrix invertedMvp( false/*don't init*/);
1677 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1678 bool success = invertedMvp.Invert();
1680 // Convert to GL coordinates
1681 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1686 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1693 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1699 if( XyPlaneIntersect( nearPos, farPos, local ) )
1701 Vector3 size = GetCurrentSize();
1702 localX = local.x + size.x * 0.5f;
1703 localY = local.y + size.y * 0.5f;
1714 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1717 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1719 Mathematical Formulation
1721 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1723 ( p - c ) dot ( p - c ) = r^2
1725 Given a ray with a point of origin 'o', and a direction vector 'd':
1727 ray(t) = o + td, t >= 0
1729 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1731 (o + td - c ) dot ( o + td - c ) = r^2
1733 To solve for t we first expand the above into a more recognisable quadratic equation form
1735 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1744 B = 2( o - c ) dot d
1745 C = ( o - c ) dot ( o - c ) - r^2
1747 which can be solved using a standard quadratic formula.
1749 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1751 Practical Simplification
1753 In a renderer, we often differentiate between world space and object space. In the object space
1754 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1755 into object space, the mathematical solution presented above can be simplified significantly.
1757 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1761 and we can find the t at which the (transformed) ray intersects the sphere by
1763 ( o + td ) dot ( o + td ) = r^2
1765 According to the reasoning above, we expand the above quadratic equation into the general form
1769 which now has coefficients:
1776 // Early out if mNode is NULL
1782 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1784 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1785 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1786 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1788 // Compute the radius is not needed, square radius it's enough.
1789 const Vector3& size( mNode->GetSize( bufferIndex ) );
1791 // Scale the sphere.
1792 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1794 const float width = size.width * scale.width;
1795 const float height = size.height * scale.height;
1797 float squareSphereRadius = 0.5f * ( width * width + height * height );
1799 float a = rayDir.Dot( rayDir ); // a
1800 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1801 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1803 return ( b2 * b2 - a * c ) >= 0.f;
1806 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1810 if( OnStage() && NULL != mNode )
1812 // Transforms the ray to the local reference system.
1813 // Calculate the inverse of Model matrix
1814 Matrix invModelMatrix( false/*don't init*/);
1816 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1817 invModelMatrix = mNode->GetWorldMatrix(0);
1818 invModelMatrix.Invert();
1820 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1821 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1823 // Test with the actor's XY plane (Normal = 0 0 1 1).
1825 float a = -rayOriginLocal.z;
1826 float b = rayDirLocal.z;
1828 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1830 // Ray travels distance * rayDirLocal to intersect with plane.
1833 const Vector3& size = mNode->GetSize( bufferIndex );
1835 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1836 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1838 // Test with the actor's geometry.
1839 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1846 void Actor::SetLeaveRequired( bool required )
1848 mLeaveRequired = required;
1851 bool Actor::GetLeaveRequired() const
1853 return mLeaveRequired;
1856 void Actor::SetKeyboardFocusable( bool focusable )
1858 mKeyboardFocusable = focusable;
1861 bool Actor::IsKeyboardFocusable() const
1863 return mKeyboardFocusable;
1866 bool Actor::GetTouchRequired() const
1868 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1871 bool Actor::GetHoverRequired() const
1873 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1876 bool Actor::GetWheelEventRequired() const
1878 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1881 bool Actor::IsHittable() const
1883 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1886 ActorGestureData& Actor::GetGestureData()
1888 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1889 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1890 if( NULL == mGestureData )
1892 mGestureData = new ActorGestureData;
1894 return *mGestureData;
1897 bool Actor::IsGestureRequred( Gesture::Type type ) const
1899 return mGestureData && mGestureData->IsGestureRequred( type );
1902 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1904 bool consumed = false;
1906 if( !mTouchSignal.Empty() )
1908 Dali::Actor handle( this );
1909 consumed = mTouchSignal.Emit( handle, touch );
1912 if( !mTouchedSignal.Empty() )
1914 Dali::Actor handle( this );
1915 consumed |= mTouchedSignal.Emit( handle, event );
1920 // Notification for derived classes
1921 consumed = OnTouchEvent( event ); // TODO
1927 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1929 bool consumed = false;
1931 if( !mHoveredSignal.Empty() )
1933 Dali::Actor handle( this );
1934 consumed = mHoveredSignal.Emit( handle, event );
1939 // Notification for derived classes
1940 consumed = OnHoverEvent( event );
1946 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1948 bool consumed = false;
1950 if( !mWheelEventSignal.Empty() )
1952 Dali::Actor handle( this );
1953 consumed = mWheelEventSignal.Emit( handle, event );
1958 // Notification for derived classes
1959 consumed = OnWheelEvent( event );
1965 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1967 return mTouchedSignal;
1970 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1972 return mTouchSignal;
1975 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1977 return mHoveredSignal;
1980 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1982 return mWheelEventSignal;
1985 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1987 return mOnStageSignal;
1990 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1992 return mOffStageSignal;
1995 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1997 return mOnRelayoutSignal;
2000 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2002 bool connected( true );
2003 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2005 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2007 actor->TouchedSignal().Connect( tracker, functor );
2009 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2011 actor->HoveredSignal().Connect( tracker, functor );
2013 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2015 actor->WheelEventSignal().Connect( tracker, functor );
2017 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2019 actor->OnStageSignal().Connect( tracker, functor );
2021 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2023 actor->OffStageSignal().Connect( tracker, functor );
2025 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2027 actor->OnRelayoutSignal().Connect( tracker, functor );
2029 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2031 actor->TouchSignal().Connect( tracker, functor );
2035 // signalName does not match any signal
2042 Actor::Actor( DerivedType derivedType )
2047 mParentOrigin( NULL ),
2048 mAnchorPoint( NULL ),
2049 mRelayoutData( NULL ),
2050 mGestureData( NULL ),
2051 mTargetSize( 0.0f, 0.0f, 0.0f ),
2053 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2056 mIsRoot( ROOT_LAYER == derivedType ),
2057 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2058 mIsOnStage( false ),
2060 mLeaveRequired( false ),
2061 mKeyboardFocusable( false ),
2062 mDerivedRequiresTouch( false ),
2063 mDerivedRequiresHover( false ),
2064 mDerivedRequiresWheelEvent( false ),
2065 mOnStageSignalled( false ),
2066 mInsideOnSizeSet( false ),
2067 mInheritPosition( true ),
2068 mInheritOrientation( true ),
2069 mInheritScale( true ),
2070 mPositionUsesAnchorPoint( true ),
2071 mDrawMode( DrawMode::NORMAL ),
2072 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2073 mColorMode( Node::DEFAULT_COLOR_MODE ),
2074 mClippingMode( ClippingMode::DISABLED )
2078 void Actor::Initialize()
2081 SceneGraph::Node* node = CreateNode();
2083 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
2084 mNode = node; // Keep raw-pointer to Node
2088 GetEventThreadServices().RegisterObject( this );
2093 // Remove mParent pointers from children even if we're destroying core,
2094 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2097 ActorConstIter endIter = mChildren->end();
2098 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2100 (*iter)->SetParent( NULL );
2106 // Guard to allow handle destruction after Core has been destroyed
2107 if( EventThreadServices::IsCoreRunning() )
2111 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2112 mNode = NULL; // Node is about to be destroyed
2115 GetEventThreadServices().UnregisterObject( this );
2118 // Cleanup optional gesture data
2119 delete mGestureData;
2121 // Cleanup optional parent origin and anchor
2122 delete mParentOrigin;
2123 delete mAnchorPoint;
2125 // Delete optional relayout data
2128 delete mRelayoutData;
2132 void Actor::ConnectToStage( unsigned int parentDepth )
2134 // This container is used instead of walking the Actor hierarchy.
2135 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2136 ActorContainer connectionList;
2138 // This stage is atomic i.e. not interrupted by user callbacks.
2139 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2141 // Notify applications about the newly connected actors.
2142 const ActorIter endIter = connectionList.end();
2143 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2145 (*iter)->NotifyStageConnection();
2151 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2153 DALI_ASSERT_ALWAYS( !OnStage() );
2157 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
2159 ConnectToSceneGraph();
2161 // Notification for internal derived classes
2162 OnStageConnectionInternal();
2164 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2165 connectionList.push_back( ActorPtr( this ) );
2167 // Recursively connect children
2170 ActorConstIter endIter = mChildren->end();
2171 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2173 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2179 * This method is called when the Actor is connected to the Stage.
2180 * The parent must have added its Node to the scene-graph.
2181 * The child must connect its Node to the parent's Node.
2182 * This is recursive; the child calls ConnectToStage() for its children.
2184 void Actor::ConnectToSceneGraph()
2186 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2190 // Reparent Node in next Update
2191 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2194 // Request relayout on all actors that are added to the scenegraph
2197 // Notification for Object::Observers
2201 void Actor::NotifyStageConnection()
2203 // Actors can be removed (in a callback), before the on-stage stage is reported.
2204 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2205 if( OnStage() && !mOnStageSignalled )
2207 // Notification for external (CustomActor) derived classes
2208 OnStageConnectionExternal( mDepth );
2210 if( !mOnStageSignal.Empty() )
2212 Dali::Actor handle( this );
2213 mOnStageSignal.Emit( handle );
2216 // Guard against Remove during callbacks
2219 mOnStageSignalled = true; // signal required next time Actor is removed
2224 void Actor::DisconnectFromStage()
2226 // This container is used instead of walking the Actor hierachy.
2227 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2228 ActorContainer disconnectionList;
2230 // This stage is atomic i.e. not interrupted by user callbacks
2231 RecursiveDisconnectFromStage( disconnectionList );
2233 // Notify applications about the newly disconnected actors.
2234 const ActorIter endIter = disconnectionList.end();
2235 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2237 (*iter)->NotifyStageDisconnection();
2241 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2243 DALI_ASSERT_ALWAYS( OnStage() );
2245 // Recursively disconnect children
2248 ActorConstIter endIter = mChildren->end();
2249 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2251 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2255 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2256 disconnectionList.push_back( ActorPtr( this ) );
2258 // Notification for internal derived classes
2259 OnStageDisconnectionInternal();
2261 DisconnectFromSceneGraph();
2267 * This method is called by an actor or its parent, before a node removal message is sent.
2268 * This is recursive; the child calls DisconnectFromStage() for its children.
2270 void Actor::DisconnectFromSceneGraph()
2272 // Notification for Object::Observers
2273 OnSceneObjectRemove();
2276 void Actor::NotifyStageDisconnection()
2278 // Actors can be added (in a callback), before the off-stage state is reported.
2279 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2280 // only do this step if there is a stage, i.e. Core is not being shut down
2281 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2283 // Notification for external (CustomeActor) derived classes
2284 OnStageDisconnectionExternal();
2286 if( !mOffStageSignal.Empty() )
2288 Dali::Actor handle( this );
2289 mOffStageSignal.Emit( handle );
2292 // Guard against Add during callbacks
2295 mOnStageSignalled = false; // signal required next time Actor is added
2300 bool Actor::IsNodeConnected() const
2302 bool connected( false );
2304 if( OnStage() && ( NULL != mNode ) )
2306 if( IsRoot() || mNode->GetParent() )
2315 unsigned int Actor::GetDefaultPropertyCount() const
2317 return DEFAULT_PROPERTY_COUNT;
2320 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2322 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2324 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2326 indices.PushBack( i );
2330 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2332 if( index < DEFAULT_PROPERTY_COUNT )
2334 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2340 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2342 Property::Index index = Property::INVALID_INDEX;
2344 // Look for name in default properties
2345 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2347 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2348 if( 0 == name.compare( property->name ) )
2358 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2360 if( index < DEFAULT_PROPERTY_COUNT )
2362 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2368 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2370 if( index < DEFAULT_PROPERTY_COUNT )
2372 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2378 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2380 if( index < DEFAULT_PROPERTY_COUNT )
2382 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2388 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2390 if( index < DEFAULT_PROPERTY_COUNT )
2392 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2395 // index out of range...return Property::NONE
2396 return Property::NONE;
2399 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2403 case Dali::Actor::Property::PARENT_ORIGIN:
2405 Property::Type type = property.GetType();
2406 if( type == Property::VECTOR3 )
2408 SetParentOrigin( property.Get< Vector3 >() );
2410 else if ( type == Property::STRING )
2412 std::string parentOriginString;
2413 property.Get( parentOriginString );
2414 Vector3 parentOrigin;
2415 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2417 SetParentOrigin( parentOrigin );
2423 case Dali::Actor::Property::PARENT_ORIGIN_X:
2425 SetParentOriginX( property.Get< float >() );
2429 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2431 SetParentOriginY( property.Get< float >() );
2435 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2437 SetParentOriginZ( property.Get< float >() );
2441 case Dali::Actor::Property::ANCHOR_POINT:
2443 Property::Type type = property.GetType();
2444 if( type == Property::VECTOR3 )
2446 SetAnchorPoint( property.Get< Vector3 >() );
2448 else if ( type == Property::STRING )
2450 std::string anchorPointString;
2451 property.Get( anchorPointString );
2453 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2455 SetAnchorPoint( anchor );
2461 case Dali::Actor::Property::ANCHOR_POINT_X:
2463 SetAnchorPointX( property.Get< float >() );
2467 case Dali::Actor::Property::ANCHOR_POINT_Y:
2469 SetAnchorPointY( property.Get< float >() );
2473 case Dali::Actor::Property::ANCHOR_POINT_Z:
2475 SetAnchorPointZ( property.Get< float >() );
2479 case Dali::Actor::Property::SIZE:
2481 SetSize( property.Get< Vector3 >() );
2485 case Dali::Actor::Property::SIZE_WIDTH:
2487 SetWidth( property.Get< float >() );
2491 case Dali::Actor::Property::SIZE_HEIGHT:
2493 SetHeight( property.Get< float >() );
2497 case Dali::Actor::Property::SIZE_DEPTH:
2499 SetDepth( property.Get< float >() );
2503 case Dali::Actor::Property::POSITION:
2505 SetPosition( property.Get< Vector3 >() );
2509 case Dali::Actor::Property::POSITION_X:
2511 SetX( property.Get< float >() );
2515 case Dali::Actor::Property::POSITION_Y:
2517 SetY( property.Get< float >() );
2521 case Dali::Actor::Property::POSITION_Z:
2523 SetZ( property.Get< float >() );
2527 case Dali::Actor::Property::ORIENTATION:
2529 SetOrientation( property.Get< Quaternion >() );
2533 case Dali::Actor::Property::SCALE:
2535 SetScale( property.Get< Vector3 >() );
2539 case Dali::Actor::Property::SCALE_X:
2541 SetScaleX( property.Get< float >() );
2545 case Dali::Actor::Property::SCALE_Y:
2547 SetScaleY( property.Get< float >() );
2551 case Dali::Actor::Property::SCALE_Z:
2553 SetScaleZ( property.Get< float >() );
2557 case Dali::Actor::Property::VISIBLE:
2559 SetVisible( property.Get< bool >() );
2563 case Dali::Actor::Property::COLOR:
2565 SetColor( property.Get< Vector4 >() );
2569 case Dali::Actor::Property::COLOR_RED:
2571 SetColorRed( property.Get< float >() );
2575 case Dali::Actor::Property::COLOR_GREEN:
2577 SetColorGreen( property.Get< float >() );
2581 case Dali::Actor::Property::COLOR_BLUE:
2583 SetColorBlue( property.Get< float >() );
2587 case Dali::Actor::Property::COLOR_ALPHA:
2588 case Dali::DevelActor::Property::OPACITY:
2591 if( property.Get( value ) )
2593 SetOpacity( value );
2598 case Dali::Actor::Property::NAME:
2600 SetName( property.Get< std::string >() );
2604 case Dali::Actor::Property::SENSITIVE:
2606 SetSensitive( property.Get< bool >() );
2610 case Dali::Actor::Property::LEAVE_REQUIRED:
2612 SetLeaveRequired( property.Get< bool >() );
2616 case Dali::Actor::Property::INHERIT_POSITION:
2618 SetInheritPosition( property.Get< bool >() );
2622 case Dali::Actor::Property::INHERIT_ORIENTATION:
2624 SetInheritOrientation( property.Get< bool >() );
2628 case Dali::Actor::Property::INHERIT_SCALE:
2630 SetInheritScale( property.Get< bool >() );
2634 case Dali::Actor::Property::COLOR_MODE:
2636 ColorMode mode = mColorMode;
2637 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2639 SetColorMode( mode );
2644 case Dali::Actor::Property::POSITION_INHERITANCE:
2646 PositionInheritanceMode mode = mPositionInheritanceMode;
2647 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2649 SetPositionInheritanceMode( mode );
2654 case Dali::Actor::Property::DRAW_MODE:
2656 DrawMode::Type mode = mDrawMode;
2657 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2659 SetDrawMode( mode );
2664 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2666 SetSizeModeFactor( property.Get< Vector3 >() );
2670 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2672 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2673 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2675 SetResizePolicy( type, Dimension::WIDTH );
2680 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2682 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2683 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2685 SetResizePolicy( type, Dimension::HEIGHT );
2690 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2692 SizeScalePolicy::Type type;
2693 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2695 SetSizeScalePolicy( type );
2700 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2702 if( property.Get< bool >() )
2704 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2709 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2711 if( property.Get< bool >() )
2713 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2718 case Dali::Actor::Property::PADDING:
2720 Vector4 padding = property.Get< Vector4 >();
2721 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2722 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2726 case Dali::Actor::Property::MINIMUM_SIZE:
2728 Vector2 size = property.Get< Vector2 >();
2729 SetMinimumSize( size.x, Dimension::WIDTH );
2730 SetMinimumSize( size.y, Dimension::HEIGHT );
2734 case Dali::Actor::Property::MAXIMUM_SIZE:
2736 Vector2 size = property.Get< Vector2 >();
2737 SetMaximumSize( size.x, Dimension::WIDTH );
2738 SetMaximumSize( size.y, Dimension::HEIGHT );
2742 case Dali::DevelActor::Property::SIBLING_ORDER:
2746 if( property.Get( value ) )
2748 if( static_cast<unsigned int>(value) != mSiblingOrder )
2750 SetSiblingOrder( value );
2756 case Dali::Actor::Property::CLIPPING_MODE:
2758 ClippingMode::Type convertedValue = mClippingMode;
2759 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2761 mClippingMode = convertedValue;
2764 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2770 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2773 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2775 mPositionUsesAnchorPoint = value;
2778 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2786 // this can happen in the case of a non-animatable default property so just do nothing
2792 // TODO: This method needs to be removed
2793 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2795 switch( entry.GetType() )
2797 case Property::BOOLEAN:
2799 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2800 DALI_ASSERT_DEBUG( NULL != property );
2802 // property is being used in a separate thread; queue a message to set the property
2803 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2808 case Property::INTEGER:
2810 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2811 DALI_ASSERT_DEBUG( NULL != property );
2813 // property is being used in a separate thread; queue a message to set the property
2814 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2819 case Property::FLOAT:
2821 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2822 DALI_ASSERT_DEBUG( NULL != property );
2824 // property is being used in a separate thread; queue a message to set the property
2825 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2830 case Property::VECTOR2:
2832 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2833 DALI_ASSERT_DEBUG( NULL != property );
2835 // property is being used in a separate thread; queue a message to set the property
2836 if(entry.componentIndex == 0)
2838 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2840 else if(entry.componentIndex == 1)
2842 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2846 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2852 case Property::VECTOR3:
2854 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2855 DALI_ASSERT_DEBUG( NULL != property );
2857 // property is being used in a separate thread; queue a message to set the property
2858 if(entry.componentIndex == 0)
2860 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2862 else if(entry.componentIndex == 1)
2864 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2866 else if(entry.componentIndex == 2)
2868 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2872 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2878 case Property::VECTOR4:
2880 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2881 DALI_ASSERT_DEBUG( NULL != property );
2883 // property is being used in a separate thread; queue a message to set the property
2884 if(entry.componentIndex == 0)
2886 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2888 else if(entry.componentIndex == 1)
2890 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2892 else if(entry.componentIndex == 2)
2894 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2896 else if(entry.componentIndex == 3)
2898 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2902 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2908 case Property::ROTATION:
2910 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2911 DALI_ASSERT_DEBUG( NULL != property );
2913 // property is being used in a separate thread; queue a message to set the property
2914 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2919 case Property::MATRIX:
2921 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2922 DALI_ASSERT_DEBUG( NULL != property );
2924 // property is being used in a separate thread; queue a message to set the property
2925 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2930 case Property::MATRIX3:
2932 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2933 DALI_ASSERT_DEBUG( NULL != property );
2935 // property is being used in a separate thread; queue a message to set the property
2936 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2943 // nothing to do for other types
2948 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2950 Property::Value value;
2952 if( index >= DEFAULT_PROPERTY_COUNT )
2959 case Dali::Actor::Property::PARENT_ORIGIN:
2961 value = GetCurrentParentOrigin();
2965 case Dali::Actor::Property::PARENT_ORIGIN_X:
2967 value = GetCurrentParentOrigin().x;
2971 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2973 value = GetCurrentParentOrigin().y;
2977 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2979 value = GetCurrentParentOrigin().z;
2983 case Dali::Actor::Property::ANCHOR_POINT:
2985 value = GetCurrentAnchorPoint();
2989 case Dali::Actor::Property::ANCHOR_POINT_X:
2991 value = GetCurrentAnchorPoint().x;
2995 case Dali::Actor::Property::ANCHOR_POINT_Y:
2997 value = GetCurrentAnchorPoint().y;
3001 case Dali::Actor::Property::ANCHOR_POINT_Z:
3003 value = GetCurrentAnchorPoint().z;
3007 case Dali::Actor::Property::SIZE:
3009 Vector3 size = GetTargetSize();
3011 // Should return preferred size if size is fixed as set by SetSize
3012 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
3014 size.width = GetPreferredSize().width;
3016 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
3018 size.height = GetPreferredSize().height;
3026 case Dali::Actor::Property::SIZE_WIDTH:
3028 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
3030 // Should return preferred size if size is fixed as set by SetSize
3031 value = GetPreferredSize().width;
3035 value = GetTargetSize().width;
3040 case Dali::Actor::Property::SIZE_HEIGHT:
3042 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
3044 // Should return preferred size if size is fixed as set by SetSize
3045 value = GetPreferredSize().height;
3049 value = GetTargetSize().height;
3054 case Dali::Actor::Property::SIZE_DEPTH:
3056 value = GetTargetSize().depth;
3060 case Dali::Actor::Property::POSITION:
3062 value = GetTargetPosition();
3066 case Dali::Actor::Property::POSITION_X:
3068 value = GetTargetPosition().x;
3072 case Dali::Actor::Property::POSITION_Y:
3074 value = GetTargetPosition().y;
3078 case Dali::Actor::Property::POSITION_Z:
3080 value = GetTargetPosition().z;
3084 case Dali::Actor::Property::WORLD_POSITION:
3086 value = GetCurrentWorldPosition();
3090 case Dali::Actor::Property::WORLD_POSITION_X:
3092 value = GetCurrentWorldPosition().x;
3096 case Dali::Actor::Property::WORLD_POSITION_Y:
3098 value = GetCurrentWorldPosition().y;
3102 case Dali::Actor::Property::WORLD_POSITION_Z:
3104 value = GetCurrentWorldPosition().z;
3108 case Dali::Actor::Property::ORIENTATION:
3110 value = GetCurrentOrientation();
3114 case Dali::Actor::Property::WORLD_ORIENTATION:
3116 value = GetCurrentWorldOrientation();
3120 case Dali::Actor::Property::SCALE:
3122 value = GetCurrentScale();
3126 case Dali::Actor::Property::SCALE_X:
3128 value = GetCurrentScale().x;
3132 case Dali::Actor::Property::SCALE_Y:
3134 value = GetCurrentScale().y;
3138 case Dali::Actor::Property::SCALE_Z:
3140 value = GetCurrentScale().z;
3144 case Dali::Actor::Property::WORLD_SCALE:
3146 value = GetCurrentWorldScale();
3150 case Dali::Actor::Property::VISIBLE:
3152 value = IsVisible();
3156 case Dali::Actor::Property::COLOR:
3158 value = GetCurrentColor();
3162 case Dali::Actor::Property::COLOR_RED:
3164 value = GetCurrentColor().r;
3168 case Dali::Actor::Property::COLOR_GREEN:
3170 value = GetCurrentColor().g;
3174 case Dali::Actor::Property::COLOR_BLUE:
3176 value = GetCurrentColor().b;
3180 case Dali::Actor::Property::COLOR_ALPHA:
3181 case Dali::DevelActor::Property::OPACITY:
3183 value = GetCurrentColor().a;
3187 case Dali::Actor::Property::WORLD_COLOR:
3189 value = GetCurrentWorldColor();
3193 case Dali::Actor::Property::WORLD_MATRIX:
3195 value = GetCurrentWorldMatrix();
3199 case Dali::Actor::Property::NAME:
3205 case Dali::Actor::Property::SENSITIVE:
3207 value = IsSensitive();
3211 case Dali::Actor::Property::LEAVE_REQUIRED:
3213 value = GetLeaveRequired();
3217 case Dali::Actor::Property::INHERIT_POSITION:
3219 value = IsPositionInherited();
3223 case Dali::Actor::Property::INHERIT_ORIENTATION:
3225 value = IsOrientationInherited();
3229 case Dali::Actor::Property::INHERIT_SCALE:
3231 value = IsScaleInherited();
3235 case Dali::Actor::Property::COLOR_MODE:
3237 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3241 case Dali::Actor::Property::POSITION_INHERITANCE:
3243 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3247 case Dali::Actor::Property::DRAW_MODE:
3249 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3253 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3255 value = GetSizeModeFactor();
3259 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3261 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3265 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3267 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3271 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3273 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3277 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3279 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3283 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3285 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3289 case Dali::Actor::Property::PADDING:
3291 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3292 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3293 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3297 case Dali::Actor::Property::MINIMUM_SIZE:
3299 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3303 case Dali::Actor::Property::MAXIMUM_SIZE:
3305 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3309 case Dali::DevelActor::Property::SIBLING_ORDER:
3311 value = static_cast<int>(mSiblingOrder);
3315 case Dali::Actor::Property::CLIPPING_MODE:
3317 value = mClippingMode;
3321 case Dali::DevelActor::Property::SCREEN_POSITION:
3323 value = GetCurrentScreenPosition();
3327 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3329 value = mPositionUsesAnchorPoint;
3337 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3342 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3344 // This method should only return an object connected to the scene-graph
3345 return OnStage() ? mNode : NULL;
3348 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3350 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3352 const PropertyBase* property( NULL );
3354 // This method should only return a property of an object connected to the scene-graph
3360 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3362 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3363 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3365 property = animatable->GetSceneGraphProperty();
3367 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3368 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3370 CustomPropertyMetadata* custom = FindCustomProperty( index );
3371 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3373 property = custom->GetSceneGraphProperty();
3375 else if( NULL != mNode )
3379 case Dali::Actor::Property::SIZE:
3380 property = &mNode->mSize;
3383 case Dali::Actor::Property::SIZE_WIDTH:
3384 property = &mNode->mSize;
3387 case Dali::Actor::Property::SIZE_HEIGHT:
3388 property = &mNode->mSize;
3391 case Dali::Actor::Property::SIZE_DEPTH:
3392 property = &mNode->mSize;
3395 case Dali::Actor::Property::POSITION:
3396 property = &mNode->mPosition;
3399 case Dali::Actor::Property::POSITION_X:
3400 property = &mNode->mPosition;
3403 case Dali::Actor::Property::POSITION_Y:
3404 property = &mNode->mPosition;
3407 case Dali::Actor::Property::POSITION_Z:
3408 property = &mNode->mPosition;
3411 case Dali::Actor::Property::ORIENTATION:
3412 property = &mNode->mOrientation;
3415 case Dali::Actor::Property::SCALE:
3416 property = &mNode->mScale;
3419 case Dali::Actor::Property::SCALE_X:
3420 property = &mNode->mScale;
3423 case Dali::Actor::Property::SCALE_Y:
3424 property = &mNode->mScale;
3427 case Dali::Actor::Property::SCALE_Z:
3428 property = &mNode->mScale;
3431 case Dali::Actor::Property::VISIBLE:
3432 property = &mNode->mVisible;
3435 case Dali::Actor::Property::COLOR:
3436 property = &mNode->mColor;
3439 case Dali::Actor::Property::COLOR_RED:
3440 property = &mNode->mColor;
3443 case Dali::Actor::Property::COLOR_GREEN:
3444 property = &mNode->mColor;
3447 case Dali::Actor::Property::COLOR_BLUE:
3448 property = &mNode->mColor;
3451 case Dali::Actor::Property::COLOR_ALPHA:
3452 case Dali::DevelActor::Property::OPACITY:
3453 property = &mNode->mColor;
3464 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3466 const PropertyInputImpl* property( NULL );
3468 // This method should only return a property of an object connected to the scene-graph
3474 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3476 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3477 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3479 property = animatable->GetSceneGraphProperty();
3481 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3482 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3484 CustomPropertyMetadata* custom = FindCustomProperty( index );
3485 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3486 property = custom->GetSceneGraphProperty();
3488 else if( NULL != mNode )
3492 case Dali::Actor::Property::PARENT_ORIGIN:
3493 property = &mNode->mParentOrigin;
3496 case Dali::Actor::Property::PARENT_ORIGIN_X:
3497 property = &mNode->mParentOrigin;
3500 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3501 property = &mNode->mParentOrigin;
3504 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3505 property = &mNode->mParentOrigin;
3508 case Dali::Actor::Property::ANCHOR_POINT:
3509 property = &mNode->mAnchorPoint;
3512 case Dali::Actor::Property::ANCHOR_POINT_X:
3513 property = &mNode->mAnchorPoint;
3516 case Dali::Actor::Property::ANCHOR_POINT_Y:
3517 property = &mNode->mAnchorPoint;
3520 case Dali::Actor::Property::ANCHOR_POINT_Z:
3521 property = &mNode->mAnchorPoint;
3524 case Dali::Actor::Property::SIZE:
3525 property = &mNode->mSize;
3528 case Dali::Actor::Property::SIZE_WIDTH:
3529 property = &mNode->mSize;
3532 case Dali::Actor::Property::SIZE_HEIGHT:
3533 property = &mNode->mSize;
3536 case Dali::Actor::Property::SIZE_DEPTH:
3537 property = &mNode->mSize;
3540 case Dali::Actor::Property::POSITION:
3541 property = &mNode->mPosition;
3544 case Dali::Actor::Property::POSITION_X:
3545 property = &mNode->mPosition;
3548 case Dali::Actor::Property::POSITION_Y:
3549 property = &mNode->mPosition;
3552 case Dali::Actor::Property::POSITION_Z:
3553 property = &mNode->mPosition;
3556 case Dali::Actor::Property::WORLD_POSITION:
3557 property = &mNode->mWorldPosition;
3560 case Dali::Actor::Property::WORLD_POSITION_X:
3561 property = &mNode->mWorldPosition;
3564 case Dali::Actor::Property::WORLD_POSITION_Y:
3565 property = &mNode->mWorldPosition;
3568 case Dali::Actor::Property::WORLD_POSITION_Z:
3569 property = &mNode->mWorldPosition;
3572 case Dali::Actor::Property::ORIENTATION:
3573 property = &mNode->mOrientation;
3576 case Dali::Actor::Property::WORLD_ORIENTATION:
3577 property = &mNode->mWorldOrientation;
3580 case Dali::Actor::Property::SCALE:
3581 property = &mNode->mScale;
3584 case Dali::Actor::Property::SCALE_X:
3585 property = &mNode->mScale;
3588 case Dali::Actor::Property::SCALE_Y:
3589 property = &mNode->mScale;
3592 case Dali::Actor::Property::SCALE_Z:
3593 property = &mNode->mScale;
3596 case Dali::Actor::Property::WORLD_SCALE:
3597 property = &mNode->mWorldScale;
3600 case Dali::Actor::Property::VISIBLE:
3601 property = &mNode->mVisible;
3604 case Dali::Actor::Property::COLOR:
3605 property = &mNode->mColor;
3608 case Dali::Actor::Property::COLOR_RED:
3609 property = &mNode->mColor;
3612 case Dali::Actor::Property::COLOR_GREEN:
3613 property = &mNode->mColor;
3616 case Dali::Actor::Property::COLOR_BLUE:
3617 property = &mNode->mColor;
3620 case Dali::Actor::Property::COLOR_ALPHA:
3621 case Dali::DevelActor::Property::OPACITY:
3623 property = &mNode->mColor;
3627 case Dali::Actor::Property::WORLD_COLOR:
3628 property = &mNode->mWorldColor;
3631 case Dali::Actor::Property::WORLD_MATRIX:
3632 property = &mNode->mWorldMatrix;
3643 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3645 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3647 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3649 // check whether the animatable property is registered already, if not then register one.
3650 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3651 if( animatableProperty )
3653 componentIndex = animatableProperty->componentIndex;
3660 case Dali::Actor::Property::PARENT_ORIGIN_X:
3661 case Dali::Actor::Property::ANCHOR_POINT_X:
3662 case Dali::Actor::Property::SIZE_WIDTH:
3663 case Dali::Actor::Property::POSITION_X:
3664 case Dali::Actor::Property::WORLD_POSITION_X:
3665 case Dali::Actor::Property::SCALE_X:
3666 case Dali::Actor::Property::COLOR_RED:
3672 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3673 case Dali::Actor::Property::ANCHOR_POINT_Y:
3674 case Dali::Actor::Property::SIZE_HEIGHT:
3675 case Dali::Actor::Property::POSITION_Y:
3676 case Dali::Actor::Property::WORLD_POSITION_Y:
3677 case Dali::Actor::Property::SCALE_Y:
3678 case Dali::Actor::Property::COLOR_GREEN:
3684 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3685 case Dali::Actor::Property::ANCHOR_POINT_Z:
3686 case Dali::Actor::Property::SIZE_DEPTH:
3687 case Dali::Actor::Property::POSITION_Z:
3688 case Dali::Actor::Property::WORLD_POSITION_Z:
3689 case Dali::Actor::Property::SCALE_Z:
3690 case Dali::Actor::Property::COLOR_BLUE:
3696 case Dali::Actor::Property::COLOR_ALPHA:
3697 case Dali::DevelActor::Property::OPACITY:
3711 return componentIndex;
3714 void Actor::SetParent( Actor* parent )
3718 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3722 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3725 // Instruct each actor to create a corresponding node in the scene graph
3726 ConnectToStage( parent->GetHierarchyDepth() );
3729 // Resolve the name and index for the child properties if any
3730 ResolveChildProperties();
3732 else // parent being set to NULL
3734 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3738 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3741 DALI_ASSERT_ALWAYS( mNode != NULL );
3745 // Disconnect the Node & its children from the scene-graph.
3746 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3749 // Instruct each actor to discard pointers to the scene-graph
3750 DisconnectFromStage();
3755 SceneGraph::Node* Actor::CreateNode() const
3760 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3763 Actor* actor = dynamic_cast< Actor* >( object );
3767 if( 0 == actionName.compare( ACTION_SHOW ) )
3769 actor->SetVisible( true );
3772 else if( 0 == actionName.compare( ACTION_HIDE ) )
3774 actor->SetVisible( false );
3782 void Actor::EnsureRelayoutData()
3784 // Assign relayout data.
3785 if( !mRelayoutData )
3787 mRelayoutData = new RelayoutData();
3791 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3793 // Check if actor is dependent on parent
3794 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3796 if( ( dimension & ( 1 << i ) ) )
3798 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3799 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
3809 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
3811 // Check if actor is dependent on children
3812 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3814 if( ( dimension & ( 1 << i ) ) )
3816 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3817 switch( resizePolicy )
3819 case ResizePolicy::FIT_TO_CHILDREN:
3820 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
3836 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
3838 return Actor::RelayoutDependentOnChildren( dimension );
3841 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
3843 // Check each possible dimension and see if it is dependent on the input one
3844 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3846 if( dimension & ( 1 << i ) )
3848 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
3855 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
3857 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3859 if( dimension & ( 1 << i ) )
3861 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
3866 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
3868 // If more than one dimension is requested, just return the first one found
3869 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3871 if( ( dimension & ( 1 << i ) ) )
3873 return mRelayoutData->negotiatedDimensions[ i ];
3877 return 0.0f; // Default
3880 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
3882 EnsureRelayoutData();
3884 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3886 if( dimension & ( 1 << i ) )
3888 mRelayoutData->dimensionPadding[ i ] = padding;
3893 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
3895 if ( mRelayoutData )
3897 // If more than one dimension is requested, just return the first one found
3898 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3900 if( ( dimension & ( 1 << i ) ) )
3902 return mRelayoutData->dimensionPadding[ i ];
3907 return GetDefaultDimensionPadding();
3910 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
3912 EnsureRelayoutData();
3914 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3916 if( dimension & ( 1 << i ) )
3918 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
3923 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
3925 if ( mRelayoutData )
3927 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3929 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
3939 float Actor::GetHeightForWidthBase( float width )
3941 float height = 0.0f;
3943 const Vector3 naturalSize = GetNaturalSize();
3944 if( naturalSize.width > 0.0f )
3946 height = naturalSize.height * width / naturalSize.width;
3948 else // we treat 0 as 1:1 aspect ratio
3956 float Actor::GetWidthForHeightBase( float height )
3960 const Vector3 naturalSize = GetNaturalSize();
3961 if( naturalSize.height > 0.0f )
3963 width = naturalSize.width * height / naturalSize.height;
3965 else // we treat 0 as 1:1 aspect ratio
3973 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
3975 // Fill to parent, taking size mode factor into account
3976 switch( child.GetResizePolicy( dimension ) )
3978 case ResizePolicy::FILL_TO_PARENT:
3980 return GetLatestSize( dimension );
3983 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
3985 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
3988 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
3990 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
3995 return GetLatestSize( dimension );
4000 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4002 // Can be overridden in derived class
4003 return CalculateChildSizeBase( child, dimension );
4006 float Actor::GetHeightForWidth( float width )
4008 // Can be overridden in derived class
4009 return GetHeightForWidthBase( width );
4012 float Actor::GetWidthForHeight( float height )
4014 // Can be overridden in derived class
4015 return GetWidthForHeightBase( height );
4018 float Actor::GetLatestSize( Dimension::Type dimension ) const
4020 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4023 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4025 Vector2 padding = GetPadding( dimension );
4027 return GetLatestSize( dimension ) + padding.x + padding.y;
4030 float Actor::NegotiateFromParent( Dimension::Type dimension )
4032 Actor* parent = GetParent();
4035 Vector2 padding( GetPadding( dimension ) );
4036 Vector2 parentPadding( parent->GetPadding( dimension ) );
4037 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4043 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4045 float maxDimensionPoint = 0.0f;
4047 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4049 ActorPtr child = GetChildAt( i );
4051 if( !child->RelayoutDependentOnParent( dimension ) )
4053 // Calculate the min and max points that the children range across
4054 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4055 float dimensionSize = child->GetRelayoutSize( dimension );
4056 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4060 return maxDimensionPoint;
4063 float Actor::GetSize( Dimension::Type dimension ) const
4065 return GetDimensionValue( GetTargetSize(), dimension );
4068 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4070 return GetDimensionValue( GetNaturalSize(), dimension );
4073 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4075 switch( GetResizePolicy( dimension ) )
4077 case ResizePolicy::USE_NATURAL_SIZE:
4079 return GetNaturalSize( dimension );
4082 case ResizePolicy::FIXED:
4084 return GetDimensionValue( GetPreferredSize(), dimension );
4087 case ResizePolicy::USE_ASSIGNED_SIZE:
4089 return GetDimensionValue( maximumSize, dimension );
4092 case ResizePolicy::FILL_TO_PARENT:
4093 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4094 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4096 return NegotiateFromParent( dimension );
4099 case ResizePolicy::FIT_TO_CHILDREN:
4101 return NegotiateFromChildren( dimension );
4104 case ResizePolicy::DIMENSION_DEPENDENCY:
4106 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4109 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4111 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4114 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4116 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4128 return 0.0f; // Default
4131 float Actor::ClampDimension( float size, Dimension::Type dimension )
4133 const float minSize = GetMinimumSize( dimension );
4134 const float maxSize = GetMaximumSize( dimension );
4136 return std::max( minSize, std::min( size, maxSize ) );
4139 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4141 // Check if it needs to be negotiated
4142 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4144 // Check that we havn't gotten into an infinite loop
4145 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4146 bool recursionFound = false;
4147 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4149 if( *it == searchActor )
4151 recursionFound = true;
4156 if( !recursionFound )
4158 // Record the path that we have taken
4159 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4161 // Dimension dependency check
4162 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4164 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4166 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4168 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4172 // Parent dependency check
4173 Actor* parent = GetParent();
4174 if( parent && RelayoutDependentOnParent( dimension ) )
4176 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4179 // Children dependency check
4180 if( RelayoutDependentOnChildren( dimension ) )
4182 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4184 ActorPtr child = GetChildAt( i );
4186 // Only relayout child first if it is not dependent on this actor
4187 if( !child->RelayoutDependentOnParent( dimension ) )
4189 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4194 // For deriving classes
4195 OnCalculateRelayoutSize( dimension );
4197 // All dependencies checked, calculate the size and set negotiated flag
4198 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4200 SetNegotiatedDimension( newSize, dimension );
4201 SetLayoutNegotiated( true, dimension );
4203 // For deriving classes
4204 OnLayoutNegotiated( newSize, dimension );
4206 // This actor has been successfully processed, pop it off the recursion stack
4207 recursionStack.pop_back();
4211 // TODO: Break infinite loop
4212 SetLayoutNegotiated( true, dimension );
4217 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4219 // Negotiate all dimensions that require it
4220 ActorDimensionStack recursionStack;
4222 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4224 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4227 NegotiateDimension( dimension, allocatedSize, recursionStack );
4231 Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
4233 switch( mRelayoutData->sizeSetPolicy )
4235 case SizeScalePolicy::USE_SIZE_SET:
4240 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4242 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4243 const Vector3 naturalSize = GetNaturalSize();
4244 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4246 const float sizeRatio = size.width / size.height;
4247 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4249 if( naturalSizeRatio < sizeRatio )
4251 return Vector2( naturalSizeRatio * size.height, size.height );
4253 else if( naturalSizeRatio > sizeRatio )
4255 return Vector2( size.width, size.width / naturalSizeRatio );
4266 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4268 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4269 const Vector3 naturalSize = GetNaturalSize();
4270 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4272 const float sizeRatio = size.width / size.height;
4273 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4275 if( naturalSizeRatio < sizeRatio )
4277 return Vector2( size.width, size.width / naturalSizeRatio );
4279 else if( naturalSizeRatio > sizeRatio )
4281 return Vector2( naturalSizeRatio * size.height, size.height );
4300 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4302 // Do the set actor size
4303 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4305 // Adjust for size set policy
4306 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4308 // Lock the flag to stop recursive relayouts on set size
4309 mRelayoutData->insideRelayout = true;
4310 SetSize( negotiatedSize );
4311 mRelayoutData->insideRelayout = false;
4313 // Clear flags for all dimensions
4314 SetLayoutDirty( false );
4316 // Give deriving classes a chance to respond
4317 OnRelayout( negotiatedSize, container );
4319 if( !mOnRelayoutSignal.Empty() )
4321 Dali::Actor handle( this );
4322 mOnRelayoutSignal.Emit( handle );
4326 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4328 // Force a size negotiation for actors that has assigned size during relayout
4329 // This is required as otherwise the flags that force a relayout will not
4330 // necessarilly be set. This will occur if the actor has already been laid out.
4331 // The dirty flags are then cleared. Then if the actor is added back into the
4332 // relayout container afterwards, the dirty flags would still be clear...
4333 // causing a relayout to be skipped. Here we force any actors added to the
4334 // container to be relayed out.
4335 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4337 SetLayoutNegotiated(false, Dimension::WIDTH);
4339 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4341 SetLayoutNegotiated(false, Dimension::HEIGHT);
4344 // Do the negotiation
4345 NegotiateDimensions( allocatedSize );
4347 // Set the actor size
4348 SetNegotiatedSize( container );
4350 // Negotiate down to children
4351 const Vector2 newBounds = GetTargetSize().GetVectorXY();
4353 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4355 ActorPtr child = GetChildAt( i );
4357 // Forces children that have already been laid out to be relayed out
4358 // if they have assigned size during relayout.
4359 if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
4361 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4362 child->SetLayoutDirty(true, Dimension::WIDTH);
4364 if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
4366 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4367 child->SetLayoutDirty(true, Dimension::HEIGHT);
4370 // Only relayout if required
4371 if( child->RelayoutRequired() )
4373 container.Add( Dali::Actor( child.Get() ), newBounds );
4378 void Actor::RelayoutRequest( Dimension::Type dimension )
4380 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4381 if( relayoutController )
4383 Dali::Actor self( this );
4384 relayoutController->RequestRelayout( self, dimension );
4388 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4392 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4396 void Actor::SetPreferredSize( const Vector2& size )
4398 EnsureRelayoutData();
4400 if( size.width > 0.0f )
4402 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4405 if( size.height > 0.0f )
4407 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4410 mRelayoutData->preferredSize = size;
4415 Vector2 Actor::GetPreferredSize() const
4417 if ( mRelayoutData )
4419 return Vector2( mRelayoutData->preferredSize );
4422 return GetDefaultPreferredSize();
4425 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4427 EnsureRelayoutData();
4429 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4431 if( dimension & ( 1 << i ) )
4433 mRelayoutData->minimumSize[ i ] = size;
4440 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4442 if ( mRelayoutData )
4444 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4446 if( dimension & ( 1 << i ) )
4448 return mRelayoutData->minimumSize[ i ];
4453 return 0.0f; // Default
4456 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4458 EnsureRelayoutData();
4460 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4462 if( dimension & ( 1 << i ) )
4464 mRelayoutData->maximumSize[ i ] = size;
4471 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4473 if ( mRelayoutData )
4475 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4477 if( dimension & ( 1 << i ) )
4479 return mRelayoutData->maximumSize[ i ];
4484 return FLT_MAX; // Default
4487 Object* Actor::GetParentObject() const
4492 void Actor::SetSiblingOrder( unsigned int order )
4494 mSiblingOrder = std::min( order, static_cast<unsigned int>( DevelLayer::SIBLING_ORDER_MULTIPLIER ) );
4497 SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
4501 void Actor::DefragmentSiblingIndexes( ActorContainer& siblings )
4503 // Sibling index may not be in consecutive order as the sibling range is limited ( DevelLayer::SIBLING_ORDER_MULTIPLIER )
4504 // we need to remove the gaps and ensure the number start from 0 and consecutive hence have a full range.
4506 // Start at index 0, while index <= highest order
4507 // Find next index higher than 0
4508 // if nextHigher > index+1
4509 // set all nextHigher orders to index+1
4511 // Limitation: May reach the ceiling of DevelLayer::SIBLING_ORDER_MULTIPLIER with highest sibling.
4513 ActorIter end = siblings.end();
4514 int highestOrder = 0;
4515 for( ActorIter iter = siblings.begin(); iter != end; ++iter )
4517 ActorPtr sibling = (*iter);
4518 int siblingOrder = sibling->mSiblingOrder;
4519 highestOrder = std::max( highestOrder, siblingOrder );
4522 for ( int index = 0; index <= highestOrder; index++ )
4524 int nextHighest = -1;
4526 // Find Next highest
4527 for( ActorIter iter = siblings.begin(); iter != end; ++iter )
4529 ActorPtr sibling = (*iter);
4530 int siblingOrder = sibling->mSiblingOrder;
4532 if ( siblingOrder > index )
4534 if ( nextHighest == -1 )
4536 nextHighest = siblingOrder;
4538 nextHighest = std::min( nextHighest, siblingOrder );
4542 // Check if a gap exists between indexes, if so set next index to consecutive number
4543 if ( ( nextHighest - index ) > 1 )
4545 for( ActorIter iter = siblings.begin(); iter != end; ++iter )
4547 ActorPtr sibling = (*iter);
4548 int siblingOrder = sibling->mSiblingOrder;
4549 if ( siblingOrder == nextHighest )
4551 sibling->mSiblingOrder = index + 1;
4552 if ( sibling->mSiblingOrder >= Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER )
4554 DALI_LOG_WARNING( "Reached max sibling order level for raising / lowering actors\n" );
4555 sibling->mSiblingOrder = Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
4557 sibling->SetSiblingOrder( sibling->mSiblingOrder );
4564 bool Actor::ShiftSiblingsLevels( ActorContainer& siblings, int targetLevelToShiftFrom )
4566 // Allows exclusive levels for an actor by shifting all sibling levels at the target and above by 1
4567 bool defragmentationRequired( false );
4568 ActorIter end = siblings.end();
4569 for( ActorIter iter = siblings.begin(); ( iter != end ) ; ++iter )
4571 // Move actors at nearest order and above up by 1
4572 ActorPtr sibling = (*iter);
4573 if ( sibling != this )
4575 // Iterate through container of actors, any actor with a sibling order of the target or greater should
4576 // be incremented by 1.
4577 if ( sibling->mSiblingOrder >= targetLevelToShiftFrom )
4579 sibling->mSiblingOrder++;
4580 if ( sibling->mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER )
4582 // If a sibling order raises so that it is only 1 from the maximum allowed then set flag so
4583 // can re-order all sibling orders.
4584 defragmentationRequired = true;
4586 sibling->SetSiblingOrder( sibling->mSiblingOrder );
4590 return defragmentationRequired;
4596 1) Check if already at top and nothing to be done.
4597 This Actor can have highest sibling order but if not exclusive then another actor at same sibling
4598 order can be positioned above it due to insertion order of actors.
4599 2) Find nearest sibling level above, these are the siblings this actor needs to be above
4600 3) a) There may be other levels above this target level
4601 b) Increment all sibling levels at the level above nearest(target)
4602 c) Now have a vacant sibling level
4603 4) Set this actor's sibling level to nearest +1 as now vacated.
4605 Note May not just be sibling level + 1 as could be empty levels in-between
4610 ActorC ( sibling level 4 )
4611 ActorB ( sibling level 3 )
4612 ActorA ( sibling level 1 )
4614 2 ) ACTION: Raise A above B
4615 a) Find nearest level above A = Level 3
4616 b) Increment levels above Level 3
4618 ActorC ( sibling level 5 )
4619 ActorB ( sibling level 3 ) NEAREST
4620 ActorA ( sibling level 1 )
4622 3 ) Set Actor A sibling level to nearest +1 as vacant
4624 ActorC ( sibling level 5 )
4625 ActorA ( sibling level 4 )
4626 ActorB ( sibling level 3 )
4628 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
4629 If shifting causes this ceiling to be reached. then a defragmentation can be performed to
4630 remove any empty sibling order gaps and start from sibling level 0 again.
4631 If the number of actors reaches this maximum and all using exclusive sibling order values then
4632 defragmention will stop and new sibling orders will be set to same max value.
4636 int nearestLevel = mSiblingOrder;
4637 int shortestDistanceToNextLevel = DevelLayer::SIBLING_ORDER_MULTIPLIER;
4638 bool defragmentationRequired( false );
4640 ActorContainer* siblings = mParent->mChildren;
4642 // Find Nearest sibling level above this actor
4643 ActorIter end = siblings->end();
4644 for( ActorIter iter = siblings->begin(); iter != end; ++iter )
4646 ActorPtr sibling = (*iter);
4647 if ( sibling != this )
4649 int order = GetSiblingOrder( sibling );
4651 if ( ( order >= mSiblingOrder ) )
4653 int distanceToNextLevel = order - mSiblingOrder;
4654 if ( distanceToNextLevel < shortestDistanceToNextLevel )
4656 nearestLevel = order;
4657 shortestDistanceToNextLevel = distanceToNextLevel;
4663 if ( nearestLevel < DevelLayer::SIBLING_ORDER_MULTIPLIER ) // Actor is not already exclusively at top
4665 mSiblingOrder = nearestLevel + 1; // Set sibling level to that above the nearest level
4666 defragmentationRequired = ShiftSiblingsLevels( *siblings, mSiblingOrder );
4667 // Move current actor to newly vacated order level
4668 SetSiblingOrder( mSiblingOrder );
4669 if ( defragmentationRequired )
4671 DefragmentSiblingIndexes( *siblings );
4674 SetSiblingOrder( mSiblingOrder );
4678 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4685 1) Check if actor already at bottom and if nothing needs to be done
4686 This Actor can have lowest sibling order but if not exclusive then another actor at same sibling
4687 order can be positioned above it due to insertion order of actors so need to move this actor below it.
4688 2) Find nearest sibling level below, this Actor needs to be below it
4689 3) a) Need to vacate a sibling level below nearest for this actor to occupy
4690 b) Shift up all sibling order values of actor at the nearest level and levels above it to vacate a level.
4691 c) Set this actor's sibling level to this newly vacated level.
4692 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
4693 If shifting causes this ceiling to be reached. then a defragmentation can be performed to
4694 remove any empty sibling order gaps and start from sibling level 0 again.
4695 If the number of actors reaches this maximum and all using exclusive sibling order values then
4696 defragmention will stop and new sibling orders will be set to same max value.
4701 // 1) Find nearest level below
4702 int nearestLevel = mSiblingOrder;
4703 int shortestDistanceToNextLevel = DevelLayer::SIBLING_ORDER_MULTIPLIER;
4705 ActorContainer* siblings = mParent->mChildren;
4707 ActorIter end = siblings->end();
4708 for( ActorIter iter = siblings->begin(); iter != end; ++iter )
4710 ActorPtr sibling = (*iter);
4711 if ( sibling != this )
4713 int order = GetSiblingOrder( sibling );
4715 if ( order <= mSiblingOrder )
4717 int distanceToNextLevel = mSiblingOrder - order;
4718 if ( distanceToNextLevel < shortestDistanceToNextLevel )
4720 nearestLevel = order;
4721 shortestDistanceToNextLevel = distanceToNextLevel;
4727 bool defragmentationRequired ( false );
4729 // 2) If actor already not at bottom, raise all actors at required level and above
4730 if ( shortestDistanceToNextLevel < DevelLayer::SIBLING_ORDER_MULTIPLIER ) // Actor is not already exclusively at bottom
4732 mSiblingOrder = nearestLevel;
4733 defragmentationRequired = ShiftSiblingsLevels( *siblings, mSiblingOrder );
4734 // Move current actor to newly vacated order
4735 SetSiblingOrder( mSiblingOrder );
4736 if ( defragmentationRequired )
4738 DefragmentSiblingIndexes( *siblings );
4744 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4748 void Actor::RaiseToTop()
4751 1 ) Find highest sibling order actor
4752 2 ) If highest sibling level not itself then set sibling order to that + 1
4753 3 ) highest sibling order can be same as itself so need to increment over that
4754 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
4755 If shifting causes this ceiling to be reached. then a defragmentation can be performed to
4756 remove any empty sibling order gaps and start from sibling level 0 again.
4757 If the number of actors reaches this maximum and all using exclusive sibling order values then
4758 defragmention will stop and new sibling orders will be set to same max value.
4765 ActorContainer* siblings = mParent->mChildren;
4767 ActorIter end = siblings->end();
4768 for( ActorIter iter = siblings->begin(); iter != end; ++iter )
4770 ActorPtr sibling = (*iter);
4771 if ( sibling != this )
4773 maxOrder = std::max( GetSiblingOrder( sibling ), maxOrder );
4777 bool defragmentationRequired( false );
4779 if ( maxOrder >= mSiblingOrder )
4781 mSiblingOrder = maxOrder + 1;
4782 if ( mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER )
4784 defragmentationRequired = true;
4788 SetSiblingOrder( mSiblingOrder );
4790 if ( defragmentationRequired )
4792 DefragmentSiblingIndexes( *siblings );
4797 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4801 void Actor::LowerToBottom()
4804 See Actor::LowerToBottom()
4806 1 ) Check if this actor already at exclusively at the bottom, if so then no more to be done.
4807 2 ) a ) Check if the bottom position 0 is vacant.
4808 b ) If 0 position is not vacant then shift up all sibling order values from 0 and above
4809 c ) 0 sibling position is vacant.
4810 3 ) Set this actor to vacant sibling order 0;
4811 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
4812 If shifting causes this ceiling to be reached. then a defragmentation can be performed to
4813 remove any empty sibling order gaps and start from sibling level 0 again.
4814 If the number of actors reaches this maximum and all using exclusive sibling order values then
4815 defragmention will stop and new sibling orders will be set to same max value.
4820 bool defragmentationRequired( false );
4821 bool orderZeroFree ( true );
4823 ActorContainer* siblings = mParent->mChildren;
4825 bool actorAtLowestOrder = true;
4826 ActorIter end = siblings->end();
4827 for( ActorIter iter = siblings->begin(); ( iter != end ) ; ++iter )
4829 ActorPtr sibling = (*iter);
4830 if ( sibling != this )
4832 int siblingOrder = GetSiblingOrder( sibling );
4833 if ( siblingOrder <= mSiblingOrder )
4835 actorAtLowestOrder = false;
4838 if ( siblingOrder == 0 )
4840 orderZeroFree = false;
4845 if ( ! actorAtLowestOrder )
4847 if ( ! orderZeroFree )
4849 defragmentationRequired = ShiftSiblingsLevels( *siblings, 0 );
4852 SetSiblingOrder( mSiblingOrder );
4854 if ( defragmentationRequired )
4856 DefragmentSiblingIndexes( *siblings );
4862 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4866 void Actor::RaiseAbove( Internal::Actor& target )
4869 1 ) a) Find target actor's sibling order
4870 b) If sibling order of target is the same as this actor then need to this Actor's sibling order
4871 needs to be above it or the insertion order will determine which is drawn on top.
4872 2 ) Shift up by 1 all sibling order greater than target sibling order
4873 3 ) Set this actor to the sibling order to target +1 as will be a newly vacated gap above
4874 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
4875 If shifting causes this ceiling to be reached. then a defragmentation can be performed to
4876 remove any empty sibling order gaps and start from sibling level 0 again.
4877 If the number of actors reaches this maximum and all using exclusive sibling order values then
4878 defragmention will stop and new sibling orders will be set to same max value.
4883 if ( ValidateActors( *this, target ) )
4885 // Find target's sibling order
4886 // Set actor sibling order to this number +1
4887 int targetSiblingOrder = GetSiblingOrder( &target );
4888 ActorContainer* siblings = mParent->mChildren;
4889 mSiblingOrder = targetSiblingOrder + 1;
4890 bool defragmentationRequired = ShiftSiblingsLevels( *siblings, mSiblingOrder );
4892 SetSiblingOrder( mSiblingOrder );
4894 if ( defragmentationRequired )
4896 DefragmentSiblingIndexes( *(mParent->mChildren) );
4902 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4906 void Actor::LowerBelow( Internal::Actor& target )
4909 1 ) a) Find target actor's sibling order
4910 b) If sibling order of target is the same as this actor then need to this Actor's sibling order
4911 needs to be below it or the insertion order will determine which is drawn on top.
4912 2 ) Shift the target sibling order and all sibling orders at that level or above by 1
4913 3 ) Set this actor to the sibling order of the target before it changed.
4914 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
4915 If shifting causes this ceiling to be reached. then a defragmentation can be performed to
4916 remove any empty sibling order gaps and start from sibling level 0 again.
4917 If the number of actors reaches this maximum and all using exclusive sibling order values then
4918 defragmention will stop and new sibling orders will be set to same max value.
4923 if ( ValidateActors( *this, target ) )
4925 bool defragmentationRequired ( false );
4926 // Find target's sibling order
4927 // Set actor sibling order to target sibling order - 1
4928 int targetSiblingOrder = GetSiblingOrder( &target);
4929 ActorContainer* siblings = mParent->mChildren;
4930 if ( targetSiblingOrder == 0 )
4933 ActorIter end = siblings->end();
4934 for( ActorIter iter = siblings->begin(); ( iter != end ) ; ++iter )
4936 ActorPtr sibling = (*iter);
4937 if ( sibling != this )
4939 sibling->mSiblingOrder++;
4940 if ( sibling->mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER )
4942 defragmentationRequired = true;
4944 sibling->SetSiblingOrder( sibling->mSiblingOrder );
4951 defragmentationRequired = ShiftSiblingsLevels( *siblings, targetSiblingOrder );
4953 mSiblingOrder = targetSiblingOrder;
4955 SetSiblingOrder( mSiblingOrder );
4957 if ( defragmentationRequired )
4959 DefragmentSiblingIndexes( *(mParent->mChildren) );
4965 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4969 } // namespace Internal