2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/common/animatable-property.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/nodes/node-declarations.h>
51 #include <dali/internal/update/animation/scene-graph-constraint.h>
52 #include <dali/internal/event/events/actor-gesture-data.h>
53 #include <dali/internal/common/message.h>
54 #include <dali/integration-api/debug.h>
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::PropertyBase;
60 #if defined(DEBUG_ENABLED)
61 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
62 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
71 unsigned int Actor::mActorCounter = 0;
75 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
76 inline const Vector3& GetDefaultSizeModeFactor()
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultPreferredSize()
87 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
88 inline const Vector2& GetDefaultDimensionPadding()
93 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
95 } // unnamed namespace
98 * Struct to collect relayout variables
100 struct Actor::RelayoutData
103 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
105 // Set size negotiation defaults
106 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
108 resizePolicies[ i ] = ResizePolicy::DEFAULT;
109 useAssignedSize[ i ] = false;
110 negotiatedDimensions[ i ] = 0.0f;
111 dimensionNegotiated[ i ] = false;
112 dimensionDirty[ i ] = false;
113 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
114 dimensionPadding[ i ] = GetDefaultDimensionPadding();
115 minimumSize[ i ] = 0.0f;
116 maximumSize[ i ] = FLT_MAX;
120 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
121 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
123 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
125 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
127 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
129 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
130 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
132 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
133 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
135 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
137 Vector2 preferredSize; ///< The preferred size of the actor
139 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
141 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
142 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
145 namespace // unnamed namespace
151 * We want to discourage the use of property strings (minimize string comparisons),
152 * particularly for the default properties.
153 * Name Type writable animatable constraint-input enum for index-checking
155 DALI_PROPERTY_TABLE_BEGIN
156 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
157 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
158 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
159 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
160 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
161 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
162 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
163 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
164 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
165 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
166 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
167 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
168 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
169 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
170 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
171 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
172 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
173 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
174 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
175 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
176 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
177 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
178 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
179 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
180 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
181 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
182 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
183 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
184 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
185 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
186 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
187 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
188 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
189 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
190 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
191 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
192 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
193 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
194 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
195 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
196 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
198 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
199 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
200 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
201 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
202 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
203 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
204 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
205 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
206 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
207 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
208 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
209 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
210 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
211 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
212 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
213 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
214 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
215 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
216 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
220 const char* const SIGNAL_TOUCHED = "touched";
221 const char* const SIGNAL_HOVERED = "hovered";
222 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
223 const char* const SIGNAL_ON_STAGE = "onStage";
224 const char* const SIGNAL_OFF_STAGE = "offStage";
225 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
226 const char* const SIGNAL_TOUCH = "touch";
230 const char* const ACTION_SHOW = "show";
231 const char* const ACTION_HIDE = "hide";
233 BaseHandle CreateActor()
235 return Dali::Actor::New();
238 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
240 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
241 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
242 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
243 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
244 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
245 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
248 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
249 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
254 const Vector3& value;
257 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
258 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
259 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
260 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
261 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
262 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
263 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
264 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
265 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
266 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
267 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
269 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
270 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
271 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
272 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
273 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
274 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
276 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
277 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
278 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
279 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
280 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
281 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
283 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
287 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
289 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
298 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
300 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
304 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
306 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
307 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
309 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
311 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
312 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
314 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
316 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
318 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
320 size_t sizeIgnored = 0;
321 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
323 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
330 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
332 // Values are the same so just use the same table as anchor-point
333 return GetAnchorPointConstant( value, parentOrigin );
337 * @brief Extract a given dimension from a Vector2
339 * @param[in] values The values to extract from
340 * @param[in] dimension The dimension to extract
341 * @return Return the value for the dimension
343 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
347 case Dimension::WIDTH:
351 case Dimension::HEIGHT:
353 return values.height;
364 * @brief Extract a given dimension from a Vector3
366 * @param[in] values The values to extract from
367 * @param[in] dimension The dimension to extract
368 * @return Return the value for the dimension
370 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
372 return GetDimensionValue( values.GetVectorXY(), dimension );
376 * @brief Recursively emits the visibility-changed-signal on the actor tree.
377 * @param[in] actor The actor to emit the signal on
378 * @param[in] visible The new visibility of the actor
379 * @param[in] type Whether the actor's visible property has changed or a parent's
381 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
385 actor->EmitVisibilityChangedSignal( visible, type );
387 if( actor->GetChildCount() > 0 )
389 ActorContainer& children = actor->GetChildrenInternal();
390 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
392 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
398 } // unnamed namespace
400 ActorPtr Actor::New()
402 ActorPtr actor( new Actor( BASIC ) );
404 // Second-phase construction
410 const std::string& Actor::GetName() const
415 void Actor::SetName( const std::string& name )
421 // ATTENTION: string for debug purposes is not thread safe.
422 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
426 unsigned int Actor::GetId() const
431 bool Actor::OnStage() const
436 Dali::Layer Actor::GetLayer()
440 // Short-circuit for Layer derived actors
443 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
446 // Find the immediate Layer parent
447 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
449 if( parent->IsLayer() )
451 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
458 void Actor::Add( Actor& child )
460 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
461 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
465 mChildren = new ActorContainer;
468 Actor* const oldParent( child.mParent );
470 // child might already be ours
471 if( this != oldParent )
473 // if we already have parent, unparent us first
476 oldParent->Remove( child ); // This causes OnChildRemove callback
478 // Old parent may need to readjust to missing child
479 if( oldParent->RelayoutDependentOnChildren() )
481 oldParent->RelayoutRequest();
485 // Guard against Add() during previous OnChildRemove callback
488 // Do this first, since user callbacks from within SetParent() may need to remove child
489 mChildren->push_back( ActorPtr( &child ) );
491 // SetParent asserts that child can be added
492 child.SetParent( this );
494 // Notification for derived classes
497 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
499 // Only put in a relayout request if there is a suitable dependency
500 if( RelayoutDependentOnChildren() )
508 void Actor::Remove( Actor& child )
510 if( (this == &child) || (!mChildren) )
512 // no children or removing itself
518 // Find the child in mChildren, and unparent it
519 ActorIter end = mChildren->end();
520 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
522 ActorPtr actor = (*iter);
524 if( actor.Get() == &child )
526 // Keep handle for OnChildRemove notification
529 // Do this first, since user callbacks from within SetParent() may need to add the child
530 mChildren->erase( iter );
532 DALI_ASSERT_DEBUG( actor->GetParent() == this );
533 actor->SetParent( NULL );
541 // Only put in a relayout request if there is a suitable dependency
542 if( RelayoutDependentOnChildren() )
548 // Notification for derived classes
549 OnChildRemove( child );
552 void Actor::Unparent()
556 // Remove this actor from the parent. The remove will put a relayout request in for
557 // the parent if required
558 mParent->Remove( *this );
559 // mParent is now NULL!
563 unsigned int Actor::GetChildCount() const
565 return ( NULL != mChildren ) ? mChildren->size() : 0;
568 ActorPtr Actor::GetChildAt( unsigned int index ) const
570 DALI_ASSERT_ALWAYS( index < GetChildCount() );
572 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
575 ActorPtr Actor::FindChildByName( const std::string& actorName )
578 if( actorName == mName )
584 ActorIter end = mChildren->end();
585 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
587 child = (*iter)->FindChildByName( actorName );
598 ActorPtr Actor::FindChildById( const unsigned int id )
607 ActorIter end = mChildren->end();
608 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
610 child = (*iter)->FindChildById( id );
621 void Actor::SetParentOrigin( const Vector3& origin )
625 // mNode is being used in a separate thread; queue a message to set the value & base value
626 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
629 // Cache for event-thread access
632 // not allocated, check if different from default
633 if( ParentOrigin::DEFAULT != origin )
635 mParentOrigin = new Vector3( origin );
640 // check if different from current costs more than just set
641 *mParentOrigin = origin;
645 void Actor::SetParentOriginX( float x )
647 const Vector3& current = GetCurrentParentOrigin();
649 SetParentOrigin( Vector3( x, current.y, current.z ) );
652 void Actor::SetParentOriginY( float y )
654 const Vector3& current = GetCurrentParentOrigin();
656 SetParentOrigin( Vector3( current.x, y, current.z ) );
659 void Actor::SetParentOriginZ( float z )
661 const Vector3& current = GetCurrentParentOrigin();
663 SetParentOrigin( Vector3( current.x, current.y, z ) );
666 const Vector3& Actor::GetCurrentParentOrigin() const
668 // Cached for event-thread access
669 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
672 void Actor::SetAnchorPoint( const Vector3& anchor )
676 // mNode is being used in a separate thread; queue a message to set the value & base value
677 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
680 // Cache for event-thread access
683 // not allocated, check if different from default
684 if( AnchorPoint::DEFAULT != anchor )
686 mAnchorPoint = new Vector3( anchor );
691 // check if different from current costs more than just set
692 *mAnchorPoint = anchor;
696 void Actor::SetAnchorPointX( float x )
698 const Vector3& current = GetCurrentAnchorPoint();
700 SetAnchorPoint( Vector3( x, current.y, current.z ) );
703 void Actor::SetAnchorPointY( float y )
705 const Vector3& current = GetCurrentAnchorPoint();
707 SetAnchorPoint( Vector3( current.x, y, current.z ) );
710 void Actor::SetAnchorPointZ( float z )
712 const Vector3& current = GetCurrentAnchorPoint();
714 SetAnchorPoint( Vector3( current.x, current.y, z ) );
717 const Vector3& Actor::GetCurrentAnchorPoint() const
719 // Cached for event-thread access
720 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
723 void Actor::SetPosition( float x, float y )
725 SetPosition( Vector3( x, y, 0.0f ) );
728 void Actor::SetPosition( float x, float y, float z )
730 SetPosition( Vector3( x, y, z ) );
733 void Actor::SetPosition( const Vector3& position )
735 mTargetPosition = position;
739 // mNode is being used in a separate thread; queue a message to set the value & base value
740 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
744 void Actor::SetX( float x )
746 mTargetPosition.x = x;
750 // mNode is being used in a separate thread; queue a message to set the value & base value
751 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
755 void Actor::SetY( float y )
757 mTargetPosition.y = y;
761 // mNode is being used in a separate thread; queue a message to set the value & base value
762 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
766 void Actor::SetZ( float z )
768 mTargetPosition.z = z;
772 // mNode is being used in a separate thread; queue a message to set the value & base value
773 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
777 void Actor::TranslateBy( const Vector3& distance )
779 mTargetPosition += distance;
783 // mNode is being used in a separate thread; queue a message to set the value & base value
784 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
788 const Vector3& Actor::GetCurrentPosition() const
792 // mNode is being used in a separate thread; copy the value from the previous update
793 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
796 return Vector3::ZERO;
799 const Vector3& Actor::GetTargetPosition() const
801 return mTargetPosition;
804 const Vector3& Actor::GetCurrentWorldPosition() const
808 // mNode is being used in a separate thread; copy the value from the previous update
809 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
812 return Vector3::ZERO;
815 const Vector2 Actor::GetCurrentScreenPosition() const
817 StagePtr stage = Stage::GetCurrent();
818 if( stage && OnStage() && NULL != mNode )
820 Vector3 worldPosition = mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
821 Vector3 cameraPosition = stage->GetDefaultCameraActor().mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
822 worldPosition -= cameraPosition;
824 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
825 Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
826 Vector3 halfActorSize( actorSize * 0.5f );
827 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
829 return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
830 halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
833 return Vector2::ZERO;
836 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
838 // this flag is not animatable so keep the value
839 mPositionInheritanceMode = mode;
842 // mNode is being used in a separate thread; queue a message to set the value
843 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
847 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
849 // Cached for event-thread access
850 return mPositionInheritanceMode;
853 void Actor::SetInheritPosition( bool inherit )
855 if( mInheritPosition != inherit && NULL != mNode )
857 // non animateable so keep local copy
858 mInheritPosition = inherit;
859 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
863 bool Actor::IsPositionInherited() const
865 return mInheritPosition;
868 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
870 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
871 normalizedAxis.Normalize();
873 Quaternion orientation( angle, normalizedAxis );
875 SetOrientation( orientation );
878 void Actor::SetOrientation( const Quaternion& orientation )
880 mTargetOrientation = orientation;
884 // mNode is being used in a separate thread; queue a message to set the value & base value
885 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
889 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
891 RotateBy( Quaternion(angle, axis) );
894 void Actor::RotateBy( const Quaternion& relativeRotation )
896 mTargetOrientation *= Quaternion( relativeRotation );
900 // mNode is being used in a separate thread; queue a message to set the value & base value
901 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
905 const Quaternion& Actor::GetCurrentOrientation() const
909 // mNode is being used in a separate thread; copy the value from the previous update
910 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
913 return Quaternion::IDENTITY;
916 const Quaternion& Actor::GetCurrentWorldOrientation() const
920 // mNode is being used in a separate thread; copy the value from the previous update
921 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
924 return Quaternion::IDENTITY;
927 void Actor::SetScale( float scale )
929 SetScale( Vector3( scale, scale, scale ) );
932 void Actor::SetScale( float x, float y, float z )
934 SetScale( Vector3( x, y, z ) );
937 void Actor::SetScale( const Vector3& scale )
939 mTargetScale = scale;
943 // mNode is being used in a separate thread; queue a message to set the value & base value
944 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
948 void Actor::SetScaleX( float x )
954 // mNode is being used in a separate thread; queue a message to set the value & base value
955 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
959 void Actor::SetScaleY( float y )
965 // mNode is being used in a separate thread; queue a message to set the value & base value
966 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
970 void Actor::SetScaleZ( float z )
976 // mNode is being used in a separate thread; queue a message to set the value & base value
977 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
981 void Actor::ScaleBy(const Vector3& relativeScale)
983 mTargetScale *= relativeScale;
987 // mNode is being used in a separate thread; queue a message to set the value & base value
988 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
992 const Vector3& Actor::GetCurrentScale() const
996 // mNode is being used in a separate thread; copy the value from the previous update
997 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
1000 return Vector3::ONE;
1003 const Vector3& Actor::GetCurrentWorldScale() const
1007 // mNode is being used in a separate thread; copy the value from the previous update
1008 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
1011 return Vector3::ONE;
1014 void Actor::SetInheritScale( bool inherit )
1017 if( mInheritScale != inherit && NULL != mNode )
1019 // non animateable so keep local copy
1020 mInheritScale = inherit;
1021 // mNode is being used in a separate thread; queue a message to set the value
1022 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
1026 bool Actor::IsScaleInherited() const
1028 return mInheritScale;
1031 Matrix Actor::GetCurrentWorldMatrix() const
1035 return mNode->GetWorldMatrix(0);
1038 return Matrix::IDENTITY;
1041 void Actor::SetVisible( bool visible )
1043 SetVisibleInternal( visible, SendMessage::TRUE );
1046 bool Actor::IsVisible() const
1050 // mNode is being used in a separate thread; copy the value from the previous update
1051 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1057 void Actor::SetOpacity( float opacity )
1059 mTargetColor.a = opacity;
1063 // mNode is being used in a separate thread; queue a message to set the value & base value
1064 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1068 float Actor::GetCurrentOpacity() const
1072 // mNode is being used in a separate thread; copy the value from the previous update
1073 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1079 ClippingMode::Type Actor::GetClippingMode() const
1081 return mClippingMode;
1084 unsigned int Actor::GetSortingDepth()
1086 return mSortedDepth;
1089 const Vector4& Actor::GetCurrentWorldColor() const
1093 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1096 return Color::WHITE;
1099 void Actor::SetColor( const Vector4& color )
1101 mTargetColor = color;
1105 // mNode is being used in a separate thread; queue a message to set the value & base value
1106 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1110 void Actor::SetColorRed( float red )
1112 mTargetColor.r = red;
1116 // mNode is being used in a separate thread; queue a message to set the value & base value
1117 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1121 void Actor::SetColorGreen( float green )
1123 mTargetColor.g = green;
1127 // mNode is being used in a separate thread; queue a message to set the value & base value
1128 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1132 void Actor::SetColorBlue( float blue )
1134 mTargetColor.b = blue;
1138 // mNode is being used in a separate thread; queue a message to set the value & base value
1139 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1143 const Vector4& Actor::GetCurrentColor() const
1147 // mNode is being used in a separate thread; copy the value from the previous update
1148 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1151 return Color::WHITE;
1154 void Actor::SetInheritOrientation( bool inherit )
1156 if( mInheritOrientation != inherit && NULL != mNode)
1158 // non animateable so keep local copy
1159 mInheritOrientation = inherit;
1160 // mNode is being used in a separate thread; queue a message to set the value
1161 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1165 bool Actor::IsOrientationInherited() const
1167 return mInheritOrientation;
1170 void Actor::SetSizeModeFactor( const Vector3& factor )
1172 EnsureRelayoutData();
1174 mRelayoutData->sizeModeFactor = factor;
1177 const Vector3& Actor::GetSizeModeFactor() const
1179 if ( mRelayoutData )
1181 return mRelayoutData->sizeModeFactor;
1184 return GetDefaultSizeModeFactor();
1187 void Actor::SetColorMode( ColorMode colorMode )
1189 // non animateable so keep local copy
1190 mColorMode = colorMode;
1193 // mNode is being used in a separate thread; queue a message to set the value
1194 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1198 ColorMode Actor::GetColorMode() const
1200 // we have cached copy
1204 void Actor::SetSize( float width, float height )
1206 SetSize( Vector2( width, height ) );
1209 void Actor::SetSize( float width, float height, float depth )
1211 SetSize( Vector3( width, height, depth ) );
1214 void Actor::SetSize( const Vector2& size )
1216 SetSize( Vector3( size.width, size.height, 0.f ) );
1219 void Actor::SetSizeInternal( const Vector2& size )
1221 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1224 void Actor::SetSize( const Vector3& size )
1226 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1228 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1229 SetPreferredSize( size.GetVectorXY() );
1233 SetSizeInternal( size );
1237 void Actor::SetSizeInternal( const Vector3& size )
1239 // dont allow recursive loop
1240 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1241 // 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
1242 if( ( NULL != mNode )&&
1243 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1244 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1245 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1249 // mNode is being used in a separate thread; queue a message to set the value & base value
1250 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1252 // Notification for derived classes
1253 mInsideOnSizeSet = true;
1254 OnSizeSet( mTargetSize );
1255 mInsideOnSizeSet = false;
1257 // Raise a relayout request if the flag is not locked
1258 if( mRelayoutData && !mRelayoutData->insideRelayout )
1265 void Actor::SetWidth( float width )
1267 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1269 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1270 mRelayoutData->preferredSize.width = width;
1274 mTargetSize.width = width;
1278 // mNode is being used in a separate thread; queue a message to set the value & base value
1279 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1286 void Actor::SetHeight( float height )
1288 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1290 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1291 mRelayoutData->preferredSize.height = height;
1295 mTargetSize.height = height;
1299 // mNode is being used in a separate thread; queue a message to set the value & base value
1300 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1307 void Actor::SetDepth( float depth )
1309 mTargetSize.depth = depth;
1313 // mNode is being used in a separate thread; queue a message to set the value & base value
1314 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1318 Vector3 Actor::GetTargetSize() const
1320 Vector3 size = mTargetSize;
1322 // Should return preferred size if size is fixed as set by SetSize
1323 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1325 size.width = GetPreferredSize().width;
1327 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1329 size.height = GetPreferredSize().height;
1335 const Vector3& Actor::GetCurrentSize() const
1339 // mNode is being used in a separate thread; copy the value from the previous update
1340 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1343 return Vector3::ZERO;
1346 Vector3 Actor::GetNaturalSize() const
1348 // It is up to deriving classes to return the appropriate natural size
1349 return Vector3( 0.0f, 0.0f, 0.0f );
1352 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1354 EnsureRelayoutData();
1356 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1357 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1359 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1361 if( dimension & ( 1 << i ) )
1363 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1365 mRelayoutData->useAssignedSize[ i ] = true;
1369 mRelayoutData->resizePolicies[ i ] = policy;
1370 mRelayoutData->useAssignedSize[ i ] = false;
1375 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1377 if( dimension & Dimension::WIDTH )
1379 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1382 if( dimension & Dimension::HEIGHT )
1384 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1388 // If calling SetResizePolicy, assume we want relayout enabled
1389 SetRelayoutEnabled( true );
1391 // If the resize policy is set to be FIXED, the preferred size
1392 // should be overrided by the target size. Otherwise the target
1393 // size should be overrided by the preferred size.
1395 if( dimension & Dimension::WIDTH )
1397 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1399 mRelayoutData->preferredSize.width = mTargetSize.width;
1401 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1403 mTargetSize.width = mRelayoutData->preferredSize.width;
1407 if( dimension & Dimension::HEIGHT )
1409 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1411 mRelayoutData->preferredSize.height = mTargetSize.height;
1413 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1415 mTargetSize.height = mRelayoutData->preferredSize.height;
1419 OnSetResizePolicy( policy, dimension );
1421 // Trigger relayout on this control
1425 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1427 if ( mRelayoutData )
1429 // If more than one dimension is requested, just return the first one found
1430 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1432 if( ( dimension & ( 1 << i ) ) )
1434 if( mRelayoutData->useAssignedSize[ i ] )
1436 return ResizePolicy::USE_ASSIGNED_SIZE;
1440 return mRelayoutData->resizePolicies[ i ];
1446 return ResizePolicy::DEFAULT;
1449 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1451 EnsureRelayoutData();
1453 mRelayoutData->sizeSetPolicy = policy;
1456 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1458 if ( mRelayoutData )
1460 return mRelayoutData->sizeSetPolicy;
1463 return DEFAULT_SIZE_SCALE_POLICY;
1466 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1468 EnsureRelayoutData();
1470 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1472 if( dimension & ( 1 << i ) )
1474 mRelayoutData->dimensionDependencies[ i ] = dependency;
1479 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1481 if ( mRelayoutData )
1483 // If more than one dimension is requested, just return the first one found
1484 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1486 if( ( dimension & ( 1 << i ) ) )
1488 return mRelayoutData->dimensionDependencies[ i ];
1493 return Dimension::ALL_DIMENSIONS; // Default
1496 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1498 // If relayout data has not been allocated yet and the client is requesting
1499 // to disable it, do nothing
1500 if( mRelayoutData || relayoutEnabled )
1502 EnsureRelayoutData();
1504 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1506 mRelayoutData->relayoutEnabled = relayoutEnabled;
1510 bool Actor::IsRelayoutEnabled() const
1512 // Assume that if relayout data has not been allocated yet then
1513 // relayout is disabled
1514 return mRelayoutData && mRelayoutData->relayoutEnabled;
1517 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1519 EnsureRelayoutData();
1521 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1523 if( dimension & ( 1 << i ) )
1525 mRelayoutData->dimensionDirty[ i ] = dirty;
1530 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1532 if ( mRelayoutData )
1534 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1536 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1546 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1548 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1551 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1553 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1556 unsigned int Actor::AddRenderer( Renderer& renderer )
1560 mRenderers = new RendererContainer;
1563 unsigned int index = mRenderers->size();
1564 RendererPtr rendererPtr = RendererPtr( &renderer );
1565 mRenderers->push_back( rendererPtr );
1566 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1570 unsigned int Actor::GetRendererCount() const
1572 unsigned int rendererCount(0);
1575 rendererCount = mRenderers->size();
1578 return rendererCount;
1581 RendererPtr Actor::GetRendererAt( unsigned int index )
1583 RendererPtr renderer;
1584 if( index < GetRendererCount() )
1586 renderer = ( *mRenderers )[ index ];
1592 void Actor::RemoveRenderer( Renderer& renderer )
1596 RendererIter end = mRenderers->end();
1597 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1599 if( (*iter).Get() == &renderer )
1601 mRenderers->erase( iter );
1602 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1609 void Actor::RemoveRenderer( unsigned int index )
1611 if( index < GetRendererCount() )
1613 RendererPtr renderer = ( *mRenderers )[ index ];
1614 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1615 mRenderers->erase( mRenderers->begin()+index );
1619 bool Actor::IsOverlay() const
1621 return ( DrawMode::OVERLAY_2D == mDrawMode );
1624 void Actor::SetDrawMode( DrawMode::Type drawMode )
1626 // this flag is not animatable so keep the value
1627 mDrawMode = drawMode;
1628 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1630 // mNode is being used in a separate thread; queue a message to set the value
1631 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1635 DrawMode::Type Actor::GetDrawMode() const
1640 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1642 // only valid when on-stage
1643 StagePtr stage = Stage::GetCurrent();
1644 if( stage && OnStage() )
1646 const RenderTaskList& taskList = stage->GetRenderTaskList();
1648 Vector2 converted( screenX, screenY );
1650 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1651 const int taskCount = taskList.GetTaskCount();
1652 for( int i = taskCount - 1; i >= 0; --i )
1654 Dali::RenderTask task = taskList.GetTask( i );
1655 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1657 // found a task where this conversion was ok so return
1665 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1667 bool retval = false;
1668 // only valid when on-stage
1671 CameraActor* camera = renderTask.GetCameraActor();
1675 renderTask.GetViewport( viewport );
1677 // need to translate coordinates to render tasks coordinate space
1678 Vector2 converted( screenX, screenY );
1679 if( renderTask.TranslateCoordinates( converted ) )
1681 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1688 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1690 // Early-out if mNode is NULL
1696 // Get the ModelView matrix
1698 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1700 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1701 Matrix invertedMvp( false/*don't init*/);
1702 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1703 bool success = invertedMvp.Invert();
1705 // Convert to GL coordinates
1706 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1711 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1718 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1724 if( XyPlaneIntersect( nearPos, farPos, local ) )
1726 Vector3 size = GetCurrentSize();
1727 localX = local.x + size.x * 0.5f;
1728 localY = local.y + size.y * 0.5f;
1739 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1742 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1744 Mathematical Formulation
1746 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1748 ( p - c ) dot ( p - c ) = r^2
1750 Given a ray with a point of origin 'o', and a direction vector 'd':
1752 ray(t) = o + td, t >= 0
1754 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1756 (o + td - c ) dot ( o + td - c ) = r^2
1758 To solve for t we first expand the above into a more recognisable quadratic equation form
1760 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1769 B = 2( o - c ) dot d
1770 C = ( o - c ) dot ( o - c ) - r^2
1772 which can be solved using a standard quadratic formula.
1774 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1776 Practical Simplification
1778 In a renderer, we often differentiate between world space and object space. In the object space
1779 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1780 into object space, the mathematical solution presented above can be simplified significantly.
1782 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1786 and we can find the t at which the (transformed) ray intersects the sphere by
1788 ( o + td ) dot ( o + td ) = r^2
1790 According to the reasoning above, we expand the above quadratic equation into the general form
1794 which now has coefficients:
1801 // Early out if mNode is NULL
1807 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1809 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1810 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1811 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1813 // Compute the radius is not needed, square radius it's enough.
1814 const Vector3& size( mNode->GetSize( bufferIndex ) );
1816 // Scale the sphere.
1817 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1819 const float width = size.width * scale.width;
1820 const float height = size.height * scale.height;
1822 float squareSphereRadius = 0.5f * ( width * width + height * height );
1824 float a = rayDir.Dot( rayDir ); // a
1825 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1826 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1828 return ( b2 * b2 - a * c ) >= 0.f;
1831 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1835 if( OnStage() && NULL != mNode )
1837 // Transforms the ray to the local reference system.
1838 // Calculate the inverse of Model matrix
1839 Matrix invModelMatrix( false/*don't init*/);
1841 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1842 invModelMatrix = mNode->GetWorldMatrix(0);
1843 invModelMatrix.Invert();
1845 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1846 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1848 // Test with the actor's XY plane (Normal = 0 0 1 1).
1850 float a = -rayOriginLocal.z;
1851 float b = rayDirLocal.z;
1853 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1855 // Ray travels distance * rayDirLocal to intersect with plane.
1858 const Vector3& size = mNode->GetSize( bufferIndex );
1860 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1861 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1863 // Test with the actor's geometry.
1864 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1871 void Actor::SetLeaveRequired( bool required )
1873 mLeaveRequired = required;
1876 bool Actor::GetLeaveRequired() const
1878 return mLeaveRequired;
1881 void Actor::SetKeyboardFocusable( bool focusable )
1883 mKeyboardFocusable = focusable;
1886 bool Actor::IsKeyboardFocusable() const
1888 return mKeyboardFocusable;
1891 bool Actor::GetTouchRequired() const
1893 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1896 bool Actor::GetHoverRequired() const
1898 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1901 bool Actor::GetWheelEventRequired() const
1903 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1906 bool Actor::IsHittable() const
1908 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1911 ActorGestureData& Actor::GetGestureData()
1913 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1914 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1915 if( NULL == mGestureData )
1917 mGestureData = new ActorGestureData;
1919 return *mGestureData;
1922 bool Actor::IsGestureRequred( Gesture::Type type ) const
1924 return mGestureData && mGestureData->IsGestureRequred( type );
1927 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1929 bool consumed = false;
1931 if( !mTouchSignal.Empty() )
1933 Dali::Actor handle( this );
1934 consumed = mTouchSignal.Emit( handle, touch );
1937 if( !mTouchedSignal.Empty() )
1939 Dali::Actor handle( this );
1940 consumed |= mTouchedSignal.Emit( handle, event );
1945 // Notification for derived classes
1946 consumed = OnTouchEvent( event ); // TODO
1952 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1954 bool consumed = false;
1956 if( !mHoveredSignal.Empty() )
1958 Dali::Actor handle( this );
1959 consumed = mHoveredSignal.Emit( handle, event );
1964 // Notification for derived classes
1965 consumed = OnHoverEvent( event );
1971 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1973 bool consumed = false;
1975 if( !mWheelEventSignal.Empty() )
1977 Dali::Actor handle( this );
1978 consumed = mWheelEventSignal.Emit( handle, event );
1983 // Notification for derived classes
1984 consumed = OnWheelEvent( event );
1990 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1992 if( ! mVisibilityChangedSignal.Empty() )
1994 Dali::Actor handle( this );
1995 mVisibilityChangedSignal.Emit( handle, visible, type );
1999 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
2001 if( ! mLayoutDirectionChangedSignal.Empty() )
2003 Dali::Actor handle( this );
2004 mLayoutDirectionChangedSignal.Emit( handle, type );
2008 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
2010 return mTouchedSignal;
2013 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
2015 return mTouchSignal;
2018 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2020 return mHoveredSignal;
2023 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
2025 return mWheelEventSignal;
2028 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2030 return mOnStageSignal;
2033 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2035 return mOffStageSignal;
2038 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2040 return mOnRelayoutSignal;
2043 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
2045 return mVisibilityChangedSignal;
2048 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
2050 return mLayoutDirectionChangedSignal;
2053 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2055 bool connected( true );
2056 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2058 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2060 actor->TouchedSignal().Connect( tracker, functor );
2062 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2064 actor->HoveredSignal().Connect( tracker, functor );
2066 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2068 actor->WheelEventSignal().Connect( tracker, functor );
2070 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2072 actor->OnStageSignal().Connect( tracker, functor );
2074 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2076 actor->OffStageSignal().Connect( tracker, functor );
2078 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2080 actor->OnRelayoutSignal().Connect( tracker, functor );
2082 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2084 actor->TouchSignal().Connect( tracker, functor );
2088 // signalName does not match any signal
2095 Actor::Actor( DerivedType derivedType )
2100 mParentOrigin( NULL ),
2101 mAnchorPoint( NULL ),
2102 mRelayoutData( NULL ),
2103 mGestureData( NULL ),
2104 mTargetOrientation( Quaternion::IDENTITY ),
2105 mTargetColor( Color::WHITE ),
2106 mTargetSize( Vector3::ZERO ),
2107 mTargetPosition( Vector3::ZERO ),
2108 mTargetScale( Vector3::ONE ),
2110 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2113 mIsRoot( ROOT_LAYER == derivedType ),
2114 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2115 mIsOnStage( false ),
2117 mLeaveRequired( false ),
2118 mKeyboardFocusable( false ),
2119 mDerivedRequiresTouch( false ),
2120 mDerivedRequiresHover( false ),
2121 mDerivedRequiresWheelEvent( false ),
2122 mOnStageSignalled( false ),
2123 mInsideOnSizeSet( false ),
2124 mInheritPosition( true ),
2125 mInheritOrientation( true ),
2126 mInheritScale( true ),
2127 mPositionUsesAnchorPoint( true ),
2129 mInheritLayoutDirection( true ),
2130 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2131 mDrawMode( DrawMode::NORMAL ),
2132 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2133 mColorMode( Node::DEFAULT_COLOR_MODE ),
2134 mClippingMode( ClippingMode::DISABLED )
2138 void Actor::Initialize()
2140 // Node creation, keep raw-pointer to Node for messaging
2141 mNode = CreateNode();
2142 OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
2143 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
2147 GetEventThreadServices().RegisterObject( this );
2152 // Remove mParent pointers from children even if we're destroying core,
2153 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2156 ActorConstIter endIter = mChildren->end();
2157 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2159 (*iter)->SetParent( NULL );
2165 // Guard to allow handle destruction after Core has been destroyed
2166 if( EventThreadServices::IsCoreRunning() )
2170 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2171 mNode = NULL; // Node is about to be destroyed
2174 GetEventThreadServices().UnregisterObject( this );
2177 // Cleanup optional gesture data
2178 delete mGestureData;
2180 // Cleanup optional parent origin and anchor
2181 delete mParentOrigin;
2182 delete mAnchorPoint;
2184 // Delete optional relayout data
2187 delete mRelayoutData;
2191 void Actor::ConnectToStage( unsigned int parentDepth )
2193 // This container is used instead of walking the Actor hierarchy.
2194 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2195 ActorContainer connectionList;
2197 StagePtr stage = Stage::GetCurrent();
2200 stage->RequestRebuildDepthTree();
2203 // This stage is atomic i.e. not interrupted by user callbacks.
2204 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2206 // Notify applications about the newly connected actors.
2207 const ActorIter endIter = connectionList.end();
2208 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2210 (*iter)->NotifyStageConnection();
2216 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2218 DALI_ASSERT_ALWAYS( !OnStage() );
2223 ConnectToSceneGraph();
2225 // Notification for internal derived classes
2226 OnStageConnectionInternal();
2228 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2229 connectionList.push_back( ActorPtr( this ) );
2231 // Recursively connect children
2234 ActorConstIter endIter = mChildren->end();
2235 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2237 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2243 * This method is called when the Actor is connected to the Stage.
2244 * The parent must have added its Node to the scene-graph.
2245 * The child must connect its Node to the parent's Node.
2246 * This is recursive; the child calls ConnectToStage() for its children.
2248 void Actor::ConnectToSceneGraph()
2250 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2254 // Reparent Node in next Update
2255 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2258 // Request relayout on all actors that are added to the scenegraph
2261 // Notification for Object::Observers
2265 void Actor::NotifyStageConnection()
2267 // Actors can be removed (in a callback), before the on-stage stage is reported.
2268 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2269 if( OnStage() && !mOnStageSignalled )
2271 // Notification for external (CustomActor) derived classes
2272 OnStageConnectionExternal( mDepth );
2274 if( !mOnStageSignal.Empty() )
2276 Dali::Actor handle( this );
2277 mOnStageSignal.Emit( handle );
2280 // Guard against Remove during callbacks
2283 mOnStageSignalled = true; // signal required next time Actor is removed
2288 void Actor::DisconnectFromStage()
2290 // This container is used instead of walking the Actor hierachy.
2291 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2292 ActorContainer disconnectionList;
2294 StagePtr stage = Stage::GetCurrent();
2297 stage->RequestRebuildDepthTree();
2300 // This stage is atomic i.e. not interrupted by user callbacks
2301 RecursiveDisconnectFromStage( disconnectionList );
2303 // Notify applications about the newly disconnected actors.
2304 const ActorIter endIter = disconnectionList.end();
2305 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2307 (*iter)->NotifyStageDisconnection();
2311 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2313 DALI_ASSERT_ALWAYS( OnStage() );
2315 // Recursively disconnect children
2318 ActorConstIter endIter = mChildren->end();
2319 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2321 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2325 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2326 disconnectionList.push_back( ActorPtr( this ) );
2328 // Notification for internal derived classes
2329 OnStageDisconnectionInternal();
2331 DisconnectFromSceneGraph();
2337 * This method is called by an actor or its parent, before a node removal message is sent.
2338 * This is recursive; the child calls DisconnectFromStage() for its children.
2340 void Actor::DisconnectFromSceneGraph()
2342 // Notification for Object::Observers
2343 OnSceneObjectRemove();
2346 void Actor::NotifyStageDisconnection()
2348 // Actors can be added (in a callback), before the off-stage state is reported.
2349 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2350 // only do this step if there is a stage, i.e. Core is not being shut down
2351 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2353 // Notification for external (CustomeActor) derived classes
2354 OnStageDisconnectionExternal();
2356 if( !mOffStageSignal.Empty() )
2358 Dali::Actor handle( this );
2359 mOffStageSignal.Emit( handle );
2362 // Guard against Add during callbacks
2365 mOnStageSignalled = false; // signal required next time Actor is added
2370 bool Actor::IsNodeConnected() const
2372 bool connected( false );
2374 if( OnStage() && ( NULL != mNode ) )
2376 if( IsRoot() || mNode->GetParent() )
2385 // This method initiates traversal of the actor tree using depth-first
2386 // traversal to set a depth index based on traversal order. It sends a
2387 // single message to update manager to update all the actor's nodes in
2388 // this tree with the depth index. The sceneGraphNodeDepths vector's
2389 // elements are ordered by depth, and could be used to reduce sorting
2390 // in the update thread.
2391 void Actor::RebuildDepthTree()
2393 DALI_LOG_TIMER_START(depthTimer);
2395 // Vector of scene-graph nodes and their depths to send to UpdateManager
2396 // in a single message
2397 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2400 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2402 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2403 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2406 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
2408 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2409 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
2411 // Create/add to children of this node
2414 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2416 Actor* childActor = (*it).Get();
2418 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2423 unsigned int Actor::GetDefaultPropertyCount() const
2425 return DEFAULT_PROPERTY_COUNT;
2428 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2430 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2432 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2434 indices.PushBack( i );
2438 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2440 if( index < DEFAULT_PROPERTY_COUNT )
2442 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2448 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2450 Property::Index index = Property::INVALID_INDEX;
2452 // Look for name in default properties
2453 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2455 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2456 if( 0 == name.compare( property->name ) )
2466 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2468 if( index < DEFAULT_PROPERTY_COUNT )
2470 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2476 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2478 if( index < DEFAULT_PROPERTY_COUNT )
2480 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2486 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2488 if( index < DEFAULT_PROPERTY_COUNT )
2490 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2496 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2498 if( index < DEFAULT_PROPERTY_COUNT )
2500 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2503 // index out of range...return Property::NONE
2504 return Property::NONE;
2507 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2511 case Dali::Actor::Property::PARENT_ORIGIN:
2513 Property::Type type = property.GetType();
2514 if( type == Property::VECTOR3 )
2516 SetParentOrigin( property.Get< Vector3 >() );
2518 else if ( type == Property::STRING )
2520 std::string parentOriginString;
2521 property.Get( parentOriginString );
2522 Vector3 parentOrigin;
2523 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2525 SetParentOrigin( parentOrigin );
2531 case Dali::Actor::Property::PARENT_ORIGIN_X:
2533 SetParentOriginX( property.Get< float >() );
2537 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2539 SetParentOriginY( property.Get< float >() );
2543 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2545 SetParentOriginZ( property.Get< float >() );
2549 case Dali::Actor::Property::ANCHOR_POINT:
2551 Property::Type type = property.GetType();
2552 if( type == Property::VECTOR3 )
2554 SetAnchorPoint( property.Get< Vector3 >() );
2556 else if ( type == Property::STRING )
2558 std::string anchorPointString;
2559 property.Get( anchorPointString );
2561 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2563 SetAnchorPoint( anchor );
2569 case Dali::Actor::Property::ANCHOR_POINT_X:
2571 SetAnchorPointX( property.Get< float >() );
2575 case Dali::Actor::Property::ANCHOR_POINT_Y:
2577 SetAnchorPointY( property.Get< float >() );
2581 case Dali::Actor::Property::ANCHOR_POINT_Z:
2583 SetAnchorPointZ( property.Get< float >() );
2587 case Dali::Actor::Property::SIZE:
2589 SetSize( property.Get< Vector3 >() );
2593 case Dali::Actor::Property::SIZE_WIDTH:
2595 SetWidth( property.Get< float >() );
2599 case Dali::Actor::Property::SIZE_HEIGHT:
2601 SetHeight( property.Get< float >() );
2605 case Dali::Actor::Property::SIZE_DEPTH:
2607 SetDepth( property.Get< float >() );
2611 case Dali::Actor::Property::POSITION:
2613 SetPosition( property.Get< Vector3 >() );
2617 case Dali::Actor::Property::POSITION_X:
2619 SetX( property.Get< float >() );
2623 case Dali::Actor::Property::POSITION_Y:
2625 SetY( property.Get< float >() );
2629 case Dali::Actor::Property::POSITION_Z:
2631 SetZ( property.Get< float >() );
2635 case Dali::Actor::Property::ORIENTATION:
2637 SetOrientation( property.Get< Quaternion >() );
2641 case Dali::Actor::Property::SCALE:
2643 SetScale( property.Get< Vector3 >() );
2647 case Dali::Actor::Property::SCALE_X:
2649 SetScaleX( property.Get< float >() );
2653 case Dali::Actor::Property::SCALE_Y:
2655 SetScaleY( property.Get< float >() );
2659 case Dali::Actor::Property::SCALE_Z:
2661 SetScaleZ( property.Get< float >() );
2665 case Dali::Actor::Property::VISIBLE:
2667 SetVisible( property.Get< bool >() );
2671 case Dali::Actor::Property::COLOR:
2673 SetColor( property.Get< Vector4 >() );
2677 case Dali::Actor::Property::COLOR_RED:
2679 SetColorRed( property.Get< float >() );
2683 case Dali::Actor::Property::COLOR_GREEN:
2685 SetColorGreen( property.Get< float >() );
2689 case Dali::Actor::Property::COLOR_BLUE:
2691 SetColorBlue( property.Get< float >() );
2695 case Dali::Actor::Property::COLOR_ALPHA:
2696 case Dali::DevelActor::Property::OPACITY:
2699 if( property.Get( value ) )
2701 SetOpacity( value );
2706 case Dali::Actor::Property::NAME:
2708 SetName( property.Get< std::string >() );
2712 case Dali::Actor::Property::SENSITIVE:
2714 SetSensitive( property.Get< bool >() );
2718 case Dali::Actor::Property::LEAVE_REQUIRED:
2720 SetLeaveRequired( property.Get< bool >() );
2724 case Dali::Actor::Property::INHERIT_POSITION:
2726 SetInheritPosition( property.Get< bool >() );
2730 case Dali::Actor::Property::INHERIT_ORIENTATION:
2732 SetInheritOrientation( property.Get< bool >() );
2736 case Dali::Actor::Property::INHERIT_SCALE:
2738 SetInheritScale( property.Get< bool >() );
2742 case Dali::Actor::Property::COLOR_MODE:
2744 ColorMode mode = mColorMode;
2745 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2747 SetColorMode( mode );
2752 case Dali::Actor::Property::POSITION_INHERITANCE:
2754 PositionInheritanceMode mode = mPositionInheritanceMode;
2755 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2757 SetPositionInheritanceMode( mode );
2762 case Dali::Actor::Property::DRAW_MODE:
2764 DrawMode::Type mode = mDrawMode;
2765 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2767 SetDrawMode( mode );
2772 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2774 SetSizeModeFactor( property.Get< Vector3 >() );
2778 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2780 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2781 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2783 SetResizePolicy( type, Dimension::WIDTH );
2788 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2790 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2791 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2793 SetResizePolicy( type, Dimension::HEIGHT );
2798 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2800 SizeScalePolicy::Type type;
2801 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2803 SetSizeScalePolicy( type );
2808 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2810 if( property.Get< bool >() )
2812 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2817 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2819 if( property.Get< bool >() )
2821 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2826 case Dali::Actor::Property::PADDING:
2828 Vector4 padding = property.Get< Vector4 >();
2829 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2830 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2834 case Dali::Actor::Property::MINIMUM_SIZE:
2836 Vector2 size = property.Get< Vector2 >();
2837 SetMinimumSize( size.x, Dimension::WIDTH );
2838 SetMinimumSize( size.y, Dimension::HEIGHT );
2842 case Dali::Actor::Property::MAXIMUM_SIZE:
2844 Vector2 size = property.Get< Vector2 >();
2845 SetMaximumSize( size.x, Dimension::WIDTH );
2846 SetMaximumSize( size.y, Dimension::HEIGHT );
2850 case Dali::DevelActor::Property::SIBLING_ORDER:
2854 if( property.Get( value ) )
2856 SetSiblingOrder( value );
2861 case Dali::Actor::Property::CLIPPING_MODE:
2863 ClippingMode::Type convertedValue = mClippingMode;
2864 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2866 mClippingMode = convertedValue;
2869 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2875 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2878 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2880 mPositionUsesAnchorPoint = value;
2883 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2889 case Dali::Actor::Property::LAYOUT_DIRECTION:
2891 Dali::LayoutDirection::Type direction = mLayoutDirection;
2892 mInheritLayoutDirection = false;
2894 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2896 InheritLayoutDirectionRecursively( this, direction, true );
2901 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2904 if( property.Get( value ) )
2906 SetInheritLayoutDirection( value );
2913 // this can happen in the case of a non-animatable default property so just do nothing
2919 // TODO: This method needs to be removed
2920 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2922 switch( entry.GetType() )
2924 case Property::BOOLEAN:
2926 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2927 DALI_ASSERT_DEBUG( NULL != property );
2929 // property is being used in a separate thread; queue a message to set the property
2930 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2935 case Property::INTEGER:
2937 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2938 DALI_ASSERT_DEBUG( NULL != property );
2940 // property is being used in a separate thread; queue a message to set the property
2941 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2946 case Property::FLOAT:
2948 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2949 DALI_ASSERT_DEBUG( NULL != property );
2951 // property is being used in a separate thread; queue a message to set the property
2952 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2957 case Property::VECTOR2:
2959 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2960 DALI_ASSERT_DEBUG( NULL != property );
2962 // property is being used in a separate thread; queue a message to set the property
2963 if(entry.componentIndex == 0)
2965 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2967 else if(entry.componentIndex == 1)
2969 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2973 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2979 case Property::VECTOR3:
2981 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2982 DALI_ASSERT_DEBUG( NULL != property );
2984 // property is being used in a separate thread; queue a message to set the property
2985 if(entry.componentIndex == 0)
2987 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2989 else if(entry.componentIndex == 1)
2991 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2993 else if(entry.componentIndex == 2)
2995 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2999 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
3005 case Property::VECTOR4:
3007 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
3008 DALI_ASSERT_DEBUG( NULL != property );
3010 // property is being used in a separate thread; queue a message to set the property
3011 if(entry.componentIndex == 0)
3013 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3015 else if(entry.componentIndex == 1)
3017 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3019 else if(entry.componentIndex == 2)
3021 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3023 else if(entry.componentIndex == 3)
3025 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3029 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3035 case Property::ROTATION:
3037 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3038 DALI_ASSERT_DEBUG( NULL != property );
3040 // property is being used in a separate thread; queue a message to set the property
3041 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
3046 case Property::MATRIX:
3048 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3049 DALI_ASSERT_DEBUG( NULL != property );
3051 // property is being used in a separate thread; queue a message to set the property
3052 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
3057 case Property::MATRIX3:
3059 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3060 DALI_ASSERT_DEBUG( NULL != property );
3062 // property is being used in a separate thread; queue a message to set the property
3063 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
3070 // nothing to do for other types
3075 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3077 Property::Value value;
3079 if( ! GetCachedPropertyValue( index, value ) )
3081 // If property value is not stored in the event-side, then it must be a scene-graph only property
3082 GetCurrentPropertyValue( index, value );
3088 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3090 Property::Value value;
3092 if( ! GetCurrentPropertyValue( index, value ) )
3094 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3095 GetCachedPropertyValue( index, value );
3101 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3103 switch( animationType )
3106 case Animation::BETWEEN:
3110 case Dali::Actor::Property::SIZE:
3112 if( value.Get( mTargetSize ) )
3114 // Notify deriving classes
3115 OnSizeAnimation( animation, mTargetSize );
3120 case Dali::Actor::Property::SIZE_WIDTH:
3122 if( value.Get( mTargetSize.width ) )
3124 // Notify deriving classes
3125 OnSizeAnimation( animation, mTargetSize );
3130 case Dali::Actor::Property::SIZE_HEIGHT:
3132 if( value.Get( mTargetSize.height ) )
3134 // Notify deriving classes
3135 OnSizeAnimation( animation, mTargetSize );
3140 case Dali::Actor::Property::SIZE_DEPTH:
3142 if( value.Get( mTargetSize.depth ) )
3144 // Notify deriving classes
3145 OnSizeAnimation( animation, mTargetSize );
3150 case Dali::Actor::Property::POSITION:
3152 value.Get( mTargetPosition );
3156 case Dali::Actor::Property::POSITION_X:
3158 value.Get( mTargetPosition.x );
3162 case Dali::Actor::Property::POSITION_Y:
3164 value.Get( mTargetPosition.y );
3168 case Dali::Actor::Property::POSITION_Z:
3170 value.Get( mTargetPosition.z );
3174 case Dali::Actor::Property::ORIENTATION:
3176 value.Get( mTargetOrientation );
3180 case Dali::Actor::Property::SCALE:
3182 value.Get( mTargetScale );
3186 case Dali::Actor::Property::SCALE_X:
3188 value.Get( mTargetScale.x );
3192 case Dali::Actor::Property::SCALE_Y:
3194 value.Get( mTargetScale.y );
3198 case Dali::Actor::Property::SCALE_Z:
3200 value.Get( mTargetScale.z );
3204 case Dali::Actor::Property::VISIBLE:
3206 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3210 case Dali::Actor::Property::COLOR:
3212 value.Get( mTargetColor );
3216 case Dali::Actor::Property::COLOR_RED:
3218 value.Get( mTargetColor.r );
3222 case Dali::Actor::Property::COLOR_GREEN:
3224 value.Get( mTargetColor.g );
3228 case Dali::Actor::Property::COLOR_BLUE:
3230 value.Get( mTargetColor.b );
3234 case Dali::Actor::Property::COLOR_ALPHA:
3235 case Dali::DevelActor::Property::OPACITY:
3237 value.Get( mTargetColor.a );
3243 // Not an animatable property. Do nothing.
3254 case Dali::Actor::Property::SIZE:
3256 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3258 // Notify deriving classes
3259 OnSizeAnimation( animation, mTargetSize );
3264 case Dali::Actor::Property::SIZE_WIDTH:
3266 if( AdjustValue< float >( mTargetSize.width, value ) )
3268 // Notify deriving classes
3269 OnSizeAnimation( animation, mTargetSize );
3274 case Dali::Actor::Property::SIZE_HEIGHT:
3276 if( AdjustValue< float >( mTargetSize.height, value ) )
3278 // Notify deriving classes
3279 OnSizeAnimation( animation, mTargetSize );
3284 case Dali::Actor::Property::SIZE_DEPTH:
3286 if( AdjustValue< float >( mTargetSize.depth, value ) )
3288 // Notify deriving classes
3289 OnSizeAnimation( animation, mTargetSize );
3294 case Dali::Actor::Property::POSITION:
3296 AdjustValue< Vector3 >( mTargetPosition, value );
3300 case Dali::Actor::Property::POSITION_X:
3302 AdjustValue< float >( mTargetPosition.x, value );
3306 case Dali::Actor::Property::POSITION_Y:
3308 AdjustValue< float >( mTargetPosition.y, value );
3312 case Dali::Actor::Property::POSITION_Z:
3314 AdjustValue< float >( mTargetPosition.z, value );
3318 case Dali::Actor::Property::ORIENTATION:
3320 Quaternion relativeValue;
3321 if( value.Get( relativeValue ) )
3323 mTargetOrientation *= relativeValue;
3328 case Dali::Actor::Property::SCALE:
3330 AdjustValue< Vector3 >( mTargetScale, value );
3334 case Dali::Actor::Property::SCALE_X:
3336 AdjustValue< float >( mTargetScale.x, value );
3340 case Dali::Actor::Property::SCALE_Y:
3342 AdjustValue< float >( mTargetScale.y, value );
3346 case Dali::Actor::Property::SCALE_Z:
3348 AdjustValue< float >( mTargetScale.z, value );
3352 case Dali::Actor::Property::VISIBLE:
3354 bool relativeValue = false;
3355 if( value.Get( relativeValue ) )
3357 bool visible = mVisible || relativeValue;
3358 SetVisibleInternal( visible, SendMessage::FALSE );
3363 case Dali::Actor::Property::COLOR:
3365 AdjustValue< Vector4 >( mTargetColor, value );
3369 case Dali::Actor::Property::COLOR_RED:
3371 AdjustValue< float >( mTargetColor.r, value );
3375 case Dali::Actor::Property::COLOR_GREEN:
3377 AdjustValue< float >( mTargetColor.g, value );
3381 case Dali::Actor::Property::COLOR_BLUE:
3383 AdjustValue< float >( mTargetColor.b, value );
3387 case Dali::Actor::Property::COLOR_ALPHA:
3388 case Dali::DevelActor::Property::OPACITY:
3390 AdjustValue< float >( mTargetColor.a, value );
3396 // Not an animatable property. Do nothing.
3405 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3410 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3412 // This method should only return an object connected to the scene-graph
3413 return OnStage() ? mNode : NULL;
3416 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3418 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3420 const PropertyBase* property( NULL );
3422 // This method should only return a property of an object connected to the scene-graph
3428 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3430 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3431 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3433 property = animatable->GetSceneGraphProperty();
3435 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3436 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3438 CustomPropertyMetadata* custom = FindCustomProperty( index );
3439 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3441 property = custom->GetSceneGraphProperty();
3443 else if( NULL != mNode )
3447 case Dali::Actor::Property::SIZE:
3448 property = &mNode->mSize;
3451 case Dali::Actor::Property::SIZE_WIDTH:
3452 property = &mNode->mSize;
3455 case Dali::Actor::Property::SIZE_HEIGHT:
3456 property = &mNode->mSize;
3459 case Dali::Actor::Property::SIZE_DEPTH:
3460 property = &mNode->mSize;
3463 case Dali::Actor::Property::POSITION:
3464 property = &mNode->mPosition;
3467 case Dali::Actor::Property::POSITION_X:
3468 property = &mNode->mPosition;
3471 case Dali::Actor::Property::POSITION_Y:
3472 property = &mNode->mPosition;
3475 case Dali::Actor::Property::POSITION_Z:
3476 property = &mNode->mPosition;
3479 case Dali::Actor::Property::ORIENTATION:
3480 property = &mNode->mOrientation;
3483 case Dali::Actor::Property::SCALE:
3484 property = &mNode->mScale;
3487 case Dali::Actor::Property::SCALE_X:
3488 property = &mNode->mScale;
3491 case Dali::Actor::Property::SCALE_Y:
3492 property = &mNode->mScale;
3495 case Dali::Actor::Property::SCALE_Z:
3496 property = &mNode->mScale;
3499 case Dali::Actor::Property::VISIBLE:
3500 property = &mNode->mVisible;
3503 case Dali::Actor::Property::COLOR:
3504 property = &mNode->mColor;
3507 case Dali::Actor::Property::COLOR_RED:
3508 property = &mNode->mColor;
3511 case Dali::Actor::Property::COLOR_GREEN:
3512 property = &mNode->mColor;
3515 case Dali::Actor::Property::COLOR_BLUE:
3516 property = &mNode->mColor;
3519 case Dali::Actor::Property::COLOR_ALPHA:
3520 case Dali::DevelActor::Property::OPACITY:
3521 property = &mNode->mColor;
3532 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3534 const PropertyInputImpl* property( NULL );
3536 // This method should only return a property of an object connected to the scene-graph
3542 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3544 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3545 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3547 property = animatable->GetSceneGraphProperty();
3549 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3550 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3552 CustomPropertyMetadata* custom = FindCustomProperty( index );
3553 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3554 property = custom->GetSceneGraphProperty();
3556 else if( NULL != mNode )
3560 case Dali::Actor::Property::PARENT_ORIGIN:
3561 property = &mNode->mParentOrigin;
3564 case Dali::Actor::Property::PARENT_ORIGIN_X:
3565 property = &mNode->mParentOrigin;
3568 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3569 property = &mNode->mParentOrigin;
3572 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3573 property = &mNode->mParentOrigin;
3576 case Dali::Actor::Property::ANCHOR_POINT:
3577 property = &mNode->mAnchorPoint;
3580 case Dali::Actor::Property::ANCHOR_POINT_X:
3581 property = &mNode->mAnchorPoint;
3584 case Dali::Actor::Property::ANCHOR_POINT_Y:
3585 property = &mNode->mAnchorPoint;
3588 case Dali::Actor::Property::ANCHOR_POINT_Z:
3589 property = &mNode->mAnchorPoint;
3592 case Dali::Actor::Property::SIZE:
3593 property = &mNode->mSize;
3596 case Dali::Actor::Property::SIZE_WIDTH:
3597 property = &mNode->mSize;
3600 case Dali::Actor::Property::SIZE_HEIGHT:
3601 property = &mNode->mSize;
3604 case Dali::Actor::Property::SIZE_DEPTH:
3605 property = &mNode->mSize;
3608 case Dali::Actor::Property::POSITION:
3609 property = &mNode->mPosition;
3612 case Dali::Actor::Property::POSITION_X:
3613 property = &mNode->mPosition;
3616 case Dali::Actor::Property::POSITION_Y:
3617 property = &mNode->mPosition;
3620 case Dali::Actor::Property::POSITION_Z:
3621 property = &mNode->mPosition;
3624 case Dali::Actor::Property::WORLD_POSITION:
3625 property = &mNode->mWorldPosition;
3628 case Dali::Actor::Property::WORLD_POSITION_X:
3629 property = &mNode->mWorldPosition;
3632 case Dali::Actor::Property::WORLD_POSITION_Y:
3633 property = &mNode->mWorldPosition;
3636 case Dali::Actor::Property::WORLD_POSITION_Z:
3637 property = &mNode->mWorldPosition;
3640 case Dali::Actor::Property::ORIENTATION:
3641 property = &mNode->mOrientation;
3644 case Dali::Actor::Property::WORLD_ORIENTATION:
3645 property = &mNode->mWorldOrientation;
3648 case Dali::Actor::Property::SCALE:
3649 property = &mNode->mScale;
3652 case Dali::Actor::Property::SCALE_X:
3653 property = &mNode->mScale;
3656 case Dali::Actor::Property::SCALE_Y:
3657 property = &mNode->mScale;
3660 case Dali::Actor::Property::SCALE_Z:
3661 property = &mNode->mScale;
3664 case Dali::Actor::Property::WORLD_SCALE:
3665 property = &mNode->mWorldScale;
3668 case Dali::Actor::Property::VISIBLE:
3669 property = &mNode->mVisible;
3672 case Dali::Actor::Property::COLOR:
3673 property = &mNode->mColor;
3676 case Dali::Actor::Property::COLOR_RED:
3677 property = &mNode->mColor;
3680 case Dali::Actor::Property::COLOR_GREEN:
3681 property = &mNode->mColor;
3684 case Dali::Actor::Property::COLOR_BLUE:
3685 property = &mNode->mColor;
3688 case Dali::Actor::Property::COLOR_ALPHA:
3689 case Dali::DevelActor::Property::OPACITY:
3691 property = &mNode->mColor;
3695 case Dali::Actor::Property::WORLD_COLOR:
3696 property = &mNode->mWorldColor;
3699 case Dali::Actor::Property::WORLD_MATRIX:
3700 property = &mNode->mWorldMatrix;
3711 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3713 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3715 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3717 // check whether the animatable property is registered already, if not then register one.
3718 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3719 if( animatableProperty )
3721 componentIndex = animatableProperty->componentIndex;
3728 case Dali::Actor::Property::PARENT_ORIGIN_X:
3729 case Dali::Actor::Property::ANCHOR_POINT_X:
3730 case Dali::Actor::Property::SIZE_WIDTH:
3731 case Dali::Actor::Property::POSITION_X:
3732 case Dali::Actor::Property::WORLD_POSITION_X:
3733 case Dali::Actor::Property::SCALE_X:
3734 case Dali::Actor::Property::COLOR_RED:
3740 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3741 case Dali::Actor::Property::ANCHOR_POINT_Y:
3742 case Dali::Actor::Property::SIZE_HEIGHT:
3743 case Dali::Actor::Property::POSITION_Y:
3744 case Dali::Actor::Property::WORLD_POSITION_Y:
3745 case Dali::Actor::Property::SCALE_Y:
3746 case Dali::Actor::Property::COLOR_GREEN:
3752 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3753 case Dali::Actor::Property::ANCHOR_POINT_Z:
3754 case Dali::Actor::Property::SIZE_DEPTH:
3755 case Dali::Actor::Property::POSITION_Z:
3756 case Dali::Actor::Property::WORLD_POSITION_Z:
3757 case Dali::Actor::Property::SCALE_Z:
3758 case Dali::Actor::Property::COLOR_BLUE:
3764 case Dali::Actor::Property::COLOR_ALPHA:
3765 case Dali::DevelActor::Property::OPACITY:
3779 return componentIndex;
3782 void Actor::SetParent( Actor* parent )
3786 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3790 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3793 // Instruct each actor to create a corresponding node in the scene graph
3794 ConnectToStage( parent->GetHierarchyDepth() );
3797 // Resolve the name and index for the child properties if any
3798 ResolveChildProperties();
3800 else // parent being set to NULL
3802 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3806 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3809 DALI_ASSERT_ALWAYS( mNode != NULL );
3813 // Disconnect the Node & its children from the scene-graph.
3814 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3817 // Instruct each actor to discard pointers to the scene-graph
3818 DisconnectFromStage();
3823 SceneGraph::Node* Actor::CreateNode() const
3828 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3831 Actor* actor = dynamic_cast< Actor* >( object );
3835 if( 0 == actionName.compare( ACTION_SHOW ) )
3837 actor->SetVisible( true );
3840 else if( 0 == actionName.compare( ACTION_HIDE ) )
3842 actor->SetVisible( false );
3850 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3852 bool valueSet = true;
3856 case Dali::Actor::Property::PARENT_ORIGIN:
3858 value = GetCurrentParentOrigin();
3862 case Dali::Actor::Property::PARENT_ORIGIN_X:
3864 value = GetCurrentParentOrigin().x;
3868 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3870 value = GetCurrentParentOrigin().y;
3874 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3876 value = GetCurrentParentOrigin().z;
3880 case Dali::Actor::Property::ANCHOR_POINT:
3882 value = GetCurrentAnchorPoint();
3886 case Dali::Actor::Property::ANCHOR_POINT_X:
3888 value = GetCurrentAnchorPoint().x;
3892 case Dali::Actor::Property::ANCHOR_POINT_Y:
3894 value = GetCurrentAnchorPoint().y;
3898 case Dali::Actor::Property::ANCHOR_POINT_Z:
3900 value = GetCurrentAnchorPoint().z;
3904 case Dali::Actor::Property::SIZE:
3906 value = GetTargetSize();
3910 case Dali::Actor::Property::SIZE_WIDTH:
3912 value = GetTargetSize().width;
3916 case Dali::Actor::Property::SIZE_HEIGHT:
3918 value = GetTargetSize().height;
3922 case Dali::Actor::Property::SIZE_DEPTH:
3924 value = GetTargetSize().depth;
3928 case Dali::Actor::Property::POSITION:
3930 value = GetTargetPosition();
3934 case Dali::Actor::Property::POSITION_X:
3936 value = GetTargetPosition().x;
3940 case Dali::Actor::Property::POSITION_Y:
3942 value = GetTargetPosition().y;
3946 case Dali::Actor::Property::POSITION_Z:
3948 value = GetTargetPosition().z;
3952 case Dali::Actor::Property::ORIENTATION:
3954 value = mTargetOrientation;
3958 case Dali::Actor::Property::SCALE:
3960 value = mTargetScale;
3964 case Dali::Actor::Property::SCALE_X:
3966 value = mTargetScale.x;
3970 case Dali::Actor::Property::SCALE_Y:
3972 value = mTargetScale.y;
3976 case Dali::Actor::Property::SCALE_Z:
3978 value = mTargetScale.z;
3982 case Dali::Actor::Property::VISIBLE:
3988 case Dali::Actor::Property::COLOR:
3990 value = mTargetColor;
3994 case Dali::Actor::Property::COLOR_RED:
3996 value = mTargetColor.r;
4000 case Dali::Actor::Property::COLOR_GREEN:
4002 value = mTargetColor.g;
4006 case Dali::Actor::Property::COLOR_BLUE:
4008 value = mTargetColor.b;
4012 case Dali::Actor::Property::COLOR_ALPHA:
4013 case Dali::DevelActor::Property::OPACITY:
4015 value = mTargetColor.a;
4019 case Dali::Actor::Property::NAME:
4025 case Dali::Actor::Property::SENSITIVE:
4027 value = IsSensitive();
4031 case Dali::Actor::Property::LEAVE_REQUIRED:
4033 value = GetLeaveRequired();
4037 case Dali::Actor::Property::INHERIT_POSITION:
4039 value = IsPositionInherited();
4043 case Dali::Actor::Property::INHERIT_ORIENTATION:
4045 value = IsOrientationInherited();
4049 case Dali::Actor::Property::INHERIT_SCALE:
4051 value = IsScaleInherited();
4055 case Dali::Actor::Property::COLOR_MODE:
4057 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4061 case Dali::Actor::Property::POSITION_INHERITANCE:
4063 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4067 case Dali::Actor::Property::DRAW_MODE:
4069 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4073 case Dali::Actor::Property::SIZE_MODE_FACTOR:
4075 value = GetSizeModeFactor();
4079 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4081 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4085 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4087 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4091 case Dali::Actor::Property::SIZE_SCALE_POLICY:
4093 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4097 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4099 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4103 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4105 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4109 case Dali::Actor::Property::PADDING:
4111 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4112 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4113 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4117 case Dali::Actor::Property::MINIMUM_SIZE:
4119 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4123 case Dali::Actor::Property::MAXIMUM_SIZE:
4125 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4129 case Dali::Actor::Property::CLIPPING_MODE:
4131 value = mClippingMode;
4135 case Dali::DevelActor::Property::SIBLING_ORDER:
4137 value = static_cast<int>( GetSiblingOrder() );
4141 case Dali::DevelActor::Property::SCREEN_POSITION:
4143 value = GetCurrentScreenPosition();
4147 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4149 value = mPositionUsesAnchorPoint;
4153 case Dali::Actor::Property::LAYOUT_DIRECTION:
4155 value = mLayoutDirection;
4159 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
4161 value = IsLayoutDirectionInherited();
4167 // Must be a scene-graph only property
4176 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
4178 bool valueSet = true;
4182 case Dali::Actor::Property::SIZE:
4184 value = GetCurrentSize();
4188 case Dali::Actor::Property::SIZE_WIDTH:
4190 value = GetCurrentSize().width;
4194 case Dali::Actor::Property::SIZE_HEIGHT:
4196 value = GetCurrentSize().height;
4200 case Dali::Actor::Property::SIZE_DEPTH:
4202 value = GetCurrentSize().depth;
4206 case Dali::Actor::Property::POSITION:
4208 value = GetCurrentPosition();
4212 case Dali::Actor::Property::POSITION_X:
4214 value = GetCurrentPosition().x;
4218 case Dali::Actor::Property::POSITION_Y:
4220 value = GetCurrentPosition().y;
4224 case Dali::Actor::Property::POSITION_Z:
4226 value = GetCurrentPosition().z;
4230 case Dali::Actor::Property::WORLD_POSITION:
4232 value = GetCurrentWorldPosition();
4236 case Dali::Actor::Property::WORLD_POSITION_X:
4238 value = GetCurrentWorldPosition().x;
4242 case Dali::Actor::Property::WORLD_POSITION_Y:
4244 value = GetCurrentWorldPosition().y;
4248 case Dali::Actor::Property::WORLD_POSITION_Z:
4250 value = GetCurrentWorldPosition().z;
4254 case Dali::Actor::Property::ORIENTATION:
4256 value = GetCurrentOrientation();
4260 case Dali::Actor::Property::WORLD_ORIENTATION:
4262 value = GetCurrentWorldOrientation();
4266 case Dali::Actor::Property::SCALE:
4268 value = GetCurrentScale();
4272 case Dali::Actor::Property::SCALE_X:
4274 value = GetCurrentScale().x;
4278 case Dali::Actor::Property::SCALE_Y:
4280 value = GetCurrentScale().y;
4284 case Dali::Actor::Property::SCALE_Z:
4286 value = GetCurrentScale().z;
4290 case Dali::Actor::Property::WORLD_SCALE:
4292 value = GetCurrentWorldScale();
4296 case Dali::Actor::Property::COLOR:
4298 value = GetCurrentColor();
4302 case Dali::Actor::Property::COLOR_RED:
4304 value = GetCurrentColor().r;
4308 case Dali::Actor::Property::COLOR_GREEN:
4310 value = GetCurrentColor().g;
4314 case Dali::Actor::Property::COLOR_BLUE:
4316 value = GetCurrentColor().b;
4320 case Dali::Actor::Property::COLOR_ALPHA:
4321 case Dali::DevelActor::Property::OPACITY:
4323 value = GetCurrentColor().a;
4327 case Dali::Actor::Property::WORLD_COLOR:
4329 value = GetCurrentWorldColor();
4333 case Dali::Actor::Property::WORLD_MATRIX:
4335 value = GetCurrentWorldMatrix();
4339 case Dali::Actor::Property::VISIBLE:
4341 value = IsVisible();
4347 // Must be an event-side only property
4356 void Actor::EnsureRelayoutData()
4358 // Assign relayout data.
4359 if( !mRelayoutData )
4361 mRelayoutData = new RelayoutData();
4365 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4367 // Check if actor is dependent on parent
4368 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4370 if( ( dimension & ( 1 << i ) ) )
4372 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4373 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4383 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4385 // Check if actor is dependent on children
4386 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4388 if( ( dimension & ( 1 << i ) ) )
4390 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4391 switch( resizePolicy )
4393 case ResizePolicy::FIT_TO_CHILDREN:
4394 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4410 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4412 return Actor::RelayoutDependentOnChildren( dimension );
4415 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4417 // Check each possible dimension and see if it is dependent on the input one
4418 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4420 if( dimension & ( 1 << i ) )
4422 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4429 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4431 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4433 if( dimension & ( 1 << i ) )
4435 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4440 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4442 // If more than one dimension is requested, just return the first one found
4443 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4445 if( ( dimension & ( 1 << i ) ) )
4447 return mRelayoutData->negotiatedDimensions[ i ];
4451 return 0.0f; // Default
4454 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4456 EnsureRelayoutData();
4458 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4460 if( dimension & ( 1 << i ) )
4462 mRelayoutData->dimensionPadding[ i ] = padding;
4467 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4469 if ( mRelayoutData )
4471 // If more than one dimension is requested, just return the first one found
4472 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4474 if( ( dimension & ( 1 << i ) ) )
4476 return mRelayoutData->dimensionPadding[ i ];
4481 return GetDefaultDimensionPadding();
4484 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4486 EnsureRelayoutData();
4488 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4490 if( dimension & ( 1 << i ) )
4492 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4497 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4499 if ( mRelayoutData )
4501 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4503 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4513 float Actor::GetHeightForWidthBase( float width )
4515 float height = 0.0f;
4517 const Vector3 naturalSize = GetNaturalSize();
4518 if( naturalSize.width > 0.0f )
4520 height = naturalSize.height * width / naturalSize.width;
4522 else // we treat 0 as 1:1 aspect ratio
4530 float Actor::GetWidthForHeightBase( float height )
4534 const Vector3 naturalSize = GetNaturalSize();
4535 if( naturalSize.height > 0.0f )
4537 width = naturalSize.width * height / naturalSize.height;
4539 else // we treat 0 as 1:1 aspect ratio
4547 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4549 // Fill to parent, taking size mode factor into account
4550 switch( child.GetResizePolicy( dimension ) )
4552 case ResizePolicy::FILL_TO_PARENT:
4554 return GetLatestSize( dimension );
4557 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4559 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4562 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4564 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4569 return GetLatestSize( dimension );
4574 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4576 // Can be overridden in derived class
4577 return CalculateChildSizeBase( child, dimension );
4580 float Actor::GetHeightForWidth( float width )
4582 // Can be overridden in derived class
4583 return GetHeightForWidthBase( width );
4586 float Actor::GetWidthForHeight( float height )
4588 // Can be overridden in derived class
4589 return GetWidthForHeightBase( height );
4592 float Actor::GetLatestSize( Dimension::Type dimension ) const
4594 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4597 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4599 Vector2 padding = GetPadding( dimension );
4601 return GetLatestSize( dimension ) + padding.x + padding.y;
4604 float Actor::NegotiateFromParent( Dimension::Type dimension )
4606 Actor* parent = GetParent();
4609 Vector2 padding( GetPadding( dimension ) );
4610 Vector2 parentPadding( parent->GetPadding( dimension ) );
4611 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4617 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4619 float maxDimensionPoint = 0.0f;
4621 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4623 ActorPtr child = GetChildAt( i );
4625 if( !child->RelayoutDependentOnParent( dimension ) )
4627 // Calculate the min and max points that the children range across
4628 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4629 float dimensionSize = child->GetRelayoutSize( dimension );
4630 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4634 return maxDimensionPoint;
4637 float Actor::GetSize( Dimension::Type dimension ) const
4639 return GetDimensionValue( mTargetSize, dimension );
4642 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4644 return GetDimensionValue( GetNaturalSize(), dimension );
4647 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4649 switch( GetResizePolicy( dimension ) )
4651 case ResizePolicy::USE_NATURAL_SIZE:
4653 return GetNaturalSize( dimension );
4656 case ResizePolicy::FIXED:
4658 return GetDimensionValue( GetPreferredSize(), dimension );
4661 case ResizePolicy::USE_ASSIGNED_SIZE:
4663 return GetDimensionValue( maximumSize, dimension );
4666 case ResizePolicy::FILL_TO_PARENT:
4667 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4668 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4670 return NegotiateFromParent( dimension );
4673 case ResizePolicy::FIT_TO_CHILDREN:
4675 return NegotiateFromChildren( dimension );
4678 case ResizePolicy::DIMENSION_DEPENDENCY:
4680 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4683 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4685 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4688 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4690 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4702 return 0.0f; // Default
4705 float Actor::ClampDimension( float size, Dimension::Type dimension )
4707 const float minSize = GetMinimumSize( dimension );
4708 const float maxSize = GetMaximumSize( dimension );
4710 return std::max( minSize, std::min( size, maxSize ) );
4713 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4715 // Check if it needs to be negotiated
4716 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4718 // Check that we havn't gotten into an infinite loop
4719 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4720 bool recursionFound = false;
4721 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4723 if( *it == searchActor )
4725 recursionFound = true;
4730 if( !recursionFound )
4732 // Record the path that we have taken
4733 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4735 // Dimension dependency check
4736 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4738 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4740 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4742 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4746 // Parent dependency check
4747 Actor* parent = GetParent();
4748 if( parent && RelayoutDependentOnParent( dimension ) )
4750 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4753 // Children dependency check
4754 if( RelayoutDependentOnChildren( dimension ) )
4756 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4758 ActorPtr child = GetChildAt( i );
4760 // Only relayout child first if it is not dependent on this actor
4761 if( !child->RelayoutDependentOnParent( dimension ) )
4763 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4768 // For deriving classes
4769 OnCalculateRelayoutSize( dimension );
4771 // All dependencies checked, calculate the size and set negotiated flag
4772 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4774 SetNegotiatedDimension( newSize, dimension );
4775 SetLayoutNegotiated( true, dimension );
4777 // For deriving classes
4778 OnLayoutNegotiated( newSize, dimension );
4780 // This actor has been successfully processed, pop it off the recursion stack
4781 recursionStack.pop_back();
4785 // TODO: Break infinite loop
4786 SetLayoutNegotiated( true, dimension );
4791 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4793 // Negotiate all dimensions that require it
4794 ActorDimensionStack recursionStack;
4796 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4798 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4801 NegotiateDimension( dimension, allocatedSize, recursionStack );
4805 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4807 switch( mRelayoutData->sizeSetPolicy )
4809 case SizeScalePolicy::USE_SIZE_SET:
4814 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4816 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4817 const Vector3 naturalSize = GetNaturalSize();
4818 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4820 const float sizeRatio = size.width / size.height;
4821 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4823 if( naturalSizeRatio < sizeRatio )
4825 return Vector2( naturalSizeRatio * size.height, size.height );
4827 else if( naturalSizeRatio > sizeRatio )
4829 return Vector2( size.width, size.width / naturalSizeRatio );
4840 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4842 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4843 const Vector3 naturalSize = GetNaturalSize();
4844 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4846 const float sizeRatio = size.width / size.height;
4847 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4849 if( naturalSizeRatio < sizeRatio )
4851 return Vector2( size.width, size.width / naturalSizeRatio );
4853 else if( naturalSizeRatio > sizeRatio )
4855 return Vector2( naturalSizeRatio * size.height, size.height );
4874 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4876 // Do the set actor size
4877 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4879 // Adjust for size set policy
4880 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4882 // Lock the flag to stop recursive relayouts on set size
4883 mRelayoutData->insideRelayout = true;
4884 SetSize( negotiatedSize );
4885 mRelayoutData->insideRelayout = false;
4887 // Clear flags for all dimensions
4888 SetLayoutDirty( false );
4890 // Give deriving classes a chance to respond
4891 OnRelayout( negotiatedSize, container );
4893 if( !mOnRelayoutSignal.Empty() )
4895 Dali::Actor handle( this );
4896 mOnRelayoutSignal.Emit( handle );
4900 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4902 // Force a size negotiation for actors that has assigned size during relayout
4903 // This is required as otherwise the flags that force a relayout will not
4904 // necessarilly be set. This will occur if the actor has already been laid out.
4905 // The dirty flags are then cleared. Then if the actor is added back into the
4906 // relayout container afterwards, the dirty flags would still be clear...
4907 // causing a relayout to be skipped. Here we force any actors added to the
4908 // container to be relayed out.
4909 DALI_LOG_TIMER_START( NegSizeTimer1 );
4911 if( GetUseAssignedSize(Dimension::WIDTH ) )
4913 SetLayoutNegotiated( false, Dimension::WIDTH );
4915 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4917 SetLayoutNegotiated( false, Dimension::HEIGHT );
4920 // Do the negotiation
4921 NegotiateDimensions( allocatedSize );
4923 // Set the actor size
4924 SetNegotiatedSize( container );
4926 // Negotiate down to children
4927 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4929 ActorPtr child = GetChildAt( i );
4931 // Forces children that have already been laid out to be relayed out
4932 // if they have assigned size during relayout.
4933 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4935 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4936 child->SetLayoutDirty(true, Dimension::WIDTH);
4939 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4941 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4942 child->SetLayoutDirty(true, Dimension::HEIGHT);
4945 // Only relayout if required
4946 if( child->RelayoutRequired() )
4948 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4951 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4954 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4958 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4960 if( dimension & ( 1 << i ) )
4962 mRelayoutData->useAssignedSize[ i ] = use;
4968 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4970 if ( mRelayoutData )
4972 // If more than one dimension is requested, just return the first one found
4973 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4975 if( dimension & ( 1 << i ) )
4977 return mRelayoutData->useAssignedSize[ i ];
4985 void Actor::RelayoutRequest( Dimension::Type dimension )
4987 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4988 if( relayoutController )
4990 Dali::Actor self( this );
4991 relayoutController->RequestRelayout( self, dimension );
4995 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4999 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
5003 void Actor::SetPreferredSize( const Vector2& size )
5005 EnsureRelayoutData();
5007 if( size.width > 0.0f )
5009 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
5012 if( size.height > 0.0f )
5014 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
5017 mRelayoutData->preferredSize = size;
5022 Vector2 Actor::GetPreferredSize() const
5024 if ( mRelayoutData )
5026 return Vector2( mRelayoutData->preferredSize );
5029 return GetDefaultPreferredSize();
5032 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
5034 EnsureRelayoutData();
5036 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5038 if( dimension & ( 1 << i ) )
5040 mRelayoutData->minimumSize[ i ] = size;
5047 float Actor::GetMinimumSize( Dimension::Type dimension ) const
5049 if ( mRelayoutData )
5051 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5053 if( dimension & ( 1 << i ) )
5055 return mRelayoutData->minimumSize[ i ];
5060 return 0.0f; // Default
5063 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5065 EnsureRelayoutData();
5067 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5069 if( dimension & ( 1 << i ) )
5071 mRelayoutData->maximumSize[ i ] = size;
5078 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5080 if ( mRelayoutData )
5082 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5084 if( dimension & ( 1 << i ) )
5086 return mRelayoutData->maximumSize[ i ];
5091 return FLT_MAX; // Default
5094 Object* Actor::GetParentObject() const
5099 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5101 if( mVisible != visible )
5103 if( sendMessage == SendMessage::TRUE && NULL != mNode )
5105 // mNode is being used in a separate thread; queue a message to set the value & base value
5106 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5111 // Emit the signal on this actor and all its children
5112 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5116 void Actor::SetSiblingOrder( unsigned int order )
5120 ActorContainer& siblings = *(mParent->mChildren);
5121 unsigned int currentOrder = GetSiblingOrder();
5123 if( order != currentOrder )
5129 else if( order < siblings.size() -1 )
5131 if( order > currentOrder )
5133 RaiseAbove( *siblings[order] );
5137 LowerBelow( *siblings[order] );
5148 unsigned int Actor::GetSiblingOrder() const
5150 unsigned int order = 0;
5154 ActorContainer& siblings = *(mParent->mChildren);
5155 for( size_t i=0; i<siblings.size(); ++i )
5157 if( siblings[i] == this )
5168 void Actor::RequestRebuildDepthTree()
5172 StagePtr stage = Stage::GetCurrent();
5175 stage->RequestRebuildDepthTree();
5184 ActorContainer& siblings = *(mParent->mChildren);
5185 if( siblings.back() != this ) // If not already at end
5187 for( size_t i=0; i<siblings.size(); ++i )
5189 if( siblings[i] == this )
5192 ActorPtr next = siblings[i+1];
5193 siblings[i+1] = this;
5199 RequestRebuildDepthTree();
5203 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5211 ActorContainer& siblings = *(mParent->mChildren);
5212 if( siblings.front() != this ) // If not already at beginning
5214 for( size_t i=1; i<siblings.size(); ++i )
5216 if( siblings[i] == this )
5218 // Swap with previous
5219 ActorPtr previous = siblings[i-1];
5220 siblings[i-1] = this;
5221 siblings[i] = previous;
5226 RequestRebuildDepthTree();
5230 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5234 void Actor::RaiseToTop()
5238 ActorContainer& siblings = *(mParent->mChildren);
5239 if( siblings.back() != this ) // If not already at end
5241 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5242 if( iter != siblings.end() )
5244 siblings.erase(iter);
5245 siblings.push_back(ActorPtr(this));
5248 RequestRebuildDepthTree();
5252 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5256 void Actor::LowerToBottom()
5260 ActorContainer& siblings = *(mParent->mChildren);
5261 if( siblings.front() != this ) // If not already at bottom,
5263 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5265 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5266 if( iter != siblings.end() )
5268 siblings.erase(iter);
5269 siblings.insert(siblings.begin(), thisPtr);
5272 RequestRebuildDepthTree();
5276 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5280 void Actor::RaiseAbove( Internal::Actor& target )
5284 ActorContainer& siblings = *(mParent->mChildren);
5285 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5287 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5289 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5290 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5291 if( thisIter < targetIter )
5293 siblings.erase(thisIter);
5294 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5295 // invalidate thisIter)
5296 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5298 siblings.insert(targetIter, thisPtr);
5300 RequestRebuildDepthTree();
5305 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5309 void Actor::LowerBelow( Internal::Actor& target )
5313 ActorContainer& siblings = *(mParent->mChildren);
5314 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5316 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5318 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5319 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5321 if( thisIter > targetIter )
5323 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5324 siblings.insert(targetIter, thisPtr);
5326 RequestRebuildDepthTree();
5331 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5335 void Actor::SetInheritLayoutDirection( bool inherit )
5337 if( mInheritLayoutDirection != inherit )
5339 mInheritLayoutDirection = inherit;
5341 if( inherit && mParent )
5343 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5348 bool Actor::IsLayoutDirectionInherited() const
5350 return mInheritLayoutDirection;
5353 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5355 if( actor && ( actor->mInheritLayoutDirection || set ) )
5357 if( actor->mLayoutDirection != direction)
5359 actor->mLayoutDirection = direction;
5360 actor->EmitLayoutDirectionChangedSignal( direction );
5361 actor->RelayoutRequest();
5364 if( actor->GetChildCount() > 0 )
5366 ActorContainer& children = actor->GetChildrenInternal();
5367 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5369 InheritLayoutDirectionRecursively( *iter, direction );
5375 } // namespace Internal