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/object/weak-handle.h>
37 #include <dali/devel-api/scripting/scripting.h>
38 #include <dali/internal/common/internal-constants.h>
39 #include <dali/internal/event/common/event-thread-services.h>
40 #include <dali/internal/event/render-tasks/render-task-impl.h>
41 #include <dali/internal/event/actors/camera-actor-impl.h>
42 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
43 #include <dali/internal/event/common/property-helper.h>
44 #include <dali/internal/event/common/stage-impl.h>
45 #include <dali/internal/event/common/type-info-impl.h>
46 #include <dali/internal/event/animation/constraint-impl.h>
47 #include <dali/internal/event/common/projection.h>
48 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
49 #include <dali/internal/update/common/animatable-property.h>
50 #include <dali/internal/update/nodes/node-messages.h>
51 #include <dali/internal/update/nodes/node-declarations.h>
52 #include <dali/internal/update/animation/scene-graph-constraint.h>
53 #include <dali/internal/event/events/actor-gesture-data.h>
54 #include <dali/internal/common/message.h>
55 #include <dali/integration-api/debug.h>
57 using Dali::Internal::SceneGraph::Node;
58 using Dali::Internal::SceneGraph::AnimatableProperty;
59 using Dali::Internal::SceneGraph::PropertyBase;
61 #if defined(DEBUG_ENABLED)
62 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
63 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
72 unsigned int Actor::mActorCounter = 0;
76 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
77 inline const Vector3& GetDefaultSizeModeFactor()
82 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
83 inline const Vector2& GetDefaultPreferredSize()
88 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
89 inline const Vector2& GetDefaultDimensionPadding()
94 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
96 } // unnamed namespace
99 * Struct to collect relayout variables
101 struct Actor::RelayoutData
104 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
106 // Set size negotiation defaults
107 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
109 resizePolicies[ i ] = ResizePolicy::DEFAULT;
110 useAssignedSize[ i ] = false;
111 negotiatedDimensions[ i ] = 0.0f;
112 dimensionNegotiated[ i ] = false;
113 dimensionDirty[ i ] = false;
114 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
115 dimensionPadding[ i ] = GetDefaultDimensionPadding();
116 minimumSize[ i ] = 0.0f;
117 maximumSize[ i ] = FLT_MAX;
121 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
122 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
124 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
126 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
128 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
130 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
131 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
133 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
134 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
136 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
138 Vector2 preferredSize; ///< The preferred size of the actor
140 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
142 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
143 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
146 namespace // unnamed namespace
152 * We want to discourage the use of property strings (minimize string comparisons),
153 * particularly for the default properties.
154 * Name Type writable animatable constraint-input enum for index-checking
156 DALI_PROPERTY_TABLE_BEGIN
157 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
158 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
159 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
160 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
161 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
162 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
163 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
164 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
165 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
166 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
167 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
168 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
169 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
170 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
171 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
172 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
173 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
174 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
175 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
176 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
177 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
178 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
179 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
180 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
181 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
182 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
183 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
184 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
185 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
186 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
187 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
188 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
189 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
190 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
191 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
192 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
193 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
194 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
195 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
196 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
197 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
198 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
199 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
200 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
201 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
202 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
203 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
204 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
205 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
206 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
207 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
208 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
209 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
210 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
211 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
212 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
213 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
214 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
215 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
219 const char* const SIGNAL_TOUCHED = "touched";
220 const char* const SIGNAL_HOVERED = "hovered";
221 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
222 const char* const SIGNAL_ON_STAGE = "onStage";
223 const char* const SIGNAL_OFF_STAGE = "offStage";
224 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
225 const char* const SIGNAL_TOUCH = "touch";
229 const char* const ACTION_SHOW = "show";
230 const char* const ACTION_HIDE = "hide";
232 BaseHandle CreateActor()
234 return Dali::Actor::New();
237 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
239 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
240 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
241 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
242 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
243 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
244 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
245 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
247 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
248 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
253 const Vector3& value;
256 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
257 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
258 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
259 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
260 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
261 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
262 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
263 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
264 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
265 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
266 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
268 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
269 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
270 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
271 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
272 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
273 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
275 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
276 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
277 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
278 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
279 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
280 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
282 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
283 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
286 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
288 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
289 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
297 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
299 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
300 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
303 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
305 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
306 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
307 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
308 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
311 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
313 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
315 size_t sizeIgnored = 0;
316 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
318 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
325 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
327 // Values are the same so just use the same table as anchor-point
328 return GetAnchorPointConstant( value, parentOrigin );
332 * @brief Extract a given dimension from a Vector2
334 * @param[in] values The values to extract from
335 * @param[in] dimension The dimension to extract
336 * @return Return the value for the dimension
338 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
342 case Dimension::WIDTH:
346 case Dimension::HEIGHT:
348 return values.height;
359 * @brief Extract a given dimension from a Vector3
361 * @param[in] values The values to extract from
362 * @param[in] dimension The dimension to extract
363 * @return Return the value for the dimension
365 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
367 return GetDimensionValue( values.GetVectorXY(), dimension );
371 * @brief Recursively emits the visibility-changed-signal on the actor tree.
372 * @param[in] actor The actor to emit the signal on
373 * @param[in] visible The new visibility of the actor
374 * @param[in] type Whether the actor's visible property has changed or a parent's
376 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
380 actor->EmitVisibilityChangedSignal( visible, type );
382 if( actor->GetChildCount() > 0 )
384 ActorContainer& children = actor->GetChildrenInternal();
385 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
387 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
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 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
819 return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
820 halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
823 return Vector2::ZERO;
826 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
828 // this flag is not animatable so keep the value
829 mPositionInheritanceMode = mode;
832 // mNode is being used in a separate thread; queue a message to set the value
833 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
837 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
839 // Cached for event-thread access
840 return mPositionInheritanceMode;
843 void Actor::SetInheritPosition( bool inherit )
845 if( mInheritPosition != inherit && NULL != mNode )
847 // non animateable so keep local copy
848 mInheritPosition = inherit;
849 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
853 bool Actor::IsPositionInherited() const
855 return mInheritPosition;
858 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
860 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
861 normalizedAxis.Normalize();
863 Quaternion orientation( angle, normalizedAxis );
865 SetOrientation( orientation );
868 void Actor::SetOrientation( const Quaternion& orientation )
870 mTargetOrientation = orientation;
874 // mNode is being used in a separate thread; queue a message to set the value & base value
875 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
879 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
881 RotateBy( Quaternion(angle, axis) );
884 void Actor::RotateBy( const Quaternion& relativeRotation )
886 mTargetOrientation *= Quaternion( relativeRotation );
890 // mNode is being used in a separate thread; queue a message to set the value & base value
891 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
895 const Quaternion& Actor::GetCurrentOrientation() const
899 // mNode is being used in a separate thread; copy the value from the previous update
900 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
903 return Quaternion::IDENTITY;
906 const Quaternion& Actor::GetCurrentWorldOrientation() const
910 // mNode is being used in a separate thread; copy the value from the previous update
911 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
914 return Quaternion::IDENTITY;
917 void Actor::SetScale( float scale )
919 SetScale( Vector3( scale, scale, scale ) );
922 void Actor::SetScale( float x, float y, float z )
924 SetScale( Vector3( x, y, z ) );
927 void Actor::SetScale( const Vector3& scale )
929 mTargetScale = scale;
933 // mNode is being used in a separate thread; queue a message to set the value & base value
934 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
938 void Actor::SetScaleX( float x )
944 // mNode is being used in a separate thread; queue a message to set the value & base value
945 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
949 void Actor::SetScaleY( float y )
955 // mNode is being used in a separate thread; queue a message to set the value & base value
956 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
960 void Actor::SetScaleZ( float z )
966 // mNode is being used in a separate thread; queue a message to set the value & base value
967 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
971 void Actor::ScaleBy(const Vector3& relativeScale)
973 mTargetScale *= relativeScale;
977 // mNode is being used in a separate thread; queue a message to set the value & base value
978 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
982 const Vector3& Actor::GetCurrentScale() const
986 // mNode is being used in a separate thread; copy the value from the previous update
987 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
993 const Vector3& Actor::GetCurrentWorldScale() const
997 // mNode is being used in a separate thread; copy the value from the previous update
998 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
1001 return Vector3::ONE;
1004 void Actor::SetInheritScale( bool inherit )
1007 if( mInheritScale != inherit && NULL != mNode )
1009 // non animateable so keep local copy
1010 mInheritScale = inherit;
1011 // mNode is being used in a separate thread; queue a message to set the value
1012 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
1016 bool Actor::IsScaleInherited() const
1018 return mInheritScale;
1021 Matrix Actor::GetCurrentWorldMatrix() const
1025 return mNode->GetWorldMatrix(0);
1028 return Matrix::IDENTITY;
1031 void Actor::SetVisible( bool visible )
1033 SetVisibleInternal( visible, SendMessage::TRUE );
1036 bool Actor::IsVisible() const
1040 // mNode is being used in a separate thread; copy the value from the previous update
1041 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1047 void Actor::SetOpacity( float opacity )
1049 mTargetColor.a = opacity;
1053 // mNode is being used in a separate thread; queue a message to set the value & base value
1054 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1058 float Actor::GetCurrentOpacity() const
1062 // mNode is being used in a separate thread; copy the value from the previous update
1063 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1069 ClippingMode::Type Actor::GetClippingMode() const
1071 return mClippingMode;
1074 unsigned int Actor::GetSortingDepth()
1076 return mSortedDepth;
1079 const Vector4& Actor::GetCurrentWorldColor() const
1083 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1086 return Color::WHITE;
1089 void Actor::SetColor( const Vector4& color )
1091 mTargetColor = color;
1095 // mNode is being used in a separate thread; queue a message to set the value & base value
1096 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1100 void Actor::SetColorRed( float red )
1102 mTargetColor.r = red;
1106 // mNode is being used in a separate thread; queue a message to set the value & base value
1107 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1111 void Actor::SetColorGreen( float green )
1113 mTargetColor.g = green;
1117 // mNode is being used in a separate thread; queue a message to set the value & base value
1118 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1122 void Actor::SetColorBlue( float blue )
1124 mTargetColor.b = blue;
1128 // mNode is being used in a separate thread; queue a message to set the value & base value
1129 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1133 const Vector4& Actor::GetCurrentColor() const
1137 // mNode is being used in a separate thread; copy the value from the previous update
1138 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1141 return Color::WHITE;
1144 void Actor::SetInheritOrientation( bool inherit )
1146 if( mInheritOrientation != inherit && NULL != mNode)
1148 // non animateable so keep local copy
1149 mInheritOrientation = inherit;
1150 // mNode is being used in a separate thread; queue a message to set the value
1151 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1155 bool Actor::IsOrientationInherited() const
1157 return mInheritOrientation;
1160 void Actor::SetSizeModeFactor( const Vector3& factor )
1162 EnsureRelayoutData();
1164 mRelayoutData->sizeModeFactor = factor;
1167 const Vector3& Actor::GetSizeModeFactor() const
1169 if ( mRelayoutData )
1171 return mRelayoutData->sizeModeFactor;
1174 return GetDefaultSizeModeFactor();
1177 void Actor::SetColorMode( ColorMode colorMode )
1179 // non animateable so keep local copy
1180 mColorMode = colorMode;
1183 // mNode is being used in a separate thread; queue a message to set the value
1184 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1188 ColorMode Actor::GetColorMode() const
1190 // we have cached copy
1194 void Actor::SetSize( float width, float height )
1196 SetSize( Vector2( width, height ) );
1199 void Actor::SetSize( float width, float height, float depth )
1201 SetSize( Vector3( width, height, depth ) );
1204 void Actor::SetSize( const Vector2& size )
1206 SetSize( Vector3( size.width, size.height, 0.f ) );
1209 void Actor::SetSizeInternal( const Vector2& size )
1211 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1214 void Actor::SetSize( const Vector3& size )
1216 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1218 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1219 SetPreferredSize( size.GetVectorXY() );
1223 SetSizeInternal( size );
1227 void Actor::SetSizeInternal( const Vector3& size )
1229 // dont allow recursive loop
1230 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1231 // 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
1232 if( ( NULL != mNode )&&
1233 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1234 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1235 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1239 // mNode is being used in a separate thread; queue a message to set the value & base value
1240 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1242 // Notification for derived classes
1243 mInsideOnSizeSet = true;
1244 OnSizeSet( mTargetSize );
1245 mInsideOnSizeSet = false;
1247 // Raise a relayout request if the flag is not locked
1248 if( mRelayoutData && !mRelayoutData->insideRelayout )
1255 void Actor::SetWidth( float width )
1257 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1259 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1260 mRelayoutData->preferredSize.width = width;
1264 mTargetSize.width = width;
1268 // mNode is being used in a separate thread; queue a message to set the value & base value
1269 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1276 void Actor::SetHeight( float height )
1278 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1280 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1281 mRelayoutData->preferredSize.height = height;
1285 mTargetSize.height = height;
1289 // mNode is being used in a separate thread; queue a message to set the value & base value
1290 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1297 void Actor::SetDepth( float depth )
1299 mTargetSize.depth = depth;
1303 // mNode is being used in a separate thread; queue a message to set the value & base value
1304 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1308 Vector3 Actor::GetTargetSize() const
1310 Vector3 size = mTargetSize;
1312 // Should return preferred size if size is fixed as set by SetSize
1313 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1315 size.width = GetPreferredSize().width;
1317 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1319 size.height = GetPreferredSize().height;
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 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1355 mRelayoutData->useAssignedSize[ i ] = true;
1359 mRelayoutData->resizePolicies[ i ] = policy;
1360 mRelayoutData->useAssignedSize[ i ] = false;
1365 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1367 if( dimension & Dimension::WIDTH )
1369 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1372 if( dimension & Dimension::HEIGHT )
1374 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1378 // If calling SetResizePolicy, assume we want relayout enabled
1379 SetRelayoutEnabled( true );
1381 // If the resize policy is set to be FIXED, the preferred size
1382 // should be overrided by the target size. Otherwise the target
1383 // size should be overrided by the preferred size.
1385 if( dimension & Dimension::WIDTH )
1387 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1389 mRelayoutData->preferredSize.width = mTargetSize.width;
1391 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1393 mTargetSize.width = mRelayoutData->preferredSize.width;
1397 if( dimension & Dimension::HEIGHT )
1399 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1401 mRelayoutData->preferredSize.height = mTargetSize.height;
1403 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1405 mTargetSize.height = mRelayoutData->preferredSize.height;
1409 OnSetResizePolicy( policy, dimension );
1411 // Trigger relayout on this control
1415 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1417 if ( mRelayoutData )
1419 // If more than one dimension is requested, just return the first one found
1420 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1422 if( ( dimension & ( 1 << i ) ) )
1424 if( mRelayoutData->useAssignedSize[ i ] )
1426 return ResizePolicy::USE_ASSIGNED_SIZE;
1430 return mRelayoutData->resizePolicies[ i ];
1436 return ResizePolicy::DEFAULT;
1439 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1441 EnsureRelayoutData();
1443 mRelayoutData->sizeSetPolicy = policy;
1446 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1448 if ( mRelayoutData )
1450 return mRelayoutData->sizeSetPolicy;
1453 return DEFAULT_SIZE_SCALE_POLICY;
1456 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1458 EnsureRelayoutData();
1460 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1462 if( dimension & ( 1 << i ) )
1464 mRelayoutData->dimensionDependencies[ i ] = dependency;
1469 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1471 if ( mRelayoutData )
1473 // If more than one dimension is requested, just return the first one found
1474 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1476 if( ( dimension & ( 1 << i ) ) )
1478 return mRelayoutData->dimensionDependencies[ i ];
1483 return Dimension::ALL_DIMENSIONS; // Default
1486 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1488 // If relayout data has not been allocated yet and the client is requesting
1489 // to disable it, do nothing
1490 if( mRelayoutData || relayoutEnabled )
1492 EnsureRelayoutData();
1494 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1496 mRelayoutData->relayoutEnabled = relayoutEnabled;
1500 bool Actor::IsRelayoutEnabled() const
1502 // Assume that if relayout data has not been allocated yet then
1503 // relayout is disabled
1504 return mRelayoutData && mRelayoutData->relayoutEnabled;
1507 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1509 EnsureRelayoutData();
1511 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1513 if( dimension & ( 1 << i ) )
1515 mRelayoutData->dimensionDirty[ i ] = dirty;
1520 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1522 if ( mRelayoutData )
1524 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1526 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1536 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1538 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1541 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1543 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1546 unsigned int Actor::AddRenderer( Renderer& renderer )
1550 mRenderers = new RendererContainer;
1553 unsigned int index = mRenderers->size();
1554 RendererPtr rendererPtr = RendererPtr( &renderer );
1555 mRenderers->push_back( rendererPtr );
1556 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1560 unsigned int Actor::GetRendererCount() const
1562 unsigned int rendererCount(0);
1565 rendererCount = mRenderers->size();
1568 return rendererCount;
1571 RendererPtr Actor::GetRendererAt( unsigned int index )
1573 RendererPtr renderer;
1574 if( index < GetRendererCount() )
1576 renderer = ( *mRenderers )[ index ];
1582 void Actor::RemoveRenderer( Renderer& renderer )
1586 RendererIter end = mRenderers->end();
1587 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1589 if( (*iter).Get() == &renderer )
1591 mRenderers->erase( iter );
1592 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1599 void Actor::RemoveRenderer( unsigned int index )
1601 if( index < GetRendererCount() )
1603 RendererPtr renderer = ( *mRenderers )[ index ];
1604 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1605 mRenderers->erase( mRenderers->begin()+index );
1609 bool Actor::IsOverlay() const
1611 return ( DrawMode::OVERLAY_2D == mDrawMode );
1614 void Actor::SetDrawMode( DrawMode::Type drawMode )
1616 // this flag is not animatable so keep the value
1617 mDrawMode = drawMode;
1618 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1620 // mNode is being used in a separate thread; queue a message to set the value
1621 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1625 DrawMode::Type Actor::GetDrawMode() const
1630 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1632 // only valid when on-stage
1633 StagePtr stage = Stage::GetCurrent();
1634 if( stage && OnStage() )
1636 const RenderTaskList& taskList = stage->GetRenderTaskList();
1638 Vector2 converted( screenX, screenY );
1640 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1641 const int taskCount = taskList.GetTaskCount();
1642 for( int i = taskCount - 1; i >= 0; --i )
1644 Dali::RenderTask task = taskList.GetTask( i );
1645 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1647 // found a task where this conversion was ok so return
1655 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1657 bool retval = false;
1658 // only valid when on-stage
1661 CameraActor* camera = renderTask.GetCameraActor();
1665 renderTask.GetViewport( viewport );
1667 // need to translate coordinates to render tasks coordinate space
1668 Vector2 converted( screenX, screenY );
1669 if( renderTask.TranslateCoordinates( converted ) )
1671 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1678 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1680 // Early-out if mNode is NULL
1686 // Get the ModelView matrix
1688 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1690 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1691 Matrix invertedMvp( false/*don't init*/);
1692 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1693 bool success = invertedMvp.Invert();
1695 // Convert to GL coordinates
1696 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1701 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1708 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1714 if( XyPlaneIntersect( nearPos, farPos, local ) )
1716 Vector3 size = GetCurrentSize();
1717 localX = local.x + size.x * 0.5f;
1718 localY = local.y + size.y * 0.5f;
1729 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1732 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1734 Mathematical Formulation
1736 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1738 ( p - c ) dot ( p - c ) = r^2
1740 Given a ray with a point of origin 'o', and a direction vector 'd':
1742 ray(t) = o + td, t >= 0
1744 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1746 (o + td - c ) dot ( o + td - c ) = r^2
1748 To solve for t we first expand the above into a more recognisable quadratic equation form
1750 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1759 B = 2( o - c ) dot d
1760 C = ( o - c ) dot ( o - c ) - r^2
1762 which can be solved using a standard quadratic formula.
1764 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1766 Practical Simplification
1768 In a renderer, we often differentiate between world space and object space. In the object space
1769 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1770 into object space, the mathematical solution presented above can be simplified significantly.
1772 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1776 and we can find the t at which the (transformed) ray intersects the sphere by
1778 ( o + td ) dot ( o + td ) = r^2
1780 According to the reasoning above, we expand the above quadratic equation into the general form
1784 which now has coefficients:
1791 // Early out if mNode is NULL
1797 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1799 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1800 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1801 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1803 // Compute the radius is not needed, square radius it's enough.
1804 const Vector3& size( mNode->GetSize( bufferIndex ) );
1806 // Scale the sphere.
1807 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1809 const float width = size.width * scale.width;
1810 const float height = size.height * scale.height;
1812 float squareSphereRadius = 0.5f * ( width * width + height * height );
1814 float a = rayDir.Dot( rayDir ); // a
1815 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1816 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1818 return ( b2 * b2 - a * c ) >= 0.f;
1821 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1825 if( OnStage() && NULL != mNode )
1827 // Transforms the ray to the local reference system.
1828 // Calculate the inverse of Model matrix
1829 Matrix invModelMatrix( false/*don't init*/);
1831 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1832 invModelMatrix = mNode->GetWorldMatrix(0);
1833 invModelMatrix.Invert();
1835 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1836 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1838 // Test with the actor's XY plane (Normal = 0 0 1 1).
1840 float a = -rayOriginLocal.z;
1841 float b = rayDirLocal.z;
1843 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1845 // Ray travels distance * rayDirLocal to intersect with plane.
1848 const Vector3& size = mNode->GetSize( bufferIndex );
1850 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1851 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1853 // Test with the actor's geometry.
1854 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1861 void Actor::SetLeaveRequired( bool required )
1863 mLeaveRequired = required;
1866 bool Actor::GetLeaveRequired() const
1868 return mLeaveRequired;
1871 void Actor::SetKeyboardFocusable( bool focusable )
1873 mKeyboardFocusable = focusable;
1876 bool Actor::IsKeyboardFocusable() const
1878 return mKeyboardFocusable;
1881 bool Actor::GetTouchRequired() const
1883 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1886 bool Actor::GetHoverRequired() const
1888 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1891 bool Actor::GetWheelEventRequired() const
1893 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1896 bool Actor::IsHittable() const
1898 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1901 ActorGestureData& Actor::GetGestureData()
1903 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1904 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1905 if( NULL == mGestureData )
1907 mGestureData = new ActorGestureData;
1909 return *mGestureData;
1912 bool Actor::IsGestureRequred( Gesture::Type type ) const
1914 return mGestureData && mGestureData->IsGestureRequred( type );
1917 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1919 bool consumed = false;
1921 if( !mTouchSignal.Empty() )
1923 Dali::Actor handle( this );
1924 consumed = mTouchSignal.Emit( handle, touch );
1927 if( !mTouchedSignal.Empty() )
1929 Dali::Actor handle( this );
1930 consumed |= mTouchedSignal.Emit( handle, event );
1935 // Notification for derived classes
1936 consumed = OnTouchEvent( event ); // TODO
1942 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1944 bool consumed = false;
1946 if( !mHoveredSignal.Empty() )
1948 Dali::Actor handle( this );
1949 consumed = mHoveredSignal.Emit( handle, event );
1954 // Notification for derived classes
1955 consumed = OnHoverEvent( event );
1961 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1963 bool consumed = false;
1965 if( !mWheelEventSignal.Empty() )
1967 Dali::Actor handle( this );
1968 consumed = mWheelEventSignal.Emit( handle, event );
1973 // Notification for derived classes
1974 consumed = OnWheelEvent( event );
1980 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1982 if( ! mVisibilityChangedSignal.Empty() )
1984 Dali::Actor handle( this );
1985 mVisibilityChangedSignal.Emit( handle, visible, type );
1989 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1991 return mTouchedSignal;
1994 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1996 return mTouchSignal;
1999 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2001 return mHoveredSignal;
2004 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
2006 return mWheelEventSignal;
2009 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2011 return mOnStageSignal;
2014 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2016 return mOffStageSignal;
2019 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2021 return mOnRelayoutSignal;
2024 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
2026 return mVisibilityChangedSignal;
2029 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2031 bool connected( true );
2032 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2034 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2036 actor->TouchedSignal().Connect( tracker, functor );
2038 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2040 actor->HoveredSignal().Connect( tracker, functor );
2042 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2044 actor->WheelEventSignal().Connect( tracker, functor );
2046 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2048 actor->OnStageSignal().Connect( tracker, functor );
2050 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2052 actor->OffStageSignal().Connect( tracker, functor );
2054 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2056 actor->OnRelayoutSignal().Connect( tracker, functor );
2058 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2060 actor->TouchSignal().Connect( tracker, functor );
2064 // signalName does not match any signal
2071 Actor::Actor( DerivedType derivedType )
2076 mParentOrigin( NULL ),
2077 mAnchorPoint( NULL ),
2078 mRelayoutData( NULL ),
2079 mGestureData( NULL ),
2080 mTargetOrientation( Quaternion::IDENTITY ),
2081 mTargetColor( Color::WHITE ),
2082 mTargetSize( Vector3::ZERO ),
2083 mTargetPosition( Vector3::ZERO ),
2084 mTargetScale( Vector3::ONE ),
2086 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2089 mIsRoot( ROOT_LAYER == derivedType ),
2090 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2091 mIsOnStage( false ),
2093 mLeaveRequired( false ),
2094 mKeyboardFocusable( false ),
2095 mDerivedRequiresTouch( false ),
2096 mDerivedRequiresHover( false ),
2097 mDerivedRequiresWheelEvent( false ),
2098 mOnStageSignalled( false ),
2099 mInsideOnSizeSet( false ),
2100 mInheritPosition( true ),
2101 mInheritOrientation( true ),
2102 mInheritScale( true ),
2103 mPositionUsesAnchorPoint( true ),
2105 mDrawMode( DrawMode::NORMAL ),
2106 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2107 mColorMode( Node::DEFAULT_COLOR_MODE ),
2108 mClippingMode( ClippingMode::DISABLED )
2112 void Actor::Initialize()
2114 // Node creation, keep raw-pointer to Node for messaging
2115 mNode = CreateNode();
2116 OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
2117 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
2121 GetEventThreadServices().RegisterObject( this );
2126 // Remove mParent pointers from children even if we're destroying core,
2127 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2130 ActorConstIter endIter = mChildren->end();
2131 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2133 (*iter)->SetParent( NULL );
2139 // Guard to allow handle destruction after Core has been destroyed
2140 if( EventThreadServices::IsCoreRunning() )
2144 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2145 mNode = NULL; // Node is about to be destroyed
2148 GetEventThreadServices().UnregisterObject( this );
2151 // Cleanup optional gesture data
2152 delete mGestureData;
2154 // Cleanup optional parent origin and anchor
2155 delete mParentOrigin;
2156 delete mAnchorPoint;
2158 // Delete optional relayout data
2161 delete mRelayoutData;
2165 void Actor::ConnectToStage( unsigned int parentDepth )
2167 // This container is used instead of walking the Actor hierarchy.
2168 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2169 ActorContainer connectionList;
2171 StagePtr stage = Stage::GetCurrent();
2174 stage->RequestRebuildDepthTree();
2177 // This stage is atomic i.e. not interrupted by user callbacks.
2178 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2180 // Notify applications about the newly connected actors.
2181 const ActorIter endIter = connectionList.end();
2182 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2184 (*iter)->NotifyStageConnection();
2190 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2192 DALI_ASSERT_ALWAYS( !OnStage() );
2197 ConnectToSceneGraph();
2199 // Notification for internal derived classes
2200 OnStageConnectionInternal();
2202 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2203 connectionList.push_back( ActorPtr( this ) );
2205 // Recursively connect children
2208 ActorConstIter endIter = mChildren->end();
2209 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2211 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2217 * This method is called when the Actor is connected to the Stage.
2218 * The parent must have added its Node to the scene-graph.
2219 * The child must connect its Node to the parent's Node.
2220 * This is recursive; the child calls ConnectToStage() for its children.
2222 void Actor::ConnectToSceneGraph()
2224 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2228 // Reparent Node in next Update
2229 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2232 // Request relayout on all actors that are added to the scenegraph
2235 // Notification for Object::Observers
2239 void Actor::NotifyStageConnection()
2241 // Actors can be removed (in a callback), before the on-stage stage is reported.
2242 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2243 if( OnStage() && !mOnStageSignalled )
2245 // Notification for external (CustomActor) derived classes
2246 OnStageConnectionExternal( mDepth );
2248 if( !mOnStageSignal.Empty() )
2250 Dali::Actor handle( this );
2251 mOnStageSignal.Emit( handle );
2254 // Guard against Remove during callbacks
2257 mOnStageSignalled = true; // signal required next time Actor is removed
2262 void Actor::DisconnectFromStage()
2264 // This container is used instead of walking the Actor hierachy.
2265 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2266 ActorContainer disconnectionList;
2268 StagePtr stage = Stage::GetCurrent();
2271 stage->RequestRebuildDepthTree();
2274 // This stage is atomic i.e. not interrupted by user callbacks
2275 RecursiveDisconnectFromStage( disconnectionList );
2277 // Notify applications about the newly disconnected actors.
2278 const ActorIter endIter = disconnectionList.end();
2279 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2281 (*iter)->NotifyStageDisconnection();
2285 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2287 DALI_ASSERT_ALWAYS( OnStage() );
2289 // Recursively disconnect children
2292 ActorConstIter endIter = mChildren->end();
2293 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2295 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2299 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2300 disconnectionList.push_back( ActorPtr( this ) );
2302 // Notification for internal derived classes
2303 OnStageDisconnectionInternal();
2305 DisconnectFromSceneGraph();
2311 * This method is called by an actor or its parent, before a node removal message is sent.
2312 * This is recursive; the child calls DisconnectFromStage() for its children.
2314 void Actor::DisconnectFromSceneGraph()
2316 // Notification for Object::Observers
2317 OnSceneObjectRemove();
2320 void Actor::NotifyStageDisconnection()
2322 // Actors can be added (in a callback), before the off-stage state is reported.
2323 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2324 // only do this step if there is a stage, i.e. Core is not being shut down
2325 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2327 // Notification for external (CustomeActor) derived classes
2328 OnStageDisconnectionExternal();
2330 if( !mOffStageSignal.Empty() )
2332 Dali::Actor handle( this );
2333 mOffStageSignal.Emit( handle );
2336 // Guard against Add during callbacks
2339 mOnStageSignalled = false; // signal required next time Actor is added
2344 bool Actor::IsNodeConnected() const
2346 bool connected( false );
2348 if( OnStage() && ( NULL != mNode ) )
2350 if( IsRoot() || mNode->GetParent() )
2359 // This method initiates traversal of the actor tree using depth-first
2360 // traversal to set a depth index based on traversal order. It sends a
2361 // single message to update manager to update all the actor's nodes in
2362 // this tree with the depth index. The sceneGraphNodeDepths vector's
2363 // elements are ordered by depth, and could be used to reduce sorting
2364 // in the update thread.
2365 void Actor::RebuildDepthTree()
2367 DALI_LOG_TIMER_START(depthTimer);
2369 // Vector of scene-graph nodes and their depths to send to UpdateManager
2370 // in a single message
2371 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2374 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2376 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2377 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2380 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
2382 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2383 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
2385 // Create/add to children of this node
2388 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2390 Actor* childActor = (*it).Get();
2392 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2397 unsigned int Actor::GetDefaultPropertyCount() const
2399 return DEFAULT_PROPERTY_COUNT;
2402 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2404 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2406 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2408 indices.PushBack( i );
2412 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2414 if( index < DEFAULT_PROPERTY_COUNT )
2416 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2422 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2424 Property::Index index = Property::INVALID_INDEX;
2426 // Look for name in default properties
2427 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2429 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2430 if( 0 == name.compare( property->name ) )
2440 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2442 if( index < DEFAULT_PROPERTY_COUNT )
2444 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2450 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2452 if( index < DEFAULT_PROPERTY_COUNT )
2454 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2460 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2462 if( index < DEFAULT_PROPERTY_COUNT )
2464 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2470 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2472 if( index < DEFAULT_PROPERTY_COUNT )
2474 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2477 // index out of range...return Property::NONE
2478 return Property::NONE;
2481 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2485 case Dali::Actor::Property::PARENT_ORIGIN:
2487 Property::Type type = property.GetType();
2488 if( type == Property::VECTOR3 )
2490 SetParentOrigin( property.Get< Vector3 >() );
2492 else if ( type == Property::STRING )
2494 std::string parentOriginString;
2495 property.Get( parentOriginString );
2496 Vector3 parentOrigin;
2497 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2499 SetParentOrigin( parentOrigin );
2505 case Dali::Actor::Property::PARENT_ORIGIN_X:
2507 SetParentOriginX( property.Get< float >() );
2511 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2513 SetParentOriginY( property.Get< float >() );
2517 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2519 SetParentOriginZ( property.Get< float >() );
2523 case Dali::Actor::Property::ANCHOR_POINT:
2525 Property::Type type = property.GetType();
2526 if( type == Property::VECTOR3 )
2528 SetAnchorPoint( property.Get< Vector3 >() );
2530 else if ( type == Property::STRING )
2532 std::string anchorPointString;
2533 property.Get( anchorPointString );
2535 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2537 SetAnchorPoint( anchor );
2543 case Dali::Actor::Property::ANCHOR_POINT_X:
2545 SetAnchorPointX( property.Get< float >() );
2549 case Dali::Actor::Property::ANCHOR_POINT_Y:
2551 SetAnchorPointY( property.Get< float >() );
2555 case Dali::Actor::Property::ANCHOR_POINT_Z:
2557 SetAnchorPointZ( property.Get< float >() );
2561 case Dali::Actor::Property::SIZE:
2563 SetSize( property.Get< Vector3 >() );
2567 case Dali::Actor::Property::SIZE_WIDTH:
2569 SetWidth( property.Get< float >() );
2573 case Dali::Actor::Property::SIZE_HEIGHT:
2575 SetHeight( property.Get< float >() );
2579 case Dali::Actor::Property::SIZE_DEPTH:
2581 SetDepth( property.Get< float >() );
2585 case Dali::Actor::Property::POSITION:
2587 SetPosition( property.Get< Vector3 >() );
2591 case Dali::Actor::Property::POSITION_X:
2593 SetX( property.Get< float >() );
2597 case Dali::Actor::Property::POSITION_Y:
2599 SetY( property.Get< float >() );
2603 case Dali::Actor::Property::POSITION_Z:
2605 SetZ( property.Get< float >() );
2609 case Dali::Actor::Property::ORIENTATION:
2611 SetOrientation( property.Get< Quaternion >() );
2615 case Dali::Actor::Property::SCALE:
2617 SetScale( property.Get< Vector3 >() );
2621 case Dali::Actor::Property::SCALE_X:
2623 SetScaleX( property.Get< float >() );
2627 case Dali::Actor::Property::SCALE_Y:
2629 SetScaleY( property.Get< float >() );
2633 case Dali::Actor::Property::SCALE_Z:
2635 SetScaleZ( property.Get< float >() );
2639 case Dali::Actor::Property::VISIBLE:
2641 SetVisible( property.Get< bool >() );
2645 case Dali::Actor::Property::COLOR:
2647 SetColor( property.Get< Vector4 >() );
2651 case Dali::Actor::Property::COLOR_RED:
2653 SetColorRed( property.Get< float >() );
2657 case Dali::Actor::Property::COLOR_GREEN:
2659 SetColorGreen( property.Get< float >() );
2663 case Dali::Actor::Property::COLOR_BLUE:
2665 SetColorBlue( property.Get< float >() );
2669 case Dali::Actor::Property::COLOR_ALPHA:
2670 case Dali::DevelActor::Property::OPACITY:
2673 if( property.Get( value ) )
2675 SetOpacity( value );
2680 case Dali::Actor::Property::NAME:
2682 SetName( property.Get< std::string >() );
2686 case Dali::Actor::Property::SENSITIVE:
2688 SetSensitive( property.Get< bool >() );
2692 case Dali::Actor::Property::LEAVE_REQUIRED:
2694 SetLeaveRequired( property.Get< bool >() );
2698 case Dali::Actor::Property::INHERIT_POSITION:
2700 SetInheritPosition( property.Get< bool >() );
2704 case Dali::Actor::Property::INHERIT_ORIENTATION:
2706 SetInheritOrientation( property.Get< bool >() );
2710 case Dali::Actor::Property::INHERIT_SCALE:
2712 SetInheritScale( property.Get< bool >() );
2716 case Dali::Actor::Property::COLOR_MODE:
2718 ColorMode mode = mColorMode;
2719 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2721 SetColorMode( mode );
2726 case Dali::Actor::Property::POSITION_INHERITANCE:
2728 PositionInheritanceMode mode = mPositionInheritanceMode;
2729 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2731 SetPositionInheritanceMode( mode );
2736 case Dali::Actor::Property::DRAW_MODE:
2738 DrawMode::Type mode = mDrawMode;
2739 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2741 SetDrawMode( mode );
2746 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2748 SetSizeModeFactor( property.Get< Vector3 >() );
2752 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2754 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2755 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2757 SetResizePolicy( type, Dimension::WIDTH );
2762 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2764 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2765 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2767 SetResizePolicy( type, Dimension::HEIGHT );
2772 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2774 SizeScalePolicy::Type type;
2775 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2777 SetSizeScalePolicy( type );
2782 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2784 if( property.Get< bool >() )
2786 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2791 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2793 if( property.Get< bool >() )
2795 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2800 case Dali::Actor::Property::PADDING:
2802 Vector4 padding = property.Get< Vector4 >();
2803 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2804 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2808 case Dali::Actor::Property::MINIMUM_SIZE:
2810 Vector2 size = property.Get< Vector2 >();
2811 SetMinimumSize( size.x, Dimension::WIDTH );
2812 SetMinimumSize( size.y, Dimension::HEIGHT );
2816 case Dali::Actor::Property::MAXIMUM_SIZE:
2818 Vector2 size = property.Get< Vector2 >();
2819 SetMaximumSize( size.x, Dimension::WIDTH );
2820 SetMaximumSize( size.y, Dimension::HEIGHT );
2824 case Dali::DevelActor::Property::SIBLING_ORDER:
2828 if( property.Get( value ) )
2830 SetSiblingOrder( value );
2835 case Dali::Actor::Property::CLIPPING_MODE:
2837 ClippingMode::Type convertedValue = mClippingMode;
2838 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2840 mClippingMode = convertedValue;
2843 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2849 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2852 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2854 mPositionUsesAnchorPoint = value;
2857 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2865 // this can happen in the case of a non-animatable default property so just do nothing
2871 // TODO: This method needs to be removed
2872 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2874 switch( entry.GetType() )
2876 case Property::BOOLEAN:
2878 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2879 DALI_ASSERT_DEBUG( NULL != property );
2881 // property is being used in a separate thread; queue a message to set the property
2882 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2887 case Property::INTEGER:
2889 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2890 DALI_ASSERT_DEBUG( NULL != property );
2892 // property is being used in a separate thread; queue a message to set the property
2893 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2898 case Property::FLOAT:
2900 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2901 DALI_ASSERT_DEBUG( NULL != property );
2903 // property is being used in a separate thread; queue a message to set the property
2904 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2909 case Property::VECTOR2:
2911 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2912 DALI_ASSERT_DEBUG( NULL != property );
2914 // property is being used in a separate thread; queue a message to set the property
2915 if(entry.componentIndex == 0)
2917 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2919 else if(entry.componentIndex == 1)
2921 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2925 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2931 case Property::VECTOR3:
2933 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2934 DALI_ASSERT_DEBUG( NULL != property );
2936 // property is being used in a separate thread; queue a message to set the property
2937 if(entry.componentIndex == 0)
2939 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2941 else if(entry.componentIndex == 1)
2943 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2945 else if(entry.componentIndex == 2)
2947 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2951 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2957 case Property::VECTOR4:
2959 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2960 DALI_ASSERT_DEBUG( NULL != property );
2962 // property is being used in a separate thread; queue a message to set the property
2963 if(entry.componentIndex == 0)
2965 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2967 else if(entry.componentIndex == 1)
2969 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2971 else if(entry.componentIndex == 2)
2973 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2975 else if(entry.componentIndex == 3)
2977 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2981 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2987 case Property::ROTATION:
2989 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2990 DALI_ASSERT_DEBUG( NULL != property );
2992 // property is being used in a separate thread; queue a message to set the property
2993 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2998 case Property::MATRIX:
3000 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3001 DALI_ASSERT_DEBUG( NULL != property );
3003 // property is being used in a separate thread; queue a message to set the property
3004 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
3009 case Property::MATRIX3:
3011 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3012 DALI_ASSERT_DEBUG( NULL != property );
3014 // property is being used in a separate thread; queue a message to set the property
3015 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
3022 // nothing to do for other types
3027 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3029 Property::Value value;
3031 if( ! GetCachedPropertyValue( index, value ) )
3033 // If property value is not stored in the event-side, then it must be a scene-graph only property
3034 GetCurrentPropertyValue( index, value );
3040 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3042 Property::Value value;
3044 if( ! GetCurrentPropertyValue( index, value ) )
3046 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3047 GetCachedPropertyValue( index, value );
3053 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3055 switch( animationType )
3058 case Animation::BETWEEN:
3062 case Dali::Actor::Property::SIZE:
3064 if( value.Get( mTargetSize ) )
3066 // Notify deriving classes
3067 OnSizeAnimation( animation, mTargetSize );
3072 case Dali::Actor::Property::SIZE_WIDTH:
3074 if( value.Get( mTargetSize.width ) )
3076 // Notify deriving classes
3077 OnSizeAnimation( animation, mTargetSize );
3082 case Dali::Actor::Property::SIZE_HEIGHT:
3084 if( value.Get( mTargetSize.height ) )
3086 // Notify deriving classes
3087 OnSizeAnimation( animation, mTargetSize );
3092 case Dali::Actor::Property::SIZE_DEPTH:
3094 if( value.Get( mTargetSize.depth ) )
3096 // Notify deriving classes
3097 OnSizeAnimation( animation, mTargetSize );
3102 case Dali::Actor::Property::POSITION:
3104 value.Get( mTargetPosition );
3108 case Dali::Actor::Property::POSITION_X:
3110 value.Get( mTargetPosition.x );
3114 case Dali::Actor::Property::POSITION_Y:
3116 value.Get( mTargetPosition.y );
3120 case Dali::Actor::Property::POSITION_Z:
3122 value.Get( mTargetPosition.z );
3126 case Dali::Actor::Property::ORIENTATION:
3128 value.Get( mTargetOrientation );
3132 case Dali::Actor::Property::SCALE:
3134 value.Get( mTargetScale );
3138 case Dali::Actor::Property::SCALE_X:
3140 value.Get( mTargetScale.x );
3144 case Dali::Actor::Property::SCALE_Y:
3146 value.Get( mTargetScale.y );
3150 case Dali::Actor::Property::SCALE_Z:
3152 value.Get( mTargetScale.z );
3156 case Dali::Actor::Property::VISIBLE:
3158 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3162 case Dali::Actor::Property::COLOR:
3164 value.Get( mTargetColor );
3168 case Dali::Actor::Property::COLOR_RED:
3170 value.Get( mTargetColor.r );
3174 case Dali::Actor::Property::COLOR_GREEN:
3176 value.Get( mTargetColor.g );
3180 case Dali::Actor::Property::COLOR_BLUE:
3182 value.Get( mTargetColor.b );
3186 case Dali::Actor::Property::COLOR_ALPHA:
3187 case Dali::DevelActor::Property::OPACITY:
3189 value.Get( mTargetColor.a );
3195 // Not an animatable property. Do nothing.
3206 case Dali::Actor::Property::SIZE:
3208 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3210 // Notify deriving classes
3211 OnSizeAnimation( animation, mTargetSize );
3216 case Dali::Actor::Property::SIZE_WIDTH:
3218 if( AdjustValue< float >( mTargetSize.width, value ) )
3220 // Notify deriving classes
3221 OnSizeAnimation( animation, mTargetSize );
3226 case Dali::Actor::Property::SIZE_HEIGHT:
3228 if( AdjustValue< float >( mTargetSize.height, value ) )
3230 // Notify deriving classes
3231 OnSizeAnimation( animation, mTargetSize );
3236 case Dali::Actor::Property::SIZE_DEPTH:
3238 if( AdjustValue< float >( mTargetSize.depth, value ) )
3240 // Notify deriving classes
3241 OnSizeAnimation( animation, mTargetSize );
3246 case Dali::Actor::Property::POSITION:
3248 AdjustValue< Vector3 >( mTargetPosition, value );
3252 case Dali::Actor::Property::POSITION_X:
3254 AdjustValue< float >( mTargetPosition.x, value );
3258 case Dali::Actor::Property::POSITION_Y:
3260 AdjustValue< float >( mTargetPosition.y, value );
3264 case Dali::Actor::Property::POSITION_Z:
3266 AdjustValue< float >( mTargetPosition.z, value );
3270 case Dali::Actor::Property::ORIENTATION:
3272 Quaternion relativeValue;
3273 if( value.Get( relativeValue ) )
3275 mTargetOrientation *= relativeValue;
3280 case Dali::Actor::Property::SCALE:
3282 AdjustValue< Vector3 >( mTargetScale, value );
3286 case Dali::Actor::Property::SCALE_X:
3288 AdjustValue< float >( mTargetScale.x, value );
3292 case Dali::Actor::Property::SCALE_Y:
3294 AdjustValue< float >( mTargetScale.y, value );
3298 case Dali::Actor::Property::SCALE_Z:
3300 AdjustValue< float >( mTargetScale.z, value );
3304 case Dali::Actor::Property::VISIBLE:
3306 bool relativeValue = false;
3307 if( value.Get( relativeValue ) )
3309 bool visible = mVisible || relativeValue;
3310 SetVisibleInternal( visible, SendMessage::FALSE );
3315 case Dali::Actor::Property::COLOR:
3317 AdjustValue< Vector4 >( mTargetColor, value );
3321 case Dali::Actor::Property::COLOR_RED:
3323 AdjustValue< float >( mTargetColor.r, value );
3327 case Dali::Actor::Property::COLOR_GREEN:
3329 AdjustValue< float >( mTargetColor.g, value );
3333 case Dali::Actor::Property::COLOR_BLUE:
3335 AdjustValue< float >( mTargetColor.b, value );
3339 case Dali::Actor::Property::COLOR_ALPHA:
3340 case Dali::DevelActor::Property::OPACITY:
3342 AdjustValue< float >( mTargetColor.a, value );
3348 // Not an animatable property. Do nothing.
3357 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3362 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3364 // This method should only return an object connected to the scene-graph
3365 return OnStage() ? mNode : NULL;
3368 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3370 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3372 const PropertyBase* property( NULL );
3374 // This method should only return a property of an object connected to the scene-graph
3380 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3382 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3383 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3385 property = animatable->GetSceneGraphProperty();
3387 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3388 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3390 CustomPropertyMetadata* custom = FindCustomProperty( index );
3391 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3393 property = custom->GetSceneGraphProperty();
3395 else if( NULL != mNode )
3399 case Dali::Actor::Property::SIZE:
3400 property = &mNode->mSize;
3403 case Dali::Actor::Property::SIZE_WIDTH:
3404 property = &mNode->mSize;
3407 case Dali::Actor::Property::SIZE_HEIGHT:
3408 property = &mNode->mSize;
3411 case Dali::Actor::Property::SIZE_DEPTH:
3412 property = &mNode->mSize;
3415 case Dali::Actor::Property::POSITION:
3416 property = &mNode->mPosition;
3419 case Dali::Actor::Property::POSITION_X:
3420 property = &mNode->mPosition;
3423 case Dali::Actor::Property::POSITION_Y:
3424 property = &mNode->mPosition;
3427 case Dali::Actor::Property::POSITION_Z:
3428 property = &mNode->mPosition;
3431 case Dali::Actor::Property::ORIENTATION:
3432 property = &mNode->mOrientation;
3435 case Dali::Actor::Property::SCALE:
3436 property = &mNode->mScale;
3439 case Dali::Actor::Property::SCALE_X:
3440 property = &mNode->mScale;
3443 case Dali::Actor::Property::SCALE_Y:
3444 property = &mNode->mScale;
3447 case Dali::Actor::Property::SCALE_Z:
3448 property = &mNode->mScale;
3451 case Dali::Actor::Property::VISIBLE:
3452 property = &mNode->mVisible;
3455 case Dali::Actor::Property::COLOR:
3456 property = &mNode->mColor;
3459 case Dali::Actor::Property::COLOR_RED:
3460 property = &mNode->mColor;
3463 case Dali::Actor::Property::COLOR_GREEN:
3464 property = &mNode->mColor;
3467 case Dali::Actor::Property::COLOR_BLUE:
3468 property = &mNode->mColor;
3471 case Dali::Actor::Property::COLOR_ALPHA:
3472 case Dali::DevelActor::Property::OPACITY:
3473 property = &mNode->mColor;
3484 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3486 const PropertyInputImpl* property( NULL );
3488 // This method should only return a property of an object connected to the scene-graph
3494 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3496 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3497 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3499 property = animatable->GetSceneGraphProperty();
3501 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3502 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3504 CustomPropertyMetadata* custom = FindCustomProperty( index );
3505 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3506 property = custom->GetSceneGraphProperty();
3508 else if( NULL != mNode )
3512 case Dali::Actor::Property::PARENT_ORIGIN:
3513 property = &mNode->mParentOrigin;
3516 case Dali::Actor::Property::PARENT_ORIGIN_X:
3517 property = &mNode->mParentOrigin;
3520 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3521 property = &mNode->mParentOrigin;
3524 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3525 property = &mNode->mParentOrigin;
3528 case Dali::Actor::Property::ANCHOR_POINT:
3529 property = &mNode->mAnchorPoint;
3532 case Dali::Actor::Property::ANCHOR_POINT_X:
3533 property = &mNode->mAnchorPoint;
3536 case Dali::Actor::Property::ANCHOR_POINT_Y:
3537 property = &mNode->mAnchorPoint;
3540 case Dali::Actor::Property::ANCHOR_POINT_Z:
3541 property = &mNode->mAnchorPoint;
3544 case Dali::Actor::Property::SIZE:
3545 property = &mNode->mSize;
3548 case Dali::Actor::Property::SIZE_WIDTH:
3549 property = &mNode->mSize;
3552 case Dali::Actor::Property::SIZE_HEIGHT:
3553 property = &mNode->mSize;
3556 case Dali::Actor::Property::SIZE_DEPTH:
3557 property = &mNode->mSize;
3560 case Dali::Actor::Property::POSITION:
3561 property = &mNode->mPosition;
3564 case Dali::Actor::Property::POSITION_X:
3565 property = &mNode->mPosition;
3568 case Dali::Actor::Property::POSITION_Y:
3569 property = &mNode->mPosition;
3572 case Dali::Actor::Property::POSITION_Z:
3573 property = &mNode->mPosition;
3576 case Dali::Actor::Property::WORLD_POSITION:
3577 property = &mNode->mWorldPosition;
3580 case Dali::Actor::Property::WORLD_POSITION_X:
3581 property = &mNode->mWorldPosition;
3584 case Dali::Actor::Property::WORLD_POSITION_Y:
3585 property = &mNode->mWorldPosition;
3588 case Dali::Actor::Property::WORLD_POSITION_Z:
3589 property = &mNode->mWorldPosition;
3592 case Dali::Actor::Property::ORIENTATION:
3593 property = &mNode->mOrientation;
3596 case Dali::Actor::Property::WORLD_ORIENTATION:
3597 property = &mNode->mWorldOrientation;
3600 case Dali::Actor::Property::SCALE:
3601 property = &mNode->mScale;
3604 case Dali::Actor::Property::SCALE_X:
3605 property = &mNode->mScale;
3608 case Dali::Actor::Property::SCALE_Y:
3609 property = &mNode->mScale;
3612 case Dali::Actor::Property::SCALE_Z:
3613 property = &mNode->mScale;
3616 case Dali::Actor::Property::WORLD_SCALE:
3617 property = &mNode->mWorldScale;
3620 case Dali::Actor::Property::VISIBLE:
3621 property = &mNode->mVisible;
3624 case Dali::Actor::Property::COLOR:
3625 property = &mNode->mColor;
3628 case Dali::Actor::Property::COLOR_RED:
3629 property = &mNode->mColor;
3632 case Dali::Actor::Property::COLOR_GREEN:
3633 property = &mNode->mColor;
3636 case Dali::Actor::Property::COLOR_BLUE:
3637 property = &mNode->mColor;
3640 case Dali::Actor::Property::COLOR_ALPHA:
3641 case Dali::DevelActor::Property::OPACITY:
3643 property = &mNode->mColor;
3647 case Dali::Actor::Property::WORLD_COLOR:
3648 property = &mNode->mWorldColor;
3651 case Dali::Actor::Property::WORLD_MATRIX:
3652 property = &mNode->mWorldMatrix;
3663 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3665 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3667 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3669 // check whether the animatable property is registered already, if not then register one.
3670 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3671 if( animatableProperty )
3673 componentIndex = animatableProperty->componentIndex;
3680 case Dali::Actor::Property::PARENT_ORIGIN_X:
3681 case Dali::Actor::Property::ANCHOR_POINT_X:
3682 case Dali::Actor::Property::SIZE_WIDTH:
3683 case Dali::Actor::Property::POSITION_X:
3684 case Dali::Actor::Property::WORLD_POSITION_X:
3685 case Dali::Actor::Property::SCALE_X:
3686 case Dali::Actor::Property::COLOR_RED:
3692 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3693 case Dali::Actor::Property::ANCHOR_POINT_Y:
3694 case Dali::Actor::Property::SIZE_HEIGHT:
3695 case Dali::Actor::Property::POSITION_Y:
3696 case Dali::Actor::Property::WORLD_POSITION_Y:
3697 case Dali::Actor::Property::SCALE_Y:
3698 case Dali::Actor::Property::COLOR_GREEN:
3704 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3705 case Dali::Actor::Property::ANCHOR_POINT_Z:
3706 case Dali::Actor::Property::SIZE_DEPTH:
3707 case Dali::Actor::Property::POSITION_Z:
3708 case Dali::Actor::Property::WORLD_POSITION_Z:
3709 case Dali::Actor::Property::SCALE_Z:
3710 case Dali::Actor::Property::COLOR_BLUE:
3716 case Dali::Actor::Property::COLOR_ALPHA:
3717 case Dali::DevelActor::Property::OPACITY:
3731 return componentIndex;
3734 void Actor::SetParent( Actor* parent )
3738 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3742 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3745 // Instruct each actor to create a corresponding node in the scene graph
3746 ConnectToStage( parent->GetHierarchyDepth() );
3749 // Resolve the name and index for the child properties if any
3750 ResolveChildProperties();
3752 else // parent being set to NULL
3754 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3758 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3761 DALI_ASSERT_ALWAYS( mNode != NULL );
3765 // Disconnect the Node & its children from the scene-graph.
3766 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3769 // Instruct each actor to discard pointers to the scene-graph
3770 DisconnectFromStage();
3775 SceneGraph::Node* Actor::CreateNode() const
3780 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3783 Actor* actor = dynamic_cast< Actor* >( object );
3787 if( 0 == actionName.compare( ACTION_SHOW ) )
3789 actor->SetVisible( true );
3792 else if( 0 == actionName.compare( ACTION_HIDE ) )
3794 actor->SetVisible( false );
3802 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3804 bool valueSet = true;
3808 case Dali::Actor::Property::PARENT_ORIGIN:
3810 value = GetCurrentParentOrigin();
3814 case Dali::Actor::Property::PARENT_ORIGIN_X:
3816 value = GetCurrentParentOrigin().x;
3820 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3822 value = GetCurrentParentOrigin().y;
3826 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3828 value = GetCurrentParentOrigin().z;
3832 case Dali::Actor::Property::ANCHOR_POINT:
3834 value = GetCurrentAnchorPoint();
3838 case Dali::Actor::Property::ANCHOR_POINT_X:
3840 value = GetCurrentAnchorPoint().x;
3844 case Dali::Actor::Property::ANCHOR_POINT_Y:
3846 value = GetCurrentAnchorPoint().y;
3850 case Dali::Actor::Property::ANCHOR_POINT_Z:
3852 value = GetCurrentAnchorPoint().z;
3856 case Dali::Actor::Property::SIZE:
3858 value = GetTargetSize();
3862 case Dali::Actor::Property::SIZE_WIDTH:
3864 value = GetTargetSize().width;
3868 case Dali::Actor::Property::SIZE_HEIGHT:
3870 value = GetTargetSize().height;
3874 case Dali::Actor::Property::SIZE_DEPTH:
3876 value = GetTargetSize().depth;
3880 case Dali::Actor::Property::POSITION:
3882 value = GetTargetPosition();
3886 case Dali::Actor::Property::POSITION_X:
3888 value = GetTargetPosition().x;
3892 case Dali::Actor::Property::POSITION_Y:
3894 value = GetTargetPosition().y;
3898 case Dali::Actor::Property::POSITION_Z:
3900 value = GetTargetPosition().z;
3904 case Dali::Actor::Property::ORIENTATION:
3906 value = mTargetOrientation;
3910 case Dali::Actor::Property::SCALE:
3912 value = mTargetScale;
3916 case Dali::Actor::Property::SCALE_X:
3918 value = mTargetScale.x;
3922 case Dali::Actor::Property::SCALE_Y:
3924 value = mTargetScale.y;
3928 case Dali::Actor::Property::SCALE_Z:
3930 value = mTargetScale.z;
3934 case Dali::Actor::Property::VISIBLE:
3940 case Dali::Actor::Property::COLOR:
3942 value = mTargetColor;
3946 case Dali::Actor::Property::COLOR_RED:
3948 value = mTargetColor.r;
3952 case Dali::Actor::Property::COLOR_GREEN:
3954 value = mTargetColor.g;
3958 case Dali::Actor::Property::COLOR_BLUE:
3960 value = mTargetColor.b;
3964 case Dali::Actor::Property::COLOR_ALPHA:
3965 case Dali::DevelActor::Property::OPACITY:
3967 value = mTargetColor.a;
3971 case Dali::Actor::Property::NAME:
3977 case Dali::Actor::Property::SENSITIVE:
3979 value = IsSensitive();
3983 case Dali::Actor::Property::LEAVE_REQUIRED:
3985 value = GetLeaveRequired();
3989 case Dali::Actor::Property::INHERIT_POSITION:
3991 value = IsPositionInherited();
3995 case Dali::Actor::Property::INHERIT_ORIENTATION:
3997 value = IsOrientationInherited();
4001 case Dali::Actor::Property::INHERIT_SCALE:
4003 value = IsScaleInherited();
4007 case Dali::Actor::Property::COLOR_MODE:
4009 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4013 case Dali::Actor::Property::POSITION_INHERITANCE:
4015 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4019 case Dali::Actor::Property::DRAW_MODE:
4021 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4025 case Dali::Actor::Property::SIZE_MODE_FACTOR:
4027 value = GetSizeModeFactor();
4031 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4033 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4037 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4039 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4043 case Dali::Actor::Property::SIZE_SCALE_POLICY:
4045 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4049 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4051 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4055 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4057 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4061 case Dali::Actor::Property::PADDING:
4063 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4064 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4065 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4069 case Dali::Actor::Property::MINIMUM_SIZE:
4071 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4075 case Dali::Actor::Property::MAXIMUM_SIZE:
4077 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4081 case Dali::Actor::Property::CLIPPING_MODE:
4083 value = mClippingMode;
4087 case Dali::DevelActor::Property::SIBLING_ORDER:
4089 value = static_cast<int>( GetSiblingOrder() );
4093 case Dali::DevelActor::Property::SCREEN_POSITION:
4095 value = GetCurrentScreenPosition();
4099 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4101 value = mPositionUsesAnchorPoint;
4107 // Must be a scene-graph only property
4116 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
4118 bool valueSet = true;
4122 case Dali::Actor::Property::SIZE:
4124 value = GetCurrentSize();
4128 case Dali::Actor::Property::SIZE_WIDTH:
4130 value = GetCurrentSize().width;
4134 case Dali::Actor::Property::SIZE_HEIGHT:
4136 value = GetCurrentSize().height;
4140 case Dali::Actor::Property::SIZE_DEPTH:
4142 value = GetCurrentSize().depth;
4146 case Dali::Actor::Property::POSITION:
4148 value = GetCurrentPosition();
4152 case Dali::Actor::Property::POSITION_X:
4154 value = GetCurrentPosition().x;
4158 case Dali::Actor::Property::POSITION_Y:
4160 value = GetCurrentPosition().y;
4164 case Dali::Actor::Property::POSITION_Z:
4166 value = GetCurrentPosition().z;
4170 case Dali::Actor::Property::WORLD_POSITION:
4172 value = GetCurrentWorldPosition();
4176 case Dali::Actor::Property::WORLD_POSITION_X:
4178 value = GetCurrentWorldPosition().x;
4182 case Dali::Actor::Property::WORLD_POSITION_Y:
4184 value = GetCurrentWorldPosition().y;
4188 case Dali::Actor::Property::WORLD_POSITION_Z:
4190 value = GetCurrentWorldPosition().z;
4194 case Dali::Actor::Property::ORIENTATION:
4196 value = GetCurrentOrientation();
4200 case Dali::Actor::Property::WORLD_ORIENTATION:
4202 value = GetCurrentWorldOrientation();
4206 case Dali::Actor::Property::SCALE:
4208 value = GetCurrentScale();
4212 case Dali::Actor::Property::SCALE_X:
4214 value = GetCurrentScale().x;
4218 case Dali::Actor::Property::SCALE_Y:
4220 value = GetCurrentScale().y;
4224 case Dali::Actor::Property::SCALE_Z:
4226 value = GetCurrentScale().z;
4230 case Dali::Actor::Property::WORLD_SCALE:
4232 value = GetCurrentWorldScale();
4236 case Dali::Actor::Property::COLOR:
4238 value = GetCurrentColor();
4242 case Dali::Actor::Property::COLOR_RED:
4244 value = GetCurrentColor().r;
4248 case Dali::Actor::Property::COLOR_GREEN:
4250 value = GetCurrentColor().g;
4254 case Dali::Actor::Property::COLOR_BLUE:
4256 value = GetCurrentColor().b;
4260 case Dali::Actor::Property::COLOR_ALPHA:
4261 case Dali::DevelActor::Property::OPACITY:
4263 value = GetCurrentColor().a;
4267 case Dali::Actor::Property::WORLD_COLOR:
4269 value = GetCurrentWorldColor();
4273 case Dali::Actor::Property::WORLD_MATRIX:
4275 value = GetCurrentWorldMatrix();
4279 case Dali::Actor::Property::VISIBLE:
4281 value = IsVisible();
4287 // Must be an event-side only property
4296 void Actor::EnsureRelayoutData()
4298 // Assign relayout data.
4299 if( !mRelayoutData )
4301 mRelayoutData = new RelayoutData();
4305 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4307 // Check if actor is dependent on parent
4308 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4310 if( ( dimension & ( 1 << i ) ) )
4312 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4313 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4323 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4325 // Check if actor is dependent on children
4326 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4328 if( ( dimension & ( 1 << i ) ) )
4330 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4331 switch( resizePolicy )
4333 case ResizePolicy::FIT_TO_CHILDREN:
4334 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4350 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4352 return Actor::RelayoutDependentOnChildren( dimension );
4355 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4357 // Check each possible dimension and see if it is dependent on the input one
4358 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4360 if( dimension & ( 1 << i ) )
4362 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4369 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4371 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4373 if( dimension & ( 1 << i ) )
4375 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4380 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4382 // If more than one dimension is requested, just return the first one found
4383 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4385 if( ( dimension & ( 1 << i ) ) )
4387 return mRelayoutData->negotiatedDimensions[ i ];
4391 return 0.0f; // Default
4394 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4396 EnsureRelayoutData();
4398 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4400 if( dimension & ( 1 << i ) )
4402 mRelayoutData->dimensionPadding[ i ] = padding;
4407 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4409 if ( mRelayoutData )
4411 // If more than one dimension is requested, just return the first one found
4412 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4414 if( ( dimension & ( 1 << i ) ) )
4416 return mRelayoutData->dimensionPadding[ i ];
4421 return GetDefaultDimensionPadding();
4424 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4426 EnsureRelayoutData();
4428 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4430 if( dimension & ( 1 << i ) )
4432 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4437 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4439 if ( mRelayoutData )
4441 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4443 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4453 float Actor::GetHeightForWidthBase( float width )
4455 float height = 0.0f;
4457 const Vector3 naturalSize = GetNaturalSize();
4458 if( naturalSize.width > 0.0f )
4460 height = naturalSize.height * width / naturalSize.width;
4462 else // we treat 0 as 1:1 aspect ratio
4470 float Actor::GetWidthForHeightBase( float height )
4474 const Vector3 naturalSize = GetNaturalSize();
4475 if( naturalSize.height > 0.0f )
4477 width = naturalSize.width * height / naturalSize.height;
4479 else // we treat 0 as 1:1 aspect ratio
4487 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4489 // Fill to parent, taking size mode factor into account
4490 switch( child.GetResizePolicy( dimension ) )
4492 case ResizePolicy::FILL_TO_PARENT:
4494 return GetLatestSize( dimension );
4497 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4499 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4502 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4504 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4509 return GetLatestSize( dimension );
4514 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4516 // Can be overridden in derived class
4517 return CalculateChildSizeBase( child, dimension );
4520 float Actor::GetHeightForWidth( float width )
4522 // Can be overridden in derived class
4523 return GetHeightForWidthBase( width );
4526 float Actor::GetWidthForHeight( float height )
4528 // Can be overridden in derived class
4529 return GetWidthForHeightBase( height );
4532 float Actor::GetLatestSize( Dimension::Type dimension ) const
4534 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4537 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4539 Vector2 padding = GetPadding( dimension );
4541 return GetLatestSize( dimension ) + padding.x + padding.y;
4544 float Actor::NegotiateFromParent( Dimension::Type dimension )
4546 Actor* parent = GetParent();
4549 Vector2 padding( GetPadding( dimension ) );
4550 Vector2 parentPadding( parent->GetPadding( dimension ) );
4551 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4557 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4559 float maxDimensionPoint = 0.0f;
4561 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4563 ActorPtr child = GetChildAt( i );
4565 if( !child->RelayoutDependentOnParent( dimension ) )
4567 // Calculate the min and max points that the children range across
4568 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4569 float dimensionSize = child->GetRelayoutSize( dimension );
4570 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4574 return maxDimensionPoint;
4577 float Actor::GetSize( Dimension::Type dimension ) const
4579 return GetDimensionValue( mTargetSize, dimension );
4582 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4584 return GetDimensionValue( GetNaturalSize(), dimension );
4587 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4589 switch( GetResizePolicy( dimension ) )
4591 case ResizePolicy::USE_NATURAL_SIZE:
4593 return GetNaturalSize( dimension );
4596 case ResizePolicy::FIXED:
4598 return GetDimensionValue( GetPreferredSize(), dimension );
4601 case ResizePolicy::USE_ASSIGNED_SIZE:
4603 return GetDimensionValue( maximumSize, dimension );
4606 case ResizePolicy::FILL_TO_PARENT:
4607 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4608 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4610 return NegotiateFromParent( dimension );
4613 case ResizePolicy::FIT_TO_CHILDREN:
4615 return NegotiateFromChildren( dimension );
4618 case ResizePolicy::DIMENSION_DEPENDENCY:
4620 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4623 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4625 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4628 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4630 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4642 return 0.0f; // Default
4645 float Actor::ClampDimension( float size, Dimension::Type dimension )
4647 const float minSize = GetMinimumSize( dimension );
4648 const float maxSize = GetMaximumSize( dimension );
4650 return std::max( minSize, std::min( size, maxSize ) );
4653 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4655 // Check if it needs to be negotiated
4656 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4658 // Check that we havn't gotten into an infinite loop
4659 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4660 bool recursionFound = false;
4661 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4663 if( *it == searchActor )
4665 recursionFound = true;
4670 if( !recursionFound )
4672 // Record the path that we have taken
4673 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4675 // Dimension dependency check
4676 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4678 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4680 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4682 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4686 // Parent dependency check
4687 Actor* parent = GetParent();
4688 if( parent && RelayoutDependentOnParent( dimension ) )
4690 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4693 // Children dependency check
4694 if( RelayoutDependentOnChildren( dimension ) )
4696 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4698 ActorPtr child = GetChildAt( i );
4700 // Only relayout child first if it is not dependent on this actor
4701 if( !child->RelayoutDependentOnParent( dimension ) )
4703 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4708 // For deriving classes
4709 OnCalculateRelayoutSize( dimension );
4711 // All dependencies checked, calculate the size and set negotiated flag
4712 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4714 SetNegotiatedDimension( newSize, dimension );
4715 SetLayoutNegotiated( true, dimension );
4717 // For deriving classes
4718 OnLayoutNegotiated( newSize, dimension );
4720 // This actor has been successfully processed, pop it off the recursion stack
4721 recursionStack.pop_back();
4725 // TODO: Break infinite loop
4726 SetLayoutNegotiated( true, dimension );
4731 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4733 // Negotiate all dimensions that require it
4734 ActorDimensionStack recursionStack;
4736 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4738 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4741 NegotiateDimension( dimension, allocatedSize, recursionStack );
4745 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4747 switch( mRelayoutData->sizeSetPolicy )
4749 case SizeScalePolicy::USE_SIZE_SET:
4754 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4756 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4757 const Vector3 naturalSize = GetNaturalSize();
4758 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4760 const float sizeRatio = size.width / size.height;
4761 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4763 if( naturalSizeRatio < sizeRatio )
4765 return Vector2( naturalSizeRatio * size.height, size.height );
4767 else if( naturalSizeRatio > sizeRatio )
4769 return Vector2( size.width, size.width / naturalSizeRatio );
4780 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4782 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4783 const Vector3 naturalSize = GetNaturalSize();
4784 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4786 const float sizeRatio = size.width / size.height;
4787 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4789 if( naturalSizeRatio < sizeRatio )
4791 return Vector2( size.width, size.width / naturalSizeRatio );
4793 else if( naturalSizeRatio > sizeRatio )
4795 return Vector2( naturalSizeRatio * size.height, size.height );
4814 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4816 // Do the set actor size
4817 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4819 // Adjust for size set policy
4820 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4822 // Lock the flag to stop recursive relayouts on set size
4823 mRelayoutData->insideRelayout = true;
4824 SetSize( negotiatedSize );
4825 mRelayoutData->insideRelayout = false;
4827 // Clear flags for all dimensions
4828 SetLayoutDirty( false );
4830 // Give deriving classes a chance to respond
4831 OnRelayout( negotiatedSize, container );
4833 if( !mOnRelayoutSignal.Empty() )
4835 Dali::Actor handle( this );
4836 mOnRelayoutSignal.Emit( handle );
4840 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4842 // Force a size negotiation for actors that has assigned size during relayout
4843 // This is required as otherwise the flags that force a relayout will not
4844 // necessarilly be set. This will occur if the actor has already been laid out.
4845 // The dirty flags are then cleared. Then if the actor is added back into the
4846 // relayout container afterwards, the dirty flags would still be clear...
4847 // causing a relayout to be skipped. Here we force any actors added to the
4848 // container to be relayed out.
4849 DALI_LOG_TIMER_START( NegSizeTimer1 );
4851 if( GetUseAssignedSize(Dimension::WIDTH ) )
4853 SetLayoutNegotiated( false, Dimension::WIDTH );
4855 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4857 SetLayoutNegotiated( false, Dimension::HEIGHT );
4860 // Do the negotiation
4861 NegotiateDimensions( allocatedSize );
4863 // Set the actor size
4864 SetNegotiatedSize( container );
4866 // Negotiate down to children
4867 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4869 ActorPtr child = GetChildAt( i );
4871 // Forces children that have already been laid out to be relayed out
4872 // if they have assigned size during relayout.
4873 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4875 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4876 child->SetLayoutDirty(true, Dimension::WIDTH);
4879 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4881 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4882 child->SetLayoutDirty(true, Dimension::HEIGHT);
4885 // Only relayout if required
4886 if( child->RelayoutRequired() )
4888 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4891 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4894 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4898 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4900 if( dimension & ( 1 << i ) )
4902 mRelayoutData->useAssignedSize[ i ] = use;
4908 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4910 if ( mRelayoutData )
4912 // If more than one dimension is requested, just return the first one found
4913 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4915 if( dimension & ( 1 << i ) )
4917 return mRelayoutData->useAssignedSize[ i ];
4925 void Actor::RelayoutRequest( Dimension::Type dimension )
4927 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4928 if( relayoutController )
4930 Dali::Actor self( this );
4931 relayoutController->RequestRelayout( self, dimension );
4935 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4939 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4943 void Actor::SetPreferredSize( const Vector2& size )
4945 EnsureRelayoutData();
4947 if( size.width > 0.0f )
4949 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4952 if( size.height > 0.0f )
4954 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4957 mRelayoutData->preferredSize = size;
4962 Vector2 Actor::GetPreferredSize() const
4964 if ( mRelayoutData )
4966 return Vector2( mRelayoutData->preferredSize );
4969 return GetDefaultPreferredSize();
4972 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4974 EnsureRelayoutData();
4976 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4978 if( dimension & ( 1 << i ) )
4980 mRelayoutData->minimumSize[ i ] = size;
4987 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4989 if ( mRelayoutData )
4991 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4993 if( dimension & ( 1 << i ) )
4995 return mRelayoutData->minimumSize[ i ];
5000 return 0.0f; // Default
5003 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5005 EnsureRelayoutData();
5007 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5009 if( dimension & ( 1 << i ) )
5011 mRelayoutData->maximumSize[ i ] = size;
5018 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5020 if ( mRelayoutData )
5022 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5024 if( dimension & ( 1 << i ) )
5026 return mRelayoutData->maximumSize[ i ];
5031 return FLT_MAX; // Default
5034 Object* Actor::GetParentObject() const
5039 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5041 if( mVisible != visible )
5043 if( sendMessage == SendMessage::TRUE && NULL != mNode )
5045 // mNode is being used in a separate thread; queue a message to set the value & base value
5046 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5051 // Emit the signal on this actor and all its children
5052 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5056 void Actor::SetSiblingOrder( unsigned int order )
5060 ActorContainer& siblings = *(mParent->mChildren);
5061 unsigned int currentOrder = GetSiblingOrder();
5063 if( order != currentOrder )
5069 else if( order < siblings.size() -1 )
5071 if( order > currentOrder )
5073 RaiseAbove( *siblings[order] );
5077 LowerBelow( *siblings[order] );
5088 unsigned int Actor::GetSiblingOrder() const
5090 unsigned int order = 0;
5094 ActorContainer& siblings = *(mParent->mChildren);
5095 for( size_t i=0; i<siblings.size(); ++i )
5097 if( siblings[i] == this )
5108 void Actor::RequestRebuildDepthTree()
5112 StagePtr stage = Stage::GetCurrent();
5115 stage->RequestRebuildDepthTree();
5124 ActorContainer& siblings = *(mParent->mChildren);
5125 if( siblings.back() != this ) // If not already at end
5127 for( size_t i=0; i<siblings.size(); ++i )
5129 if( siblings[i] == this )
5132 ActorPtr next = siblings[i+1];
5133 siblings[i+1] = this;
5139 RequestRebuildDepthTree();
5143 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5151 ActorContainer& siblings = *(mParent->mChildren);
5152 if( siblings.front() != this ) // If not already at beginning
5154 for( size_t i=0; i<siblings.size(); ++i )
5156 if( siblings[i] == this )
5158 // Swap with previous
5159 ActorPtr previous = siblings[i-1];
5160 siblings[i-1] = this;
5161 siblings[i] = previous;
5166 RequestRebuildDepthTree();
5170 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5174 void Actor::RaiseToTop()
5178 ActorContainer& siblings = *(mParent->mChildren);
5179 if( siblings.back() != this ) // If not already at end
5181 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5182 if( iter != siblings.end() )
5184 siblings.erase(iter);
5185 siblings.push_back(ActorPtr(this));
5188 RequestRebuildDepthTree();
5192 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5196 void Actor::LowerToBottom()
5200 ActorContainer& siblings = *(mParent->mChildren);
5201 if( siblings.front() != this ) // If not already at bottom,
5203 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5205 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5206 if( iter != siblings.end() )
5208 siblings.erase(iter);
5209 siblings.insert(siblings.begin(), thisPtr);
5212 RequestRebuildDepthTree();
5216 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5220 void Actor::RaiseAbove( Internal::Actor& target )
5224 ActorContainer& siblings = *(mParent->mChildren);
5225 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5227 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5229 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5230 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5231 if( thisIter < targetIter )
5233 siblings.erase(thisIter);
5234 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5235 // invalidate thisIter)
5236 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5238 siblings.insert(targetIter, thisPtr);
5240 RequestRebuildDepthTree();
5245 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5249 void Actor::LowerBelow( Internal::Actor& target )
5253 ActorContainer& siblings = *(mParent->mChildren);
5254 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5256 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5258 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5259 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5261 if( thisIter > targetIter )
5263 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5264 siblings.insert(targetIter, thisPtr);
5266 RequestRebuildDepthTree();
5271 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5275 } // namespace Internal