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( "layoutDirection", STRING, true, false, false, Dali::DevelActor::Property::LAYOUT_DIRECTION )
216 DALI_PROPERTY( "layoutDirectionInheritance", BOOLEAN, true, false, false, Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE )
217 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
221 const char* const SIGNAL_TOUCHED = "touched";
222 const char* const SIGNAL_HOVERED = "hovered";
223 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
224 const char* const SIGNAL_ON_STAGE = "onStage";
225 const char* const SIGNAL_OFF_STAGE = "offStage";
226 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
227 const char* const SIGNAL_TOUCH = "touch";
231 const char* const ACTION_SHOW = "show";
232 const char* const ACTION_HIDE = "hide";
234 BaseHandle CreateActor()
236 return Dali::Actor::New();
239 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
241 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
242 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
243 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
244 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
245 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
247 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
249 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
250 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
255 const Vector3& value;
258 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
259 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
260 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
261 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
262 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
263 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
264 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
265 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
266 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
267 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
268 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
270 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
271 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
272 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
273 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
274 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
275 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
277 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
278 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
279 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
280 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
281 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
282 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
284 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
287 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
288 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
290 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
299 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
301 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
305 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
307 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
310 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
312 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelActor::LayoutDirection, LTR )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelActor::LayoutDirection, RTL )
315 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
317 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
319 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
321 size_t sizeIgnored = 0;
322 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
324 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
331 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
333 // Values are the same so just use the same table as anchor-point
334 return GetAnchorPointConstant( value, parentOrigin );
338 * @brief Extract a given dimension from a Vector2
340 * @param[in] values The values to extract from
341 * @param[in] dimension The dimension to extract
342 * @return Return the value for the dimension
344 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
348 case Dimension::WIDTH:
352 case Dimension::HEIGHT:
354 return values.height;
365 * @brief Extract a given dimension from a Vector3
367 * @param[in] values The values to extract from
368 * @param[in] dimension The dimension to extract
369 * @return Return the value for the dimension
371 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
373 return GetDimensionValue( values.GetVectorXY(), dimension );
377 * @brief Recursively emits the visibility-changed-signal on the actor tree.
378 * @param[in] actor The actor to emit the signal on
379 * @param[in] visible The new visibility of the actor
380 * @param[in] type Whether the actor's visible property has changed or a parent's
382 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
386 actor->EmitVisibilityChangedSignal( visible, type );
388 if( actor->GetChildCount() > 0 )
390 ActorContainer& children = actor->GetChildrenInternal();
391 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
393 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
399 } // unnamed namespace
401 ActorPtr Actor::New()
403 ActorPtr actor( new Actor( BASIC ) );
405 // Second-phase construction
411 const std::string& Actor::GetName() const
416 void Actor::SetName( const std::string& name )
422 // ATTENTION: string for debug purposes is not thread safe.
423 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
427 unsigned int Actor::GetId() const
432 bool Actor::OnStage() const
437 Dali::Layer Actor::GetLayer()
441 // Short-circuit for Layer derived actors
444 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
447 // Find the immediate Layer parent
448 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
450 if( parent->IsLayer() )
452 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
459 void Actor::Add( Actor& child )
461 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
462 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
466 mChildren = new ActorContainer;
469 Actor* const oldParent( child.mParent );
471 // child might already be ours
472 if( this != oldParent )
474 // if we already have parent, unparent us first
477 oldParent->Remove( child ); // This causes OnChildRemove callback
479 // Old parent may need to readjust to missing child
480 if( oldParent->RelayoutDependentOnChildren() )
482 oldParent->RelayoutRequest();
486 // Guard against Add() during previous OnChildRemove callback
489 // Do this first, since user callbacks from within SetParent() may need to remove child
490 mChildren->push_back( ActorPtr( &child ) );
492 // SetParent asserts that child can be added
493 child.SetParent( this );
495 // Notification for derived classes
498 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
500 // Only put in a relayout request if there is a suitable dependency
501 if( RelayoutDependentOnChildren() )
509 void Actor::Remove( Actor& child )
511 if( (this == &child) || (!mChildren) )
513 // no children or removing itself
519 // Find the child in mChildren, and unparent it
520 ActorIter end = mChildren->end();
521 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
523 ActorPtr actor = (*iter);
525 if( actor.Get() == &child )
527 // Keep handle for OnChildRemove notification
530 // Do this first, since user callbacks from within SetParent() may need to add the child
531 mChildren->erase( iter );
533 DALI_ASSERT_DEBUG( actor->GetParent() == this );
534 actor->SetParent( NULL );
542 // Only put in a relayout request if there is a suitable dependency
543 if( RelayoutDependentOnChildren() )
549 // Notification for derived classes
550 OnChildRemove( child );
553 void Actor::Unparent()
557 // Remove this actor from the parent. The remove will put a relayout request in for
558 // the parent if required
559 mParent->Remove( *this );
560 // mParent is now NULL!
564 unsigned int Actor::GetChildCount() const
566 return ( NULL != mChildren ) ? mChildren->size() : 0;
569 ActorPtr Actor::GetChildAt( unsigned int index ) const
571 DALI_ASSERT_ALWAYS( index < GetChildCount() );
573 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
576 ActorPtr Actor::FindChildByName( const std::string& actorName )
579 if( actorName == mName )
585 ActorIter end = mChildren->end();
586 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
588 child = (*iter)->FindChildByName( actorName );
599 ActorPtr Actor::FindChildById( const unsigned int id )
608 ActorIter end = mChildren->end();
609 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
611 child = (*iter)->FindChildById( id );
622 void Actor::SetParentOrigin( const Vector3& origin )
626 // mNode is being used in a separate thread; queue a message to set the value & base value
627 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
630 // Cache for event-thread access
633 // not allocated, check if different from default
634 if( ParentOrigin::DEFAULT != origin )
636 mParentOrigin = new Vector3( origin );
641 // check if different from current costs more than just set
642 *mParentOrigin = origin;
646 void Actor::SetParentOriginX( float x )
648 const Vector3& current = GetCurrentParentOrigin();
650 SetParentOrigin( Vector3( x, current.y, current.z ) );
653 void Actor::SetParentOriginY( float y )
655 const Vector3& current = GetCurrentParentOrigin();
657 SetParentOrigin( Vector3( current.x, y, current.z ) );
660 void Actor::SetParentOriginZ( float z )
662 const Vector3& current = GetCurrentParentOrigin();
664 SetParentOrigin( Vector3( current.x, current.y, z ) );
667 const Vector3& Actor::GetCurrentParentOrigin() const
669 // Cached for event-thread access
670 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
673 void Actor::SetAnchorPoint( const Vector3& anchor )
677 // mNode is being used in a separate thread; queue a message to set the value & base value
678 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
681 // Cache for event-thread access
684 // not allocated, check if different from default
685 if( AnchorPoint::DEFAULT != anchor )
687 mAnchorPoint = new Vector3( anchor );
692 // check if different from current costs more than just set
693 *mAnchorPoint = anchor;
697 void Actor::SetAnchorPointX( float x )
699 const Vector3& current = GetCurrentAnchorPoint();
701 SetAnchorPoint( Vector3( x, current.y, current.z ) );
704 void Actor::SetAnchorPointY( float y )
706 const Vector3& current = GetCurrentAnchorPoint();
708 SetAnchorPoint( Vector3( current.x, y, current.z ) );
711 void Actor::SetAnchorPointZ( float z )
713 const Vector3& current = GetCurrentAnchorPoint();
715 SetAnchorPoint( Vector3( current.x, current.y, z ) );
718 const Vector3& Actor::GetCurrentAnchorPoint() const
720 // Cached for event-thread access
721 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
724 void Actor::SetPosition( float x, float y )
726 SetPosition( Vector3( x, y, 0.0f ) );
729 void Actor::SetPosition( float x, float y, float z )
731 SetPosition( Vector3( x, y, z ) );
734 void Actor::SetPosition( const Vector3& position )
736 mTargetPosition = position;
740 // mNode is being used in a separate thread; queue a message to set the value & base value
741 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
745 void Actor::SetX( float x )
747 mTargetPosition.x = x;
751 // mNode is being used in a separate thread; queue a message to set the value & base value
752 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
756 void Actor::SetY( float y )
758 mTargetPosition.y = y;
762 // mNode is being used in a separate thread; queue a message to set the value & base value
763 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
767 void Actor::SetZ( float z )
769 mTargetPosition.z = z;
773 // mNode is being used in a separate thread; queue a message to set the value & base value
774 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
778 void Actor::TranslateBy( const Vector3& distance )
780 mTargetPosition += distance;
784 // mNode is being used in a separate thread; queue a message to set the value & base value
785 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
789 const Vector3& Actor::GetCurrentPosition() const
793 // mNode is being used in a separate thread; copy the value from the previous update
794 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
797 return Vector3::ZERO;
800 const Vector3& Actor::GetTargetPosition() const
802 return mTargetPosition;
805 const Vector3& Actor::GetCurrentWorldPosition() const
809 // mNode is being used in a separate thread; copy the value from the previous update
810 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
813 return Vector3::ZERO;
816 const Vector2 Actor::GetCurrentScreenPosition() const
818 if( OnStage() && NULL != mNode )
820 StagePtr stage = Stage::GetCurrent();
821 Vector3 worldPosition = mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
822 Vector3 actorSize = GetCurrentSize() * GetCurrentScale();
823 Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
824 Vector3 halfActorSize( actorSize * 0.5f );
825 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
827 return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
828 halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
831 return Vector2::ZERO;
834 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
836 // this flag is not animatable so keep the value
837 mPositionInheritanceMode = mode;
840 // mNode is being used in a separate thread; queue a message to set the value
841 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
845 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
847 // Cached for event-thread access
848 return mPositionInheritanceMode;
851 void Actor::SetInheritPosition( bool inherit )
853 if( mInheritPosition != inherit && NULL != mNode )
855 // non animateable so keep local copy
856 mInheritPosition = inherit;
857 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
861 bool Actor::IsPositionInherited() const
863 return mInheritPosition;
866 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
868 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
869 normalizedAxis.Normalize();
871 Quaternion orientation( angle, normalizedAxis );
873 SetOrientation( orientation );
876 void Actor::SetOrientation( const Quaternion& orientation )
878 mTargetOrientation = orientation;
882 // mNode is being used in a separate thread; queue a message to set the value & base value
883 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
887 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
889 RotateBy( Quaternion(angle, axis) );
892 void Actor::RotateBy( const Quaternion& relativeRotation )
894 mTargetOrientation *= Quaternion( relativeRotation );
898 // mNode is being used in a separate thread; queue a message to set the value & base value
899 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
903 const Quaternion& Actor::GetCurrentOrientation() const
907 // mNode is being used in a separate thread; copy the value from the previous update
908 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
911 return Quaternion::IDENTITY;
914 const Quaternion& Actor::GetCurrentWorldOrientation() const
918 // mNode is being used in a separate thread; copy the value from the previous update
919 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
922 return Quaternion::IDENTITY;
925 void Actor::SetScale( float scale )
927 SetScale( Vector3( scale, scale, scale ) );
930 void Actor::SetScale( float x, float y, float z )
932 SetScale( Vector3( x, y, z ) );
935 void Actor::SetScale( const Vector3& scale )
937 mTargetScale = scale;
941 // mNode is being used in a separate thread; queue a message to set the value & base value
942 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
946 void Actor::SetScaleX( float x )
952 // mNode is being used in a separate thread; queue a message to set the value & base value
953 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
957 void Actor::SetScaleY( float y )
963 // mNode is being used in a separate thread; queue a message to set the value & base value
964 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
968 void Actor::SetScaleZ( float z )
974 // mNode is being used in a separate thread; queue a message to set the value & base value
975 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
979 void Actor::ScaleBy(const Vector3& relativeScale)
981 mTargetScale *= relativeScale;
985 // mNode is being used in a separate thread; queue a message to set the value & base value
986 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
990 const Vector3& Actor::GetCurrentScale() const
994 // mNode is being used in a separate thread; copy the value from the previous update
995 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
1001 const Vector3& Actor::GetCurrentWorldScale() const
1005 // mNode is being used in a separate thread; copy the value from the previous update
1006 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
1009 return Vector3::ONE;
1012 void Actor::SetInheritScale( bool inherit )
1015 if( mInheritScale != inherit && NULL != mNode )
1017 // non animateable so keep local copy
1018 mInheritScale = inherit;
1019 // mNode is being used in a separate thread; queue a message to set the value
1020 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
1024 bool Actor::IsScaleInherited() const
1026 return mInheritScale;
1029 Matrix Actor::GetCurrentWorldMatrix() const
1033 return mNode->GetWorldMatrix(0);
1036 return Matrix::IDENTITY;
1039 void Actor::SetVisible( bool visible )
1041 SetVisibleInternal( visible, SendMessage::TRUE );
1044 bool Actor::IsVisible() const
1048 // mNode is being used in a separate thread; copy the value from the previous update
1049 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1055 void Actor::SetOpacity( float opacity )
1057 mTargetColor.a = opacity;
1061 // mNode is being used in a separate thread; queue a message to set the value & base value
1062 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1066 float Actor::GetCurrentOpacity() const
1070 // mNode is being used in a separate thread; copy the value from the previous update
1071 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1077 ClippingMode::Type Actor::GetClippingMode() const
1079 return mClippingMode;
1082 unsigned int Actor::GetSortingDepth()
1084 return mSortedDepth;
1087 const Vector4& Actor::GetCurrentWorldColor() const
1091 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1094 return Color::WHITE;
1097 void Actor::SetColor( const Vector4& color )
1099 mTargetColor = color;
1103 // mNode is being used in a separate thread; queue a message to set the value & base value
1104 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1108 void Actor::SetColorRed( float red )
1110 mTargetColor.r = red;
1114 // mNode is being used in a separate thread; queue a message to set the value & base value
1115 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1119 void Actor::SetColorGreen( float green )
1121 mTargetColor.g = green;
1125 // mNode is being used in a separate thread; queue a message to set the value & base value
1126 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1130 void Actor::SetColorBlue( float blue )
1132 mTargetColor.b = blue;
1136 // mNode is being used in a separate thread; queue a message to set the value & base value
1137 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1141 const Vector4& Actor::GetCurrentColor() const
1145 // mNode is being used in a separate thread; copy the value from the previous update
1146 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1149 return Color::WHITE;
1152 void Actor::SetInheritOrientation( bool inherit )
1154 if( mInheritOrientation != inherit && NULL != mNode)
1156 // non animateable so keep local copy
1157 mInheritOrientation = inherit;
1158 // mNode is being used in a separate thread; queue a message to set the value
1159 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1163 bool Actor::IsOrientationInherited() const
1165 return mInheritOrientation;
1168 void Actor::SetSizeModeFactor( const Vector3& factor )
1170 EnsureRelayoutData();
1172 mRelayoutData->sizeModeFactor = factor;
1175 const Vector3& Actor::GetSizeModeFactor() const
1177 if ( mRelayoutData )
1179 return mRelayoutData->sizeModeFactor;
1182 return GetDefaultSizeModeFactor();
1185 void Actor::SetColorMode( ColorMode colorMode )
1187 // non animateable so keep local copy
1188 mColorMode = colorMode;
1191 // mNode is being used in a separate thread; queue a message to set the value
1192 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1196 ColorMode Actor::GetColorMode() const
1198 // we have cached copy
1202 void Actor::SetSize( float width, float height )
1204 SetSize( Vector2( width, height ) );
1207 void Actor::SetSize( float width, float height, float depth )
1209 SetSize( Vector3( width, height, depth ) );
1212 void Actor::SetSize( const Vector2& size )
1214 SetSize( Vector3( size.width, size.height, 0.f ) );
1217 void Actor::SetSizeInternal( const Vector2& size )
1219 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1222 void Actor::SetSize( const Vector3& size )
1224 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1226 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1227 SetPreferredSize( size.GetVectorXY() );
1231 SetSizeInternal( size );
1235 void Actor::SetSizeInternal( const Vector3& size )
1237 // dont allow recursive loop
1238 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1239 // 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
1240 if( ( NULL != mNode )&&
1241 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1242 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1243 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1247 // mNode is being used in a separate thread; queue a message to set the value & base value
1248 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1250 // Notification for derived classes
1251 mInsideOnSizeSet = true;
1252 OnSizeSet( mTargetSize );
1253 mInsideOnSizeSet = false;
1255 // Raise a relayout request if the flag is not locked
1256 if( mRelayoutData && !mRelayoutData->insideRelayout )
1263 void Actor::SetWidth( float width )
1265 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1267 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1268 mRelayoutData->preferredSize.width = width;
1272 mTargetSize.width = width;
1276 // mNode is being used in a separate thread; queue a message to set the value & base value
1277 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1284 void Actor::SetHeight( float height )
1286 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1288 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1289 mRelayoutData->preferredSize.height = height;
1293 mTargetSize.height = height;
1297 // mNode is being used in a separate thread; queue a message to set the value & base value
1298 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1305 void Actor::SetDepth( float depth )
1307 mTargetSize.depth = depth;
1311 // mNode is being used in a separate thread; queue a message to set the value & base value
1312 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1316 Vector3 Actor::GetTargetSize() const
1318 Vector3 size = mTargetSize;
1320 // Should return preferred size if size is fixed as set by SetSize
1321 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1323 size.width = GetPreferredSize().width;
1325 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1327 size.height = GetPreferredSize().height;
1333 const Vector3& Actor::GetCurrentSize() const
1337 // mNode is being used in a separate thread; copy the value from the previous update
1338 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1341 return Vector3::ZERO;
1344 Vector3 Actor::GetNaturalSize() const
1346 // It is up to deriving classes to return the appropriate natural size
1347 return Vector3( 0.0f, 0.0f, 0.0f );
1350 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1352 EnsureRelayoutData();
1354 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1355 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1357 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1359 if( dimension & ( 1 << i ) )
1361 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1363 mRelayoutData->useAssignedSize[ i ] = true;
1367 mRelayoutData->resizePolicies[ i ] = policy;
1368 mRelayoutData->useAssignedSize[ i ] = false;
1373 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1375 if( dimension & Dimension::WIDTH )
1377 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1380 if( dimension & Dimension::HEIGHT )
1382 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1386 // If calling SetResizePolicy, assume we want relayout enabled
1387 SetRelayoutEnabled( true );
1389 // If the resize policy is set to be FIXED, the preferred size
1390 // should be overrided by the target size. Otherwise the target
1391 // size should be overrided by the preferred size.
1393 if( dimension & Dimension::WIDTH )
1395 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1397 mRelayoutData->preferredSize.width = mTargetSize.width;
1399 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1401 mTargetSize.width = mRelayoutData->preferredSize.width;
1405 if( dimension & Dimension::HEIGHT )
1407 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1409 mRelayoutData->preferredSize.height = mTargetSize.height;
1411 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1413 mTargetSize.height = mRelayoutData->preferredSize.height;
1417 OnSetResizePolicy( policy, dimension );
1419 // Trigger relayout on this control
1423 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1425 if ( mRelayoutData )
1427 // If more than one dimension is requested, just return the first one found
1428 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1430 if( ( dimension & ( 1 << i ) ) )
1432 if( mRelayoutData->useAssignedSize[ i ] )
1434 return ResizePolicy::USE_ASSIGNED_SIZE;
1438 return mRelayoutData->resizePolicies[ i ];
1444 return ResizePolicy::DEFAULT;
1447 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1449 EnsureRelayoutData();
1451 mRelayoutData->sizeSetPolicy = policy;
1454 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1456 if ( mRelayoutData )
1458 return mRelayoutData->sizeSetPolicy;
1461 return DEFAULT_SIZE_SCALE_POLICY;
1464 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1466 EnsureRelayoutData();
1468 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1470 if( dimension & ( 1 << i ) )
1472 mRelayoutData->dimensionDependencies[ i ] = dependency;
1477 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1479 if ( mRelayoutData )
1481 // If more than one dimension is requested, just return the first one found
1482 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1484 if( ( dimension & ( 1 << i ) ) )
1486 return mRelayoutData->dimensionDependencies[ i ];
1491 return Dimension::ALL_DIMENSIONS; // Default
1494 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1496 // If relayout data has not been allocated yet and the client is requesting
1497 // to disable it, do nothing
1498 if( mRelayoutData || relayoutEnabled )
1500 EnsureRelayoutData();
1502 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1504 mRelayoutData->relayoutEnabled = relayoutEnabled;
1508 bool Actor::IsRelayoutEnabled() const
1510 // Assume that if relayout data has not been allocated yet then
1511 // relayout is disabled
1512 return mRelayoutData && mRelayoutData->relayoutEnabled;
1515 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1517 EnsureRelayoutData();
1519 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1521 if( dimension & ( 1 << i ) )
1523 mRelayoutData->dimensionDirty[ i ] = dirty;
1528 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1530 if ( mRelayoutData )
1532 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1534 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1544 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1546 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1549 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1551 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1554 unsigned int Actor::AddRenderer( Renderer& renderer )
1558 mRenderers = new RendererContainer;
1561 unsigned int index = mRenderers->size();
1562 RendererPtr rendererPtr = RendererPtr( &renderer );
1563 mRenderers->push_back( rendererPtr );
1564 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1568 unsigned int Actor::GetRendererCount() const
1570 unsigned int rendererCount(0);
1573 rendererCount = mRenderers->size();
1576 return rendererCount;
1579 RendererPtr Actor::GetRendererAt( unsigned int index )
1581 RendererPtr renderer;
1582 if( index < GetRendererCount() )
1584 renderer = ( *mRenderers )[ index ];
1590 void Actor::RemoveRenderer( Renderer& renderer )
1594 RendererIter end = mRenderers->end();
1595 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1597 if( (*iter).Get() == &renderer )
1599 mRenderers->erase( iter );
1600 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1607 void Actor::RemoveRenderer( unsigned int index )
1609 if( index < GetRendererCount() )
1611 RendererPtr renderer = ( *mRenderers )[ index ];
1612 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1613 mRenderers->erase( mRenderers->begin()+index );
1617 bool Actor::IsOverlay() const
1619 return ( DrawMode::OVERLAY_2D == mDrawMode );
1622 void Actor::SetDrawMode( DrawMode::Type drawMode )
1624 // this flag is not animatable so keep the value
1625 mDrawMode = drawMode;
1626 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1628 // mNode is being used in a separate thread; queue a message to set the value
1629 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1633 DrawMode::Type Actor::GetDrawMode() const
1638 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1640 // only valid when on-stage
1641 StagePtr stage = Stage::GetCurrent();
1642 if( stage && OnStage() )
1644 const RenderTaskList& taskList = stage->GetRenderTaskList();
1646 Vector2 converted( screenX, screenY );
1648 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1649 const int taskCount = taskList.GetTaskCount();
1650 for( int i = taskCount - 1; i >= 0; --i )
1652 Dali::RenderTask task = taskList.GetTask( i );
1653 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1655 // found a task where this conversion was ok so return
1663 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1665 bool retval = false;
1666 // only valid when on-stage
1669 CameraActor* camera = renderTask.GetCameraActor();
1673 renderTask.GetViewport( viewport );
1675 // need to translate coordinates to render tasks coordinate space
1676 Vector2 converted( screenX, screenY );
1677 if( renderTask.TranslateCoordinates( converted ) )
1679 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1686 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1688 // Early-out if mNode is NULL
1694 // Get the ModelView matrix
1696 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1698 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1699 Matrix invertedMvp( false/*don't init*/);
1700 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1701 bool success = invertedMvp.Invert();
1703 // Convert to GL coordinates
1704 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1709 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1716 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1722 if( XyPlaneIntersect( nearPos, farPos, local ) )
1724 Vector3 size = GetCurrentSize();
1725 localX = local.x + size.x * 0.5f;
1726 localY = local.y + size.y * 0.5f;
1737 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1740 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1742 Mathematical Formulation
1744 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1746 ( p - c ) dot ( p - c ) = r^2
1748 Given a ray with a point of origin 'o', and a direction vector 'd':
1750 ray(t) = o + td, t >= 0
1752 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1754 (o + td - c ) dot ( o + td - c ) = r^2
1756 To solve for t we first expand the above into a more recognisable quadratic equation form
1758 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1767 B = 2( o - c ) dot d
1768 C = ( o - c ) dot ( o - c ) - r^2
1770 which can be solved using a standard quadratic formula.
1772 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1774 Practical Simplification
1776 In a renderer, we often differentiate between world space and object space. In the object space
1777 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1778 into object space, the mathematical solution presented above can be simplified significantly.
1780 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1784 and we can find the t at which the (transformed) ray intersects the sphere by
1786 ( o + td ) dot ( o + td ) = r^2
1788 According to the reasoning above, we expand the above quadratic equation into the general form
1792 which now has coefficients:
1799 // Early out if mNode is NULL
1805 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1807 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1808 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1809 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1811 // Compute the radius is not needed, square radius it's enough.
1812 const Vector3& size( mNode->GetSize( bufferIndex ) );
1814 // Scale the sphere.
1815 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1817 const float width = size.width * scale.width;
1818 const float height = size.height * scale.height;
1820 float squareSphereRadius = 0.5f * ( width * width + height * height );
1822 float a = rayDir.Dot( rayDir ); // a
1823 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1824 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1826 return ( b2 * b2 - a * c ) >= 0.f;
1829 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1833 if( OnStage() && NULL != mNode )
1835 // Transforms the ray to the local reference system.
1836 // Calculate the inverse of Model matrix
1837 Matrix invModelMatrix( false/*don't init*/);
1839 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1840 invModelMatrix = mNode->GetWorldMatrix(0);
1841 invModelMatrix.Invert();
1843 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1844 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1846 // Test with the actor's XY plane (Normal = 0 0 1 1).
1848 float a = -rayOriginLocal.z;
1849 float b = rayDirLocal.z;
1851 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1853 // Ray travels distance * rayDirLocal to intersect with plane.
1856 const Vector3& size = mNode->GetSize( bufferIndex );
1858 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1859 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1861 // Test with the actor's geometry.
1862 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1869 void Actor::SetLeaveRequired( bool required )
1871 mLeaveRequired = required;
1874 bool Actor::GetLeaveRequired() const
1876 return mLeaveRequired;
1879 void Actor::SetKeyboardFocusable( bool focusable )
1881 mKeyboardFocusable = focusable;
1884 bool Actor::IsKeyboardFocusable() const
1886 return mKeyboardFocusable;
1889 bool Actor::GetTouchRequired() const
1891 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1894 bool Actor::GetHoverRequired() const
1896 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1899 bool Actor::GetWheelEventRequired() const
1901 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1904 bool Actor::IsHittable() const
1906 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1909 ActorGestureData& Actor::GetGestureData()
1911 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1912 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1913 if( NULL == mGestureData )
1915 mGestureData = new ActorGestureData;
1917 return *mGestureData;
1920 bool Actor::IsGestureRequred( Gesture::Type type ) const
1922 return mGestureData && mGestureData->IsGestureRequred( type );
1925 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1927 bool consumed = false;
1929 if( !mTouchSignal.Empty() )
1931 Dali::Actor handle( this );
1932 consumed = mTouchSignal.Emit( handle, touch );
1935 if( !mTouchedSignal.Empty() )
1937 Dali::Actor handle( this );
1938 consumed |= mTouchedSignal.Emit( handle, event );
1943 // Notification for derived classes
1944 consumed = OnTouchEvent( event ); // TODO
1950 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1952 bool consumed = false;
1954 if( !mHoveredSignal.Empty() )
1956 Dali::Actor handle( this );
1957 consumed = mHoveredSignal.Emit( handle, event );
1962 // Notification for derived classes
1963 consumed = OnHoverEvent( event );
1969 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1971 bool consumed = false;
1973 if( !mWheelEventSignal.Empty() )
1975 Dali::Actor handle( this );
1976 consumed = mWheelEventSignal.Emit( handle, event );
1981 // Notification for derived classes
1982 consumed = OnWheelEvent( event );
1988 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1990 if( ! mVisibilityChangedSignal.Empty() )
1992 Dali::Actor handle( this );
1993 mVisibilityChangedSignal.Emit( handle, visible, type );
1997 void Actor::EmitLayoutDirectionChangedSignal( DevelActor::LayoutDirection::Type type )
1999 if( ! mLayoutDirectionChangedSignal.Empty() )
2001 Dali::Actor handle( this );
2002 mLayoutDirectionChangedSignal.Emit( handle, type );
2006 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
2008 return mTouchedSignal;
2011 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
2013 return mTouchSignal;
2016 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2018 return mHoveredSignal;
2021 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
2023 return mWheelEventSignal;
2026 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2028 return mOnStageSignal;
2031 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2033 return mOffStageSignal;
2036 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2038 return mOnRelayoutSignal;
2041 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
2043 return mVisibilityChangedSignal;
2046 DevelActor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
2048 return mLayoutDirectionChangedSignal;
2051 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2053 bool connected( true );
2054 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2056 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2058 actor->TouchedSignal().Connect( tracker, functor );
2060 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2062 actor->HoveredSignal().Connect( tracker, functor );
2064 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2066 actor->WheelEventSignal().Connect( tracker, functor );
2068 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2070 actor->OnStageSignal().Connect( tracker, functor );
2072 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2074 actor->OffStageSignal().Connect( tracker, functor );
2076 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2078 actor->OnRelayoutSignal().Connect( tracker, functor );
2080 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2082 actor->TouchSignal().Connect( tracker, functor );
2086 // signalName does not match any signal
2093 Actor::Actor( DerivedType derivedType )
2098 mParentOrigin( NULL ),
2099 mAnchorPoint( NULL ),
2100 mRelayoutData( NULL ),
2101 mGestureData( NULL ),
2102 mTargetOrientation( Quaternion::IDENTITY ),
2103 mTargetColor( Color::WHITE ),
2104 mTargetSize( Vector3::ZERO ),
2105 mTargetPosition( Vector3::ZERO ),
2106 mTargetScale( Vector3::ONE ),
2108 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2111 mIsRoot( ROOT_LAYER == derivedType ),
2112 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2113 mIsOnStage( false ),
2115 mLeaveRequired( false ),
2116 mKeyboardFocusable( false ),
2117 mDerivedRequiresTouch( false ),
2118 mDerivedRequiresHover( false ),
2119 mDerivedRequiresWheelEvent( false ),
2120 mOnStageSignalled( false ),
2121 mInsideOnSizeSet( false ),
2122 mInheritPosition( true ),
2123 mInheritOrientation( true ),
2124 mInheritScale( true ),
2125 mPositionUsesAnchorPoint( true ),
2127 mLayoutDirectionInheritance( true ),
2128 mLayoutDirection( DevelActor::LayoutDirection::LTR ),
2129 mDrawMode( DrawMode::NORMAL ),
2130 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2131 mColorMode( Node::DEFAULT_COLOR_MODE ),
2132 mClippingMode( ClippingMode::DISABLED )
2136 void Actor::Initialize()
2138 // Node creation, keep raw-pointer to Node for messaging
2139 mNode = CreateNode();
2140 OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
2141 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
2145 GetEventThreadServices().RegisterObject( this );
2150 // Remove mParent pointers from children even if we're destroying core,
2151 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2154 ActorConstIter endIter = mChildren->end();
2155 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2157 (*iter)->SetParent( NULL );
2163 // Guard to allow handle destruction after Core has been destroyed
2164 if( EventThreadServices::IsCoreRunning() )
2168 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2169 mNode = NULL; // Node is about to be destroyed
2172 GetEventThreadServices().UnregisterObject( this );
2175 // Cleanup optional gesture data
2176 delete mGestureData;
2178 // Cleanup optional parent origin and anchor
2179 delete mParentOrigin;
2180 delete mAnchorPoint;
2182 // Delete optional relayout data
2185 delete mRelayoutData;
2189 void Actor::ConnectToStage( unsigned int parentDepth )
2191 // This container is used instead of walking the Actor hierarchy.
2192 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2193 ActorContainer connectionList;
2195 StagePtr stage = Stage::GetCurrent();
2198 stage->RequestRebuildDepthTree();
2201 // This stage is atomic i.e. not interrupted by user callbacks.
2202 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2204 // Notify applications about the newly connected actors.
2205 const ActorIter endIter = connectionList.end();
2206 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2208 (*iter)->NotifyStageConnection();
2214 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2216 DALI_ASSERT_ALWAYS( !OnStage() );
2221 ConnectToSceneGraph();
2223 // Notification for internal derived classes
2224 OnStageConnectionInternal();
2226 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2227 connectionList.push_back( ActorPtr( this ) );
2229 // Recursively connect children
2232 ActorConstIter endIter = mChildren->end();
2233 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2235 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2241 * This method is called when the Actor is connected to the Stage.
2242 * The parent must have added its Node to the scene-graph.
2243 * The child must connect its Node to the parent's Node.
2244 * This is recursive; the child calls ConnectToStage() for its children.
2246 void Actor::ConnectToSceneGraph()
2248 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2252 // Reparent Node in next Update
2253 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2256 // Request relayout on all actors that are added to the scenegraph
2259 // Notification for Object::Observers
2263 void Actor::NotifyStageConnection()
2265 // Actors can be removed (in a callback), before the on-stage stage is reported.
2266 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2267 if( OnStage() && !mOnStageSignalled )
2269 // Notification for external (CustomActor) derived classes
2270 OnStageConnectionExternal( mDepth );
2272 if( !mOnStageSignal.Empty() )
2274 Dali::Actor handle( this );
2275 mOnStageSignal.Emit( handle );
2278 // Guard against Remove during callbacks
2281 mOnStageSignalled = true; // signal required next time Actor is removed
2286 void Actor::DisconnectFromStage()
2288 // This container is used instead of walking the Actor hierachy.
2289 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2290 ActorContainer disconnectionList;
2292 StagePtr stage = Stage::GetCurrent();
2295 stage->RequestRebuildDepthTree();
2298 // This stage is atomic i.e. not interrupted by user callbacks
2299 RecursiveDisconnectFromStage( disconnectionList );
2301 // Notify applications about the newly disconnected actors.
2302 const ActorIter endIter = disconnectionList.end();
2303 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2305 (*iter)->NotifyStageDisconnection();
2309 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2311 DALI_ASSERT_ALWAYS( OnStage() );
2313 // Recursively disconnect children
2316 ActorConstIter endIter = mChildren->end();
2317 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2319 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2323 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2324 disconnectionList.push_back( ActorPtr( this ) );
2326 // Notification for internal derived classes
2327 OnStageDisconnectionInternal();
2329 DisconnectFromSceneGraph();
2335 * This method is called by an actor or its parent, before a node removal message is sent.
2336 * This is recursive; the child calls DisconnectFromStage() for its children.
2338 void Actor::DisconnectFromSceneGraph()
2340 // Notification for Object::Observers
2341 OnSceneObjectRemove();
2344 void Actor::NotifyStageDisconnection()
2346 // Actors can be added (in a callback), before the off-stage state is reported.
2347 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2348 // only do this step if there is a stage, i.e. Core is not being shut down
2349 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2351 // Notification for external (CustomeActor) derived classes
2352 OnStageDisconnectionExternal();
2354 if( !mOffStageSignal.Empty() )
2356 Dali::Actor handle( this );
2357 mOffStageSignal.Emit( handle );
2360 // Guard against Add during callbacks
2363 mOnStageSignalled = false; // signal required next time Actor is added
2368 bool Actor::IsNodeConnected() const
2370 bool connected( false );
2372 if( OnStage() && ( NULL != mNode ) )
2374 if( IsRoot() || mNode->GetParent() )
2383 // This method initiates traversal of the actor tree using depth-first
2384 // traversal to set a depth index based on traversal order. It sends a
2385 // single message to update manager to update all the actor's nodes in
2386 // this tree with the depth index. The sceneGraphNodeDepths vector's
2387 // elements are ordered by depth, and could be used to reduce sorting
2388 // in the update thread.
2389 void Actor::RebuildDepthTree()
2391 DALI_LOG_TIMER_START(depthTimer);
2393 // Vector of scene-graph nodes and their depths to send to UpdateManager
2394 // in a single message
2395 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2398 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2400 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2401 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2404 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
2406 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2407 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
2409 // Create/add to children of this node
2412 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2414 Actor* childActor = (*it).Get();
2416 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2421 unsigned int Actor::GetDefaultPropertyCount() const
2423 return DEFAULT_PROPERTY_COUNT;
2426 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2428 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2430 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2432 indices.PushBack( i );
2436 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2438 if( index < DEFAULT_PROPERTY_COUNT )
2440 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2446 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2448 Property::Index index = Property::INVALID_INDEX;
2450 // Look for name in default properties
2451 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2453 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2454 if( 0 == name.compare( property->name ) )
2464 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2466 if( index < DEFAULT_PROPERTY_COUNT )
2468 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2474 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2476 if( index < DEFAULT_PROPERTY_COUNT )
2478 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2484 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2486 if( index < DEFAULT_PROPERTY_COUNT )
2488 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2494 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2496 if( index < DEFAULT_PROPERTY_COUNT )
2498 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2501 // index out of range...return Property::NONE
2502 return Property::NONE;
2505 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2509 case Dali::Actor::Property::PARENT_ORIGIN:
2511 Property::Type type = property.GetType();
2512 if( type == Property::VECTOR3 )
2514 SetParentOrigin( property.Get< Vector3 >() );
2516 else if ( type == Property::STRING )
2518 std::string parentOriginString;
2519 property.Get( parentOriginString );
2520 Vector3 parentOrigin;
2521 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2523 SetParentOrigin( parentOrigin );
2529 case Dali::Actor::Property::PARENT_ORIGIN_X:
2531 SetParentOriginX( property.Get< float >() );
2535 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2537 SetParentOriginY( property.Get< float >() );
2541 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2543 SetParentOriginZ( property.Get< float >() );
2547 case Dali::Actor::Property::ANCHOR_POINT:
2549 Property::Type type = property.GetType();
2550 if( type == Property::VECTOR3 )
2552 SetAnchorPoint( property.Get< Vector3 >() );
2554 else if ( type == Property::STRING )
2556 std::string anchorPointString;
2557 property.Get( anchorPointString );
2559 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2561 SetAnchorPoint( anchor );
2567 case Dali::Actor::Property::ANCHOR_POINT_X:
2569 SetAnchorPointX( property.Get< float >() );
2573 case Dali::Actor::Property::ANCHOR_POINT_Y:
2575 SetAnchorPointY( property.Get< float >() );
2579 case Dali::Actor::Property::ANCHOR_POINT_Z:
2581 SetAnchorPointZ( property.Get< float >() );
2585 case Dali::Actor::Property::SIZE:
2587 SetSize( property.Get< Vector3 >() );
2591 case Dali::Actor::Property::SIZE_WIDTH:
2593 SetWidth( property.Get< float >() );
2597 case Dali::Actor::Property::SIZE_HEIGHT:
2599 SetHeight( property.Get< float >() );
2603 case Dali::Actor::Property::SIZE_DEPTH:
2605 SetDepth( property.Get< float >() );
2609 case Dali::Actor::Property::POSITION:
2611 SetPosition( property.Get< Vector3 >() );
2615 case Dali::Actor::Property::POSITION_X:
2617 SetX( property.Get< float >() );
2621 case Dali::Actor::Property::POSITION_Y:
2623 SetY( property.Get< float >() );
2627 case Dali::Actor::Property::POSITION_Z:
2629 SetZ( property.Get< float >() );
2633 case Dali::Actor::Property::ORIENTATION:
2635 SetOrientation( property.Get< Quaternion >() );
2639 case Dali::Actor::Property::SCALE:
2641 SetScale( property.Get< Vector3 >() );
2645 case Dali::Actor::Property::SCALE_X:
2647 SetScaleX( property.Get< float >() );
2651 case Dali::Actor::Property::SCALE_Y:
2653 SetScaleY( property.Get< float >() );
2657 case Dali::Actor::Property::SCALE_Z:
2659 SetScaleZ( property.Get< float >() );
2663 case Dali::Actor::Property::VISIBLE:
2665 SetVisible( property.Get< bool >() );
2669 case Dali::Actor::Property::COLOR:
2671 SetColor( property.Get< Vector4 >() );
2675 case Dali::Actor::Property::COLOR_RED:
2677 SetColorRed( property.Get< float >() );
2681 case Dali::Actor::Property::COLOR_GREEN:
2683 SetColorGreen( property.Get< float >() );
2687 case Dali::Actor::Property::COLOR_BLUE:
2689 SetColorBlue( property.Get< float >() );
2693 case Dali::Actor::Property::COLOR_ALPHA:
2694 case Dali::DevelActor::Property::OPACITY:
2697 if( property.Get( value ) )
2699 SetOpacity( value );
2704 case Dali::Actor::Property::NAME:
2706 SetName( property.Get< std::string >() );
2710 case Dali::Actor::Property::SENSITIVE:
2712 SetSensitive( property.Get< bool >() );
2716 case Dali::Actor::Property::LEAVE_REQUIRED:
2718 SetLeaveRequired( property.Get< bool >() );
2722 case Dali::Actor::Property::INHERIT_POSITION:
2724 SetInheritPosition( property.Get< bool >() );
2728 case Dali::Actor::Property::INHERIT_ORIENTATION:
2730 SetInheritOrientation( property.Get< bool >() );
2734 case Dali::Actor::Property::INHERIT_SCALE:
2736 SetInheritScale( property.Get< bool >() );
2740 case Dali::Actor::Property::COLOR_MODE:
2742 ColorMode mode = mColorMode;
2743 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2745 SetColorMode( mode );
2750 case Dali::Actor::Property::POSITION_INHERITANCE:
2752 PositionInheritanceMode mode = mPositionInheritanceMode;
2753 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2755 SetPositionInheritanceMode( mode );
2760 case Dali::Actor::Property::DRAW_MODE:
2762 DrawMode::Type mode = mDrawMode;
2763 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2765 SetDrawMode( mode );
2770 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2772 SetSizeModeFactor( property.Get< Vector3 >() );
2776 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2778 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2779 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2781 SetResizePolicy( type, Dimension::WIDTH );
2786 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2788 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2789 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2791 SetResizePolicy( type, Dimension::HEIGHT );
2796 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2798 SizeScalePolicy::Type type;
2799 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2801 SetSizeScalePolicy( type );
2806 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2808 if( property.Get< bool >() )
2810 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2815 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2817 if( property.Get< bool >() )
2819 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2824 case Dali::Actor::Property::PADDING:
2826 Vector4 padding = property.Get< Vector4 >();
2827 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2828 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2832 case Dali::Actor::Property::MINIMUM_SIZE:
2834 Vector2 size = property.Get< Vector2 >();
2835 SetMinimumSize( size.x, Dimension::WIDTH );
2836 SetMinimumSize( size.y, Dimension::HEIGHT );
2840 case Dali::Actor::Property::MAXIMUM_SIZE:
2842 Vector2 size = property.Get< Vector2 >();
2843 SetMaximumSize( size.x, Dimension::WIDTH );
2844 SetMaximumSize( size.y, Dimension::HEIGHT );
2848 case Dali::DevelActor::Property::SIBLING_ORDER:
2852 if( property.Get( value ) )
2854 SetSiblingOrder( value );
2859 case Dali::Actor::Property::CLIPPING_MODE:
2861 ClippingMode::Type convertedValue = mClippingMode;
2862 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2864 mClippingMode = convertedValue;
2867 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2873 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2876 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2878 mPositionUsesAnchorPoint = value;
2881 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2887 case Dali::DevelActor::Property::LAYOUT_DIRECTION:
2889 Dali::DevelActor::LayoutDirection::Type direction = mLayoutDirection;
2892 if( Scripting::GetEnumerationProperty< DevelActor::LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2894 flag = mLayoutDirectionInheritance;
2895 mLayoutDirectionInheritance = true;
2896 InheritLayoutDirectionRecursively( this, direction );
2897 mLayoutDirectionInheritance = flag;
2902 case Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE:
2905 if( property.Get( value ) && value != mLayoutDirectionInheritance )
2907 mLayoutDirectionInheritance = value;
2914 // this can happen in the case of a non-animatable default property so just do nothing
2920 // TODO: This method needs to be removed
2921 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2923 switch( entry.GetType() )
2925 case Property::BOOLEAN:
2927 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2928 DALI_ASSERT_DEBUG( NULL != property );
2930 // property is being used in a separate thread; queue a message to set the property
2931 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2936 case Property::INTEGER:
2938 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2939 DALI_ASSERT_DEBUG( NULL != property );
2941 // property is being used in a separate thread; queue a message to set the property
2942 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2947 case Property::FLOAT:
2949 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2950 DALI_ASSERT_DEBUG( NULL != property );
2952 // property is being used in a separate thread; queue a message to set the property
2953 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2958 case Property::VECTOR2:
2960 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2961 DALI_ASSERT_DEBUG( NULL != property );
2963 // property is being used in a separate thread; queue a message to set the property
2964 if(entry.componentIndex == 0)
2966 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2968 else if(entry.componentIndex == 1)
2970 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2974 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2980 case Property::VECTOR3:
2982 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2983 DALI_ASSERT_DEBUG( NULL != property );
2985 // property is being used in a separate thread; queue a message to set the property
2986 if(entry.componentIndex == 0)
2988 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2990 else if(entry.componentIndex == 1)
2992 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2994 else if(entry.componentIndex == 2)
2996 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
3000 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
3006 case Property::VECTOR4:
3008 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
3009 DALI_ASSERT_DEBUG( NULL != property );
3011 // property is being used in a separate thread; queue a message to set the property
3012 if(entry.componentIndex == 0)
3014 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3016 else if(entry.componentIndex == 1)
3018 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3020 else if(entry.componentIndex == 2)
3022 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3024 else if(entry.componentIndex == 3)
3026 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3030 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3036 case Property::ROTATION:
3038 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3039 DALI_ASSERT_DEBUG( NULL != property );
3041 // property is being used in a separate thread; queue a message to set the property
3042 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
3047 case Property::MATRIX:
3049 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3050 DALI_ASSERT_DEBUG( NULL != property );
3052 // property is being used in a separate thread; queue a message to set the property
3053 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
3058 case Property::MATRIX3:
3060 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3061 DALI_ASSERT_DEBUG( NULL != property );
3063 // property is being used in a separate thread; queue a message to set the property
3064 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
3071 // nothing to do for other types
3076 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3078 Property::Value value;
3080 if( ! GetCachedPropertyValue( index, value ) )
3082 // If property value is not stored in the event-side, then it must be a scene-graph only property
3083 GetCurrentPropertyValue( index, value );
3089 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3091 Property::Value value;
3093 if( ! GetCurrentPropertyValue( index, value ) )
3095 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3096 GetCachedPropertyValue( index, value );
3102 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3104 switch( animationType )
3107 case Animation::BETWEEN:
3111 case Dali::Actor::Property::SIZE:
3113 if( value.Get( mTargetSize ) )
3115 // Notify deriving classes
3116 OnSizeAnimation( animation, mTargetSize );
3121 case Dali::Actor::Property::SIZE_WIDTH:
3123 if( value.Get( mTargetSize.width ) )
3125 // Notify deriving classes
3126 OnSizeAnimation( animation, mTargetSize );
3131 case Dali::Actor::Property::SIZE_HEIGHT:
3133 if( value.Get( mTargetSize.height ) )
3135 // Notify deriving classes
3136 OnSizeAnimation( animation, mTargetSize );
3141 case Dali::Actor::Property::SIZE_DEPTH:
3143 if( value.Get( mTargetSize.depth ) )
3145 // Notify deriving classes
3146 OnSizeAnimation( animation, mTargetSize );
3151 case Dali::Actor::Property::POSITION:
3153 value.Get( mTargetPosition );
3157 case Dali::Actor::Property::POSITION_X:
3159 value.Get( mTargetPosition.x );
3163 case Dali::Actor::Property::POSITION_Y:
3165 value.Get( mTargetPosition.y );
3169 case Dali::Actor::Property::POSITION_Z:
3171 value.Get( mTargetPosition.z );
3175 case Dali::Actor::Property::ORIENTATION:
3177 value.Get( mTargetOrientation );
3181 case Dali::Actor::Property::SCALE:
3183 value.Get( mTargetScale );
3187 case Dali::Actor::Property::SCALE_X:
3189 value.Get( mTargetScale.x );
3193 case Dali::Actor::Property::SCALE_Y:
3195 value.Get( mTargetScale.y );
3199 case Dali::Actor::Property::SCALE_Z:
3201 value.Get( mTargetScale.z );
3205 case Dali::Actor::Property::VISIBLE:
3207 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3211 case Dali::Actor::Property::COLOR:
3213 value.Get( mTargetColor );
3217 case Dali::Actor::Property::COLOR_RED:
3219 value.Get( mTargetColor.r );
3223 case Dali::Actor::Property::COLOR_GREEN:
3225 value.Get( mTargetColor.g );
3229 case Dali::Actor::Property::COLOR_BLUE:
3231 value.Get( mTargetColor.b );
3235 case Dali::Actor::Property::COLOR_ALPHA:
3236 case Dali::DevelActor::Property::OPACITY:
3238 value.Get( mTargetColor.a );
3244 // Not an animatable property. Do nothing.
3255 case Dali::Actor::Property::SIZE:
3257 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3259 // Notify deriving classes
3260 OnSizeAnimation( animation, mTargetSize );
3265 case Dali::Actor::Property::SIZE_WIDTH:
3267 if( AdjustValue< float >( mTargetSize.width, value ) )
3269 // Notify deriving classes
3270 OnSizeAnimation( animation, mTargetSize );
3275 case Dali::Actor::Property::SIZE_HEIGHT:
3277 if( AdjustValue< float >( mTargetSize.height, value ) )
3279 // Notify deriving classes
3280 OnSizeAnimation( animation, mTargetSize );
3285 case Dali::Actor::Property::SIZE_DEPTH:
3287 if( AdjustValue< float >( mTargetSize.depth, value ) )
3289 // Notify deriving classes
3290 OnSizeAnimation( animation, mTargetSize );
3295 case Dali::Actor::Property::POSITION:
3297 AdjustValue< Vector3 >( mTargetPosition, value );
3301 case Dali::Actor::Property::POSITION_X:
3303 AdjustValue< float >( mTargetPosition.x, value );
3307 case Dali::Actor::Property::POSITION_Y:
3309 AdjustValue< float >( mTargetPosition.y, value );
3313 case Dali::Actor::Property::POSITION_Z:
3315 AdjustValue< float >( mTargetPosition.z, value );
3319 case Dali::Actor::Property::ORIENTATION:
3321 Quaternion relativeValue;
3322 if( value.Get( relativeValue ) )
3324 mTargetOrientation *= relativeValue;
3329 case Dali::Actor::Property::SCALE:
3331 AdjustValue< Vector3 >( mTargetScale, value );
3335 case Dali::Actor::Property::SCALE_X:
3337 AdjustValue< float >( mTargetScale.x, value );
3341 case Dali::Actor::Property::SCALE_Y:
3343 AdjustValue< float >( mTargetScale.y, value );
3347 case Dali::Actor::Property::SCALE_Z:
3349 AdjustValue< float >( mTargetScale.z, value );
3353 case Dali::Actor::Property::VISIBLE:
3355 bool relativeValue = false;
3356 if( value.Get( relativeValue ) )
3358 bool visible = mVisible || relativeValue;
3359 SetVisibleInternal( visible, SendMessage::FALSE );
3364 case Dali::Actor::Property::COLOR:
3366 AdjustValue< Vector4 >( mTargetColor, value );
3370 case Dali::Actor::Property::COLOR_RED:
3372 AdjustValue< float >( mTargetColor.r, value );
3376 case Dali::Actor::Property::COLOR_GREEN:
3378 AdjustValue< float >( mTargetColor.g, value );
3382 case Dali::Actor::Property::COLOR_BLUE:
3384 AdjustValue< float >( mTargetColor.b, value );
3388 case Dali::Actor::Property::COLOR_ALPHA:
3389 case Dali::DevelActor::Property::OPACITY:
3391 AdjustValue< float >( mTargetColor.a, value );
3397 // Not an animatable property. Do nothing.
3406 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3411 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3413 // This method should only return an object connected to the scene-graph
3414 return OnStage() ? mNode : NULL;
3417 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3419 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3421 const PropertyBase* property( NULL );
3423 // This method should only return a property of an object connected to the scene-graph
3429 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3431 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3432 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3434 property = animatable->GetSceneGraphProperty();
3436 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3437 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3439 CustomPropertyMetadata* custom = FindCustomProperty( index );
3440 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3442 property = custom->GetSceneGraphProperty();
3444 else if( NULL != mNode )
3448 case Dali::Actor::Property::SIZE:
3449 property = &mNode->mSize;
3452 case Dali::Actor::Property::SIZE_WIDTH:
3453 property = &mNode->mSize;
3456 case Dali::Actor::Property::SIZE_HEIGHT:
3457 property = &mNode->mSize;
3460 case Dali::Actor::Property::SIZE_DEPTH:
3461 property = &mNode->mSize;
3464 case Dali::Actor::Property::POSITION:
3465 property = &mNode->mPosition;
3468 case Dali::Actor::Property::POSITION_X:
3469 property = &mNode->mPosition;
3472 case Dali::Actor::Property::POSITION_Y:
3473 property = &mNode->mPosition;
3476 case Dali::Actor::Property::POSITION_Z:
3477 property = &mNode->mPosition;
3480 case Dali::Actor::Property::ORIENTATION:
3481 property = &mNode->mOrientation;
3484 case Dali::Actor::Property::SCALE:
3485 property = &mNode->mScale;
3488 case Dali::Actor::Property::SCALE_X:
3489 property = &mNode->mScale;
3492 case Dali::Actor::Property::SCALE_Y:
3493 property = &mNode->mScale;
3496 case Dali::Actor::Property::SCALE_Z:
3497 property = &mNode->mScale;
3500 case Dali::Actor::Property::VISIBLE:
3501 property = &mNode->mVisible;
3504 case Dali::Actor::Property::COLOR:
3505 property = &mNode->mColor;
3508 case Dali::Actor::Property::COLOR_RED:
3509 property = &mNode->mColor;
3512 case Dali::Actor::Property::COLOR_GREEN:
3513 property = &mNode->mColor;
3516 case Dali::Actor::Property::COLOR_BLUE:
3517 property = &mNode->mColor;
3520 case Dali::Actor::Property::COLOR_ALPHA:
3521 case Dali::DevelActor::Property::OPACITY:
3522 property = &mNode->mColor;
3533 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3535 const PropertyInputImpl* property( NULL );
3537 // This method should only return a property of an object connected to the scene-graph
3543 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3545 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3546 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3548 property = animatable->GetSceneGraphProperty();
3550 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3551 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3553 CustomPropertyMetadata* custom = FindCustomProperty( index );
3554 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3555 property = custom->GetSceneGraphProperty();
3557 else if( NULL != mNode )
3561 case Dali::Actor::Property::PARENT_ORIGIN:
3562 property = &mNode->mParentOrigin;
3565 case Dali::Actor::Property::PARENT_ORIGIN_X:
3566 property = &mNode->mParentOrigin;
3569 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3570 property = &mNode->mParentOrigin;
3573 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3574 property = &mNode->mParentOrigin;
3577 case Dali::Actor::Property::ANCHOR_POINT:
3578 property = &mNode->mAnchorPoint;
3581 case Dali::Actor::Property::ANCHOR_POINT_X:
3582 property = &mNode->mAnchorPoint;
3585 case Dali::Actor::Property::ANCHOR_POINT_Y:
3586 property = &mNode->mAnchorPoint;
3589 case Dali::Actor::Property::ANCHOR_POINT_Z:
3590 property = &mNode->mAnchorPoint;
3593 case Dali::Actor::Property::SIZE:
3594 property = &mNode->mSize;
3597 case Dali::Actor::Property::SIZE_WIDTH:
3598 property = &mNode->mSize;
3601 case Dali::Actor::Property::SIZE_HEIGHT:
3602 property = &mNode->mSize;
3605 case Dali::Actor::Property::SIZE_DEPTH:
3606 property = &mNode->mSize;
3609 case Dali::Actor::Property::POSITION:
3610 property = &mNode->mPosition;
3613 case Dali::Actor::Property::POSITION_X:
3614 property = &mNode->mPosition;
3617 case Dali::Actor::Property::POSITION_Y:
3618 property = &mNode->mPosition;
3621 case Dali::Actor::Property::POSITION_Z:
3622 property = &mNode->mPosition;
3625 case Dali::Actor::Property::WORLD_POSITION:
3626 property = &mNode->mWorldPosition;
3629 case Dali::Actor::Property::WORLD_POSITION_X:
3630 property = &mNode->mWorldPosition;
3633 case Dali::Actor::Property::WORLD_POSITION_Y:
3634 property = &mNode->mWorldPosition;
3637 case Dali::Actor::Property::WORLD_POSITION_Z:
3638 property = &mNode->mWorldPosition;
3641 case Dali::Actor::Property::ORIENTATION:
3642 property = &mNode->mOrientation;
3645 case Dali::Actor::Property::WORLD_ORIENTATION:
3646 property = &mNode->mWorldOrientation;
3649 case Dali::Actor::Property::SCALE:
3650 property = &mNode->mScale;
3653 case Dali::Actor::Property::SCALE_X:
3654 property = &mNode->mScale;
3657 case Dali::Actor::Property::SCALE_Y:
3658 property = &mNode->mScale;
3661 case Dali::Actor::Property::SCALE_Z:
3662 property = &mNode->mScale;
3665 case Dali::Actor::Property::WORLD_SCALE:
3666 property = &mNode->mWorldScale;
3669 case Dali::Actor::Property::VISIBLE:
3670 property = &mNode->mVisible;
3673 case Dali::Actor::Property::COLOR:
3674 property = &mNode->mColor;
3677 case Dali::Actor::Property::COLOR_RED:
3678 property = &mNode->mColor;
3681 case Dali::Actor::Property::COLOR_GREEN:
3682 property = &mNode->mColor;
3685 case Dali::Actor::Property::COLOR_BLUE:
3686 property = &mNode->mColor;
3689 case Dali::Actor::Property::COLOR_ALPHA:
3690 case Dali::DevelActor::Property::OPACITY:
3692 property = &mNode->mColor;
3696 case Dali::Actor::Property::WORLD_COLOR:
3697 property = &mNode->mWorldColor;
3700 case Dali::Actor::Property::WORLD_MATRIX:
3701 property = &mNode->mWorldMatrix;
3712 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3714 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3716 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3718 // check whether the animatable property is registered already, if not then register one.
3719 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3720 if( animatableProperty )
3722 componentIndex = animatableProperty->componentIndex;
3729 case Dali::Actor::Property::PARENT_ORIGIN_X:
3730 case Dali::Actor::Property::ANCHOR_POINT_X:
3731 case Dali::Actor::Property::SIZE_WIDTH:
3732 case Dali::Actor::Property::POSITION_X:
3733 case Dali::Actor::Property::WORLD_POSITION_X:
3734 case Dali::Actor::Property::SCALE_X:
3735 case Dali::Actor::Property::COLOR_RED:
3741 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3742 case Dali::Actor::Property::ANCHOR_POINT_Y:
3743 case Dali::Actor::Property::SIZE_HEIGHT:
3744 case Dali::Actor::Property::POSITION_Y:
3745 case Dali::Actor::Property::WORLD_POSITION_Y:
3746 case Dali::Actor::Property::SCALE_Y:
3747 case Dali::Actor::Property::COLOR_GREEN:
3753 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3754 case Dali::Actor::Property::ANCHOR_POINT_Z:
3755 case Dali::Actor::Property::SIZE_DEPTH:
3756 case Dali::Actor::Property::POSITION_Z:
3757 case Dali::Actor::Property::WORLD_POSITION_Z:
3758 case Dali::Actor::Property::SCALE_Z:
3759 case Dali::Actor::Property::COLOR_BLUE:
3765 case Dali::Actor::Property::COLOR_ALPHA:
3766 case Dali::DevelActor::Property::OPACITY:
3780 return componentIndex;
3783 void Actor::SetParent( Actor* parent )
3787 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3791 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3794 // Instruct each actor to create a corresponding node in the scene graph
3795 ConnectToStage( parent->GetHierarchyDepth() );
3798 // Resolve the name and index for the child properties if any
3799 ResolveChildProperties();
3801 else // parent being set to NULL
3803 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3807 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3810 DALI_ASSERT_ALWAYS( mNode != NULL );
3814 // Disconnect the Node & its children from the scene-graph.
3815 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3818 // Instruct each actor to discard pointers to the scene-graph
3819 DisconnectFromStage();
3824 SceneGraph::Node* Actor::CreateNode() const
3829 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3832 Actor* actor = dynamic_cast< Actor* >( object );
3836 if( 0 == actionName.compare( ACTION_SHOW ) )
3838 actor->SetVisible( true );
3841 else if( 0 == actionName.compare( ACTION_HIDE ) )
3843 actor->SetVisible( false );
3851 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3853 bool valueSet = true;
3857 case Dali::Actor::Property::PARENT_ORIGIN:
3859 value = GetCurrentParentOrigin();
3863 case Dali::Actor::Property::PARENT_ORIGIN_X:
3865 value = GetCurrentParentOrigin().x;
3869 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3871 value = GetCurrentParentOrigin().y;
3875 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3877 value = GetCurrentParentOrigin().z;
3881 case Dali::Actor::Property::ANCHOR_POINT:
3883 value = GetCurrentAnchorPoint();
3887 case Dali::Actor::Property::ANCHOR_POINT_X:
3889 value = GetCurrentAnchorPoint().x;
3893 case Dali::Actor::Property::ANCHOR_POINT_Y:
3895 value = GetCurrentAnchorPoint().y;
3899 case Dali::Actor::Property::ANCHOR_POINT_Z:
3901 value = GetCurrentAnchorPoint().z;
3905 case Dali::Actor::Property::SIZE:
3907 value = GetTargetSize();
3911 case Dali::Actor::Property::SIZE_WIDTH:
3913 value = GetTargetSize().width;
3917 case Dali::Actor::Property::SIZE_HEIGHT:
3919 value = GetTargetSize().height;
3923 case Dali::Actor::Property::SIZE_DEPTH:
3925 value = GetTargetSize().depth;
3929 case Dali::Actor::Property::POSITION:
3931 value = GetTargetPosition();
3935 case Dali::Actor::Property::POSITION_X:
3937 value = GetTargetPosition().x;
3941 case Dali::Actor::Property::POSITION_Y:
3943 value = GetTargetPosition().y;
3947 case Dali::Actor::Property::POSITION_Z:
3949 value = GetTargetPosition().z;
3953 case Dali::Actor::Property::ORIENTATION:
3955 value = mTargetOrientation;
3959 case Dali::Actor::Property::SCALE:
3961 value = mTargetScale;
3965 case Dali::Actor::Property::SCALE_X:
3967 value = mTargetScale.x;
3971 case Dali::Actor::Property::SCALE_Y:
3973 value = mTargetScale.y;
3977 case Dali::Actor::Property::SCALE_Z:
3979 value = mTargetScale.z;
3983 case Dali::Actor::Property::VISIBLE:
3989 case Dali::Actor::Property::COLOR:
3991 value = mTargetColor;
3995 case Dali::Actor::Property::COLOR_RED:
3997 value = mTargetColor.r;
4001 case Dali::Actor::Property::COLOR_GREEN:
4003 value = mTargetColor.g;
4007 case Dali::Actor::Property::COLOR_BLUE:
4009 value = mTargetColor.b;
4013 case Dali::Actor::Property::COLOR_ALPHA:
4014 case Dali::DevelActor::Property::OPACITY:
4016 value = mTargetColor.a;
4020 case Dali::Actor::Property::NAME:
4026 case Dali::Actor::Property::SENSITIVE:
4028 value = IsSensitive();
4032 case Dali::Actor::Property::LEAVE_REQUIRED:
4034 value = GetLeaveRequired();
4038 case Dali::Actor::Property::INHERIT_POSITION:
4040 value = IsPositionInherited();
4044 case Dali::Actor::Property::INHERIT_ORIENTATION:
4046 value = IsOrientationInherited();
4050 case Dali::Actor::Property::INHERIT_SCALE:
4052 value = IsScaleInherited();
4056 case Dali::Actor::Property::COLOR_MODE:
4058 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4062 case Dali::Actor::Property::POSITION_INHERITANCE:
4064 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4068 case Dali::Actor::Property::DRAW_MODE:
4070 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4074 case Dali::Actor::Property::SIZE_MODE_FACTOR:
4076 value = GetSizeModeFactor();
4080 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4082 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4086 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4088 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4092 case Dali::Actor::Property::SIZE_SCALE_POLICY:
4094 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4098 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4100 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4104 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4106 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4110 case Dali::Actor::Property::PADDING:
4112 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4113 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4114 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4118 case Dali::Actor::Property::MINIMUM_SIZE:
4120 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4124 case Dali::Actor::Property::MAXIMUM_SIZE:
4126 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4130 case Dali::Actor::Property::CLIPPING_MODE:
4132 value = mClippingMode;
4136 case Dali::DevelActor::Property::SIBLING_ORDER:
4138 value = static_cast<int>( GetSiblingOrder() );
4142 case Dali::DevelActor::Property::SCREEN_POSITION:
4144 value = GetCurrentScreenPosition();
4148 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4150 value = mPositionUsesAnchorPoint;
4154 case Dali::DevelActor::Property::LAYOUT_DIRECTION:
4156 value = Scripting::GetLinearEnumerationName< DevelActor::LayoutDirection::Type >( mLayoutDirection, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT );
4160 case Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE:
4162 value = mLayoutDirectionInheritance;
4168 // Must be a scene-graph only property
4177 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
4179 bool valueSet = true;
4183 case Dali::Actor::Property::SIZE:
4185 value = GetCurrentSize();
4189 case Dali::Actor::Property::SIZE_WIDTH:
4191 value = GetCurrentSize().width;
4195 case Dali::Actor::Property::SIZE_HEIGHT:
4197 value = GetCurrentSize().height;
4201 case Dali::Actor::Property::SIZE_DEPTH:
4203 value = GetCurrentSize().depth;
4207 case Dali::Actor::Property::POSITION:
4209 value = GetCurrentPosition();
4213 case Dali::Actor::Property::POSITION_X:
4215 value = GetCurrentPosition().x;
4219 case Dali::Actor::Property::POSITION_Y:
4221 value = GetCurrentPosition().y;
4225 case Dali::Actor::Property::POSITION_Z:
4227 value = GetCurrentPosition().z;
4231 case Dali::Actor::Property::WORLD_POSITION:
4233 value = GetCurrentWorldPosition();
4237 case Dali::Actor::Property::WORLD_POSITION_X:
4239 value = GetCurrentWorldPosition().x;
4243 case Dali::Actor::Property::WORLD_POSITION_Y:
4245 value = GetCurrentWorldPosition().y;
4249 case Dali::Actor::Property::WORLD_POSITION_Z:
4251 value = GetCurrentWorldPosition().z;
4255 case Dali::Actor::Property::ORIENTATION:
4257 value = GetCurrentOrientation();
4261 case Dali::Actor::Property::WORLD_ORIENTATION:
4263 value = GetCurrentWorldOrientation();
4267 case Dali::Actor::Property::SCALE:
4269 value = GetCurrentScale();
4273 case Dali::Actor::Property::SCALE_X:
4275 value = GetCurrentScale().x;
4279 case Dali::Actor::Property::SCALE_Y:
4281 value = GetCurrentScale().y;
4285 case Dali::Actor::Property::SCALE_Z:
4287 value = GetCurrentScale().z;
4291 case Dali::Actor::Property::WORLD_SCALE:
4293 value = GetCurrentWorldScale();
4297 case Dali::Actor::Property::COLOR:
4299 value = GetCurrentColor();
4303 case Dali::Actor::Property::COLOR_RED:
4305 value = GetCurrentColor().r;
4309 case Dali::Actor::Property::COLOR_GREEN:
4311 value = GetCurrentColor().g;
4315 case Dali::Actor::Property::COLOR_BLUE:
4317 value = GetCurrentColor().b;
4321 case Dali::Actor::Property::COLOR_ALPHA:
4322 case Dali::DevelActor::Property::OPACITY:
4324 value = GetCurrentColor().a;
4328 case Dali::Actor::Property::WORLD_COLOR:
4330 value = GetCurrentWorldColor();
4334 case Dali::Actor::Property::WORLD_MATRIX:
4336 value = GetCurrentWorldMatrix();
4340 case Dali::Actor::Property::VISIBLE:
4342 value = IsVisible();
4348 // Must be an event-side only property
4357 void Actor::EnsureRelayoutData()
4359 // Assign relayout data.
4360 if( !mRelayoutData )
4362 mRelayoutData = new RelayoutData();
4366 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4368 // Check if actor is dependent on parent
4369 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4371 if( ( dimension & ( 1 << i ) ) )
4373 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4374 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4384 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4386 // Check if actor is dependent on children
4387 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4389 if( ( dimension & ( 1 << i ) ) )
4391 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4392 switch( resizePolicy )
4394 case ResizePolicy::FIT_TO_CHILDREN:
4395 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4411 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4413 return Actor::RelayoutDependentOnChildren( dimension );
4416 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4418 // Check each possible dimension and see if it is dependent on the input one
4419 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4421 if( dimension & ( 1 << i ) )
4423 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4430 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4432 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4434 if( dimension & ( 1 << i ) )
4436 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4441 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4443 // If more than one dimension is requested, just return the first one found
4444 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4446 if( ( dimension & ( 1 << i ) ) )
4448 return mRelayoutData->negotiatedDimensions[ i ];
4452 return 0.0f; // Default
4455 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4457 EnsureRelayoutData();
4459 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4461 if( dimension & ( 1 << i ) )
4463 mRelayoutData->dimensionPadding[ i ] = padding;
4468 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4470 if ( mRelayoutData )
4472 // If more than one dimension is requested, just return the first one found
4473 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4475 if( ( dimension & ( 1 << i ) ) )
4477 return mRelayoutData->dimensionPadding[ i ];
4482 return GetDefaultDimensionPadding();
4485 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4487 EnsureRelayoutData();
4489 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4491 if( dimension & ( 1 << i ) )
4493 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4498 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4500 if ( mRelayoutData )
4502 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4504 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4514 float Actor::GetHeightForWidthBase( float width )
4516 float height = 0.0f;
4518 const Vector3 naturalSize = GetNaturalSize();
4519 if( naturalSize.width > 0.0f )
4521 height = naturalSize.height * width / naturalSize.width;
4523 else // we treat 0 as 1:1 aspect ratio
4531 float Actor::GetWidthForHeightBase( float height )
4535 const Vector3 naturalSize = GetNaturalSize();
4536 if( naturalSize.height > 0.0f )
4538 width = naturalSize.width * height / naturalSize.height;
4540 else // we treat 0 as 1:1 aspect ratio
4548 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4550 // Fill to parent, taking size mode factor into account
4551 switch( child.GetResizePolicy( dimension ) )
4553 case ResizePolicy::FILL_TO_PARENT:
4555 return GetLatestSize( dimension );
4558 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4560 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4563 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4565 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4570 return GetLatestSize( dimension );
4575 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4577 // Can be overridden in derived class
4578 return CalculateChildSizeBase( child, dimension );
4581 float Actor::GetHeightForWidth( float width )
4583 // Can be overridden in derived class
4584 return GetHeightForWidthBase( width );
4587 float Actor::GetWidthForHeight( float height )
4589 // Can be overridden in derived class
4590 return GetWidthForHeightBase( height );
4593 float Actor::GetLatestSize( Dimension::Type dimension ) const
4595 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4598 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4600 Vector2 padding = GetPadding( dimension );
4602 return GetLatestSize( dimension ) + padding.x + padding.y;
4605 float Actor::NegotiateFromParent( Dimension::Type dimension )
4607 Actor* parent = GetParent();
4610 Vector2 padding( GetPadding( dimension ) );
4611 Vector2 parentPadding( parent->GetPadding( dimension ) );
4612 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4618 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4620 float maxDimensionPoint = 0.0f;
4622 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4624 ActorPtr child = GetChildAt( i );
4626 if( !child->RelayoutDependentOnParent( dimension ) )
4628 // Calculate the min and max points that the children range across
4629 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4630 float dimensionSize = child->GetRelayoutSize( dimension );
4631 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4635 return maxDimensionPoint;
4638 float Actor::GetSize( Dimension::Type dimension ) const
4640 return GetDimensionValue( mTargetSize, dimension );
4643 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4645 return GetDimensionValue( GetNaturalSize(), dimension );
4648 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4650 switch( GetResizePolicy( dimension ) )
4652 case ResizePolicy::USE_NATURAL_SIZE:
4654 return GetNaturalSize( dimension );
4657 case ResizePolicy::FIXED:
4659 return GetDimensionValue( GetPreferredSize(), dimension );
4662 case ResizePolicy::USE_ASSIGNED_SIZE:
4664 return GetDimensionValue( maximumSize, dimension );
4667 case ResizePolicy::FILL_TO_PARENT:
4668 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4669 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4671 return NegotiateFromParent( dimension );
4674 case ResizePolicy::FIT_TO_CHILDREN:
4676 return NegotiateFromChildren( dimension );
4679 case ResizePolicy::DIMENSION_DEPENDENCY:
4681 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4684 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4686 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4689 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4691 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4703 return 0.0f; // Default
4706 float Actor::ClampDimension( float size, Dimension::Type dimension )
4708 const float minSize = GetMinimumSize( dimension );
4709 const float maxSize = GetMaximumSize( dimension );
4711 return std::max( minSize, std::min( size, maxSize ) );
4714 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4716 // Check if it needs to be negotiated
4717 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4719 // Check that we havn't gotten into an infinite loop
4720 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4721 bool recursionFound = false;
4722 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4724 if( *it == searchActor )
4726 recursionFound = true;
4731 if( !recursionFound )
4733 // Record the path that we have taken
4734 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4736 // Dimension dependency check
4737 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4739 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4741 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4743 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4747 // Parent dependency check
4748 Actor* parent = GetParent();
4749 if( parent && RelayoutDependentOnParent( dimension ) )
4751 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4754 // Children dependency check
4755 if( RelayoutDependentOnChildren( dimension ) )
4757 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4759 ActorPtr child = GetChildAt( i );
4761 // Only relayout child first if it is not dependent on this actor
4762 if( !child->RelayoutDependentOnParent( dimension ) )
4764 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4769 // For deriving classes
4770 OnCalculateRelayoutSize( dimension );
4772 // All dependencies checked, calculate the size and set negotiated flag
4773 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4775 SetNegotiatedDimension( newSize, dimension );
4776 SetLayoutNegotiated( true, dimension );
4778 // For deriving classes
4779 OnLayoutNegotiated( newSize, dimension );
4781 // This actor has been successfully processed, pop it off the recursion stack
4782 recursionStack.pop_back();
4786 // TODO: Break infinite loop
4787 SetLayoutNegotiated( true, dimension );
4792 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4794 // Negotiate all dimensions that require it
4795 ActorDimensionStack recursionStack;
4797 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4799 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4802 NegotiateDimension( dimension, allocatedSize, recursionStack );
4806 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4808 switch( mRelayoutData->sizeSetPolicy )
4810 case SizeScalePolicy::USE_SIZE_SET:
4815 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4817 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4818 const Vector3 naturalSize = GetNaturalSize();
4819 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4821 const float sizeRatio = size.width / size.height;
4822 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4824 if( naturalSizeRatio < sizeRatio )
4826 return Vector2( naturalSizeRatio * size.height, size.height );
4828 else if( naturalSizeRatio > sizeRatio )
4830 return Vector2( size.width, size.width / naturalSizeRatio );
4841 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4843 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4844 const Vector3 naturalSize = GetNaturalSize();
4845 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4847 const float sizeRatio = size.width / size.height;
4848 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4850 if( naturalSizeRatio < sizeRatio )
4852 return Vector2( size.width, size.width / naturalSizeRatio );
4854 else if( naturalSizeRatio > sizeRatio )
4856 return Vector2( naturalSizeRatio * size.height, size.height );
4875 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4877 // Do the set actor size
4878 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4880 // Adjust for size set policy
4881 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4883 // Lock the flag to stop recursive relayouts on set size
4884 mRelayoutData->insideRelayout = true;
4885 SetSize( negotiatedSize );
4886 mRelayoutData->insideRelayout = false;
4888 // Clear flags for all dimensions
4889 SetLayoutDirty( false );
4891 // Give deriving classes a chance to respond
4892 OnRelayout( negotiatedSize, container );
4894 if( !mOnRelayoutSignal.Empty() )
4896 Dali::Actor handle( this );
4897 mOnRelayoutSignal.Emit( handle );
4901 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4903 // Force a size negotiation for actors that has assigned size during relayout
4904 // This is required as otherwise the flags that force a relayout will not
4905 // necessarilly be set. This will occur if the actor has already been laid out.
4906 // The dirty flags are then cleared. Then if the actor is added back into the
4907 // relayout container afterwards, the dirty flags would still be clear...
4908 // causing a relayout to be skipped. Here we force any actors added to the
4909 // container to be relayed out.
4910 DALI_LOG_TIMER_START( NegSizeTimer1 );
4912 if( GetUseAssignedSize(Dimension::WIDTH ) )
4914 SetLayoutNegotiated( false, Dimension::WIDTH );
4916 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4918 SetLayoutNegotiated( false, Dimension::HEIGHT );
4921 // Do the negotiation
4922 NegotiateDimensions( allocatedSize );
4924 // Set the actor size
4925 SetNegotiatedSize( container );
4927 // Negotiate down to children
4928 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4930 ActorPtr child = GetChildAt( i );
4932 // Forces children that have already been laid out to be relayed out
4933 // if they have assigned size during relayout.
4934 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4936 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4937 child->SetLayoutDirty(true, Dimension::WIDTH);
4940 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4942 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4943 child->SetLayoutDirty(true, Dimension::HEIGHT);
4946 // Only relayout if required
4947 if( child->RelayoutRequired() )
4949 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4952 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4955 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4959 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4961 if( dimension & ( 1 << i ) )
4963 mRelayoutData->useAssignedSize[ i ] = use;
4969 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4971 if ( mRelayoutData )
4973 // If more than one dimension is requested, just return the first one found
4974 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4976 if( dimension & ( 1 << i ) )
4978 return mRelayoutData->useAssignedSize[ i ];
4986 void Actor::RelayoutRequest( Dimension::Type dimension )
4988 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4989 if( relayoutController )
4991 Dali::Actor self( this );
4992 relayoutController->RequestRelayout( self, dimension );
4996 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
5000 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
5004 void Actor::SetPreferredSize( const Vector2& size )
5006 EnsureRelayoutData();
5008 if( size.width > 0.0f )
5010 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
5013 if( size.height > 0.0f )
5015 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
5018 mRelayoutData->preferredSize = size;
5023 Vector2 Actor::GetPreferredSize() const
5025 if ( mRelayoutData )
5027 return Vector2( mRelayoutData->preferredSize );
5030 return GetDefaultPreferredSize();
5033 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
5035 EnsureRelayoutData();
5037 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5039 if( dimension & ( 1 << i ) )
5041 mRelayoutData->minimumSize[ i ] = size;
5048 float Actor::GetMinimumSize( Dimension::Type dimension ) const
5050 if ( mRelayoutData )
5052 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5054 if( dimension & ( 1 << i ) )
5056 return mRelayoutData->minimumSize[ i ];
5061 return 0.0f; // Default
5064 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5066 EnsureRelayoutData();
5068 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5070 if( dimension & ( 1 << i ) )
5072 mRelayoutData->maximumSize[ i ] = size;
5079 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5081 if ( mRelayoutData )
5083 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5085 if( dimension & ( 1 << i ) )
5087 return mRelayoutData->maximumSize[ i ];
5092 return FLT_MAX; // Default
5095 Object* Actor::GetParentObject() const
5100 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5102 if( mVisible != visible )
5104 if( sendMessage == SendMessage::TRUE && NULL != mNode )
5106 // mNode is being used in a separate thread; queue a message to set the value & base value
5107 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5112 // Emit the signal on this actor and all its children
5113 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5117 void Actor::SetSiblingOrder( unsigned int order )
5121 ActorContainer& siblings = *(mParent->mChildren);
5122 unsigned int currentOrder = GetSiblingOrder();
5124 if( order != currentOrder )
5130 else if( order < siblings.size() -1 )
5132 if( order > currentOrder )
5134 RaiseAbove( *siblings[order] );
5138 LowerBelow( *siblings[order] );
5149 unsigned int Actor::GetSiblingOrder() const
5151 unsigned int order = 0;
5155 ActorContainer& siblings = *(mParent->mChildren);
5156 for( size_t i=0; i<siblings.size(); ++i )
5158 if( siblings[i] == this )
5169 void Actor::RequestRebuildDepthTree()
5173 StagePtr stage = Stage::GetCurrent();
5176 stage->RequestRebuildDepthTree();
5185 ActorContainer& siblings = *(mParent->mChildren);
5186 if( siblings.back() != this ) // If not already at end
5188 for( size_t i=0; i<siblings.size(); ++i )
5190 if( siblings[i] == this )
5193 ActorPtr next = siblings[i+1];
5194 siblings[i+1] = this;
5200 RequestRebuildDepthTree();
5204 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5212 ActorContainer& siblings = *(mParent->mChildren);
5213 if( siblings.front() != this ) // If not already at beginning
5215 for( size_t i=0; i<siblings.size(); ++i )
5217 if( siblings[i] == this )
5219 // Swap with previous
5220 ActorPtr previous = siblings[i-1];
5221 siblings[i-1] = this;
5222 siblings[i] = previous;
5227 RequestRebuildDepthTree();
5231 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5235 void Actor::RaiseToTop()
5239 ActorContainer& siblings = *(mParent->mChildren);
5240 if( siblings.back() != this ) // If not already at end
5242 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5243 if( iter != siblings.end() )
5245 siblings.erase(iter);
5246 siblings.push_back(ActorPtr(this));
5249 RequestRebuildDepthTree();
5253 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5257 void Actor::LowerToBottom()
5261 ActorContainer& siblings = *(mParent->mChildren);
5262 if( siblings.front() != this ) // If not already at bottom,
5264 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5266 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5267 if( iter != siblings.end() )
5269 siblings.erase(iter);
5270 siblings.insert(siblings.begin(), thisPtr);
5273 RequestRebuildDepthTree();
5277 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5281 void Actor::RaiseAbove( Internal::Actor& target )
5285 ActorContainer& siblings = *(mParent->mChildren);
5286 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5288 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5290 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5291 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5292 if( thisIter < targetIter )
5294 siblings.erase(thisIter);
5295 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5296 // invalidate thisIter)
5297 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5299 siblings.insert(targetIter, thisPtr);
5301 RequestRebuildDepthTree();
5306 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5310 void Actor::LowerBelow( Internal::Actor& target )
5314 ActorContainer& siblings = *(mParent->mChildren);
5315 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5317 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5319 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5320 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5322 if( thisIter > targetIter )
5324 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5325 siblings.insert(targetIter, thisPtr);
5327 RequestRebuildDepthTree();
5332 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5336 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::DevelActor::LayoutDirection::Type direction )
5338 if( actor && actor->mLayoutDirectionInheritance )
5340 if( actor->mLayoutDirection != direction)
5342 actor->mLayoutDirection = direction;
5343 actor->EmitLayoutDirectionChangedSignal( direction );
5344 actor->RelayoutRequest();
5347 if( actor->GetChildCount() > 0 )
5349 ActorContainer& children = actor->GetChildrenInternal();
5350 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5352 InheritLayoutDirectionRecursively( *iter, direction );
5359 } // namespace Internal