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 if( OnStage() && NULL != mNode )
819 StagePtr stage = Stage::GetCurrent();
820 Vector3 worldPosition = mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
821 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
822 Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
823 Vector3 halfActorSize( actorSize * 0.5f );
824 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
826 return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
827 halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
830 return Vector2::ZERO;
833 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
835 // this flag is not animatable so keep the value
836 mPositionInheritanceMode = mode;
839 // mNode is being used in a separate thread; queue a message to set the value
840 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
844 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
846 // Cached for event-thread access
847 return mPositionInheritanceMode;
850 void Actor::SetInheritPosition( bool inherit )
852 if( mInheritPosition != inherit && NULL != mNode )
854 // non animateable so keep local copy
855 mInheritPosition = inherit;
856 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
860 bool Actor::IsPositionInherited() const
862 return mInheritPosition;
865 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
867 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
868 normalizedAxis.Normalize();
870 Quaternion orientation( angle, normalizedAxis );
872 SetOrientation( orientation );
875 void Actor::SetOrientation( const Quaternion& orientation )
877 mTargetOrientation = orientation;
881 // mNode is being used in a separate thread; queue a message to set the value & base value
882 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
886 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
888 RotateBy( Quaternion(angle, axis) );
891 void Actor::RotateBy( const Quaternion& relativeRotation )
893 mTargetOrientation *= Quaternion( relativeRotation );
897 // mNode is being used in a separate thread; queue a message to set the value & base value
898 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
902 const Quaternion& Actor::GetCurrentOrientation() const
906 // mNode is being used in a separate thread; copy the value from the previous update
907 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
910 return Quaternion::IDENTITY;
913 const Quaternion& Actor::GetCurrentWorldOrientation() const
917 // mNode is being used in a separate thread; copy the value from the previous update
918 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
921 return Quaternion::IDENTITY;
924 void Actor::SetScale( float scale )
926 SetScale( Vector3( scale, scale, scale ) );
929 void Actor::SetScale( float x, float y, float z )
931 SetScale( Vector3( x, y, z ) );
934 void Actor::SetScale( const Vector3& scale )
936 mTargetScale = scale;
940 // mNode is being used in a separate thread; queue a message to set the value & base value
941 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
945 void Actor::SetScaleX( float x )
951 // mNode is being used in a separate thread; queue a message to set the value & base value
952 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
956 void Actor::SetScaleY( float y )
962 // mNode is being used in a separate thread; queue a message to set the value & base value
963 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
967 void Actor::SetScaleZ( float z )
973 // mNode is being used in a separate thread; queue a message to set the value & base value
974 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
978 void Actor::ScaleBy(const Vector3& relativeScale)
980 mTargetScale *= relativeScale;
984 // mNode is being used in a separate thread; queue a message to set the value & base value
985 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
989 const Vector3& Actor::GetCurrentScale() const
993 // mNode is being used in a separate thread; copy the value from the previous update
994 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
1000 const Vector3& Actor::GetCurrentWorldScale() const
1004 // mNode is being used in a separate thread; copy the value from the previous update
1005 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
1008 return Vector3::ONE;
1011 void Actor::SetInheritScale( bool inherit )
1014 if( mInheritScale != inherit && NULL != mNode )
1016 // non animateable so keep local copy
1017 mInheritScale = inherit;
1018 // mNode is being used in a separate thread; queue a message to set the value
1019 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
1023 bool Actor::IsScaleInherited() const
1025 return mInheritScale;
1028 Matrix Actor::GetCurrentWorldMatrix() const
1032 return mNode->GetWorldMatrix(0);
1035 return Matrix::IDENTITY;
1038 void Actor::SetVisible( bool visible )
1040 SetVisibleInternal( visible, SendMessage::TRUE );
1043 bool Actor::IsVisible() const
1047 // mNode is being used in a separate thread; copy the value from the previous update
1048 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1054 void Actor::SetOpacity( float opacity )
1056 mTargetColor.a = opacity;
1060 // mNode is being used in a separate thread; queue a message to set the value & base value
1061 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1065 float Actor::GetCurrentOpacity() const
1069 // mNode is being used in a separate thread; copy the value from the previous update
1070 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1076 ClippingMode::Type Actor::GetClippingMode() const
1078 return mClippingMode;
1081 unsigned int Actor::GetSortingDepth()
1083 return mSortedDepth;
1086 const Vector4& Actor::GetCurrentWorldColor() const
1090 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1093 return Color::WHITE;
1096 void Actor::SetColor( const Vector4& color )
1098 mTargetColor = color;
1102 // mNode is being used in a separate thread; queue a message to set the value & base value
1103 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1107 void Actor::SetColorRed( float red )
1109 mTargetColor.r = red;
1113 // mNode is being used in a separate thread; queue a message to set the value & base value
1114 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1118 void Actor::SetColorGreen( float green )
1120 mTargetColor.g = green;
1124 // mNode is being used in a separate thread; queue a message to set the value & base value
1125 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1129 void Actor::SetColorBlue( float blue )
1131 mTargetColor.b = blue;
1135 // mNode is being used in a separate thread; queue a message to set the value & base value
1136 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1140 const Vector4& Actor::GetCurrentColor() const
1144 // mNode is being used in a separate thread; copy the value from the previous update
1145 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1148 return Color::WHITE;
1151 void Actor::SetInheritOrientation( bool inherit )
1153 if( mInheritOrientation != inherit && NULL != mNode)
1155 // non animateable so keep local copy
1156 mInheritOrientation = inherit;
1157 // mNode is being used in a separate thread; queue a message to set the value
1158 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1162 bool Actor::IsOrientationInherited() const
1164 return mInheritOrientation;
1167 void Actor::SetSizeModeFactor( const Vector3& factor )
1169 EnsureRelayoutData();
1171 mRelayoutData->sizeModeFactor = factor;
1174 const Vector3& Actor::GetSizeModeFactor() const
1176 if ( mRelayoutData )
1178 return mRelayoutData->sizeModeFactor;
1181 return GetDefaultSizeModeFactor();
1184 void Actor::SetColorMode( ColorMode colorMode )
1186 // non animateable so keep local copy
1187 mColorMode = colorMode;
1190 // mNode is being used in a separate thread; queue a message to set the value
1191 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1195 ColorMode Actor::GetColorMode() const
1197 // we have cached copy
1201 void Actor::SetSize( float width, float height )
1203 SetSize( Vector2( width, height ) );
1206 void Actor::SetSize( float width, float height, float depth )
1208 SetSize( Vector3( width, height, depth ) );
1211 void Actor::SetSize( const Vector2& size )
1213 SetSize( Vector3( size.width, size.height, 0.f ) );
1216 void Actor::SetSizeInternal( const Vector2& size )
1218 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1221 void Actor::SetSize( const Vector3& size )
1223 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1225 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1226 SetPreferredSize( size.GetVectorXY() );
1230 SetSizeInternal( size );
1234 void Actor::SetSizeInternal( const Vector3& size )
1236 // dont allow recursive loop
1237 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1238 // 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
1239 if( ( NULL != mNode )&&
1240 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1241 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1242 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1246 // mNode is being used in a separate thread; queue a message to set the value & base value
1247 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1249 // Notification for derived classes
1250 mInsideOnSizeSet = true;
1251 OnSizeSet( mTargetSize );
1252 mInsideOnSizeSet = false;
1254 // Raise a relayout request if the flag is not locked
1255 if( mRelayoutData && !mRelayoutData->insideRelayout )
1262 void Actor::SetWidth( float width )
1264 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1266 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1267 mRelayoutData->preferredSize.width = width;
1271 mTargetSize.width = width;
1275 // mNode is being used in a separate thread; queue a message to set the value & base value
1276 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1283 void Actor::SetHeight( float height )
1285 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1287 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1288 mRelayoutData->preferredSize.height = height;
1292 mTargetSize.height = height;
1296 // mNode is being used in a separate thread; queue a message to set the value & base value
1297 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1304 void Actor::SetDepth( float depth )
1306 mTargetSize.depth = depth;
1310 // mNode is being used in a separate thread; queue a message to set the value & base value
1311 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1315 Vector3 Actor::GetTargetSize() const
1317 Vector3 size = mTargetSize;
1319 // Should return preferred size if size is fixed as set by SetSize
1320 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1322 size.width = GetPreferredSize().width;
1324 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1326 size.height = GetPreferredSize().height;
1332 const Vector3& Actor::GetCurrentSize() const
1336 // mNode is being used in a separate thread; copy the value from the previous update
1337 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1340 return Vector3::ZERO;
1343 Vector3 Actor::GetNaturalSize() const
1345 // It is up to deriving classes to return the appropriate natural size
1346 return Vector3( 0.0f, 0.0f, 0.0f );
1349 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1351 EnsureRelayoutData();
1353 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1354 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1356 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1358 if( dimension & ( 1 << i ) )
1360 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1362 mRelayoutData->useAssignedSize[ i ] = true;
1366 mRelayoutData->resizePolicies[ i ] = policy;
1367 mRelayoutData->useAssignedSize[ i ] = false;
1372 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1374 if( dimension & Dimension::WIDTH )
1376 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1379 if( dimension & Dimension::HEIGHT )
1381 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1385 // If calling SetResizePolicy, assume we want relayout enabled
1386 SetRelayoutEnabled( true );
1388 // If the resize policy is set to be FIXED, the preferred size
1389 // should be overrided by the target size. Otherwise the target
1390 // size should be overrided by the preferred size.
1392 if( dimension & Dimension::WIDTH )
1394 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1396 mRelayoutData->preferredSize.width = mTargetSize.width;
1398 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1400 mTargetSize.width = mRelayoutData->preferredSize.width;
1404 if( dimension & Dimension::HEIGHT )
1406 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1408 mRelayoutData->preferredSize.height = mTargetSize.height;
1410 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1412 mTargetSize.height = mRelayoutData->preferredSize.height;
1416 OnSetResizePolicy( policy, dimension );
1418 // Trigger relayout on this control
1422 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1424 if ( mRelayoutData )
1426 // If more than one dimension is requested, just return the first one found
1427 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1429 if( ( dimension & ( 1 << i ) ) )
1431 if( mRelayoutData->useAssignedSize[ i ] )
1433 return ResizePolicy::USE_ASSIGNED_SIZE;
1437 return mRelayoutData->resizePolicies[ i ];
1443 return ResizePolicy::DEFAULT;
1446 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1448 EnsureRelayoutData();
1450 mRelayoutData->sizeSetPolicy = policy;
1453 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1455 if ( mRelayoutData )
1457 return mRelayoutData->sizeSetPolicy;
1460 return DEFAULT_SIZE_SCALE_POLICY;
1463 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1465 EnsureRelayoutData();
1467 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1469 if( dimension & ( 1 << i ) )
1471 mRelayoutData->dimensionDependencies[ i ] = dependency;
1476 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1478 if ( mRelayoutData )
1480 // If more than one dimension is requested, just return the first one found
1481 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1483 if( ( dimension & ( 1 << i ) ) )
1485 return mRelayoutData->dimensionDependencies[ i ];
1490 return Dimension::ALL_DIMENSIONS; // Default
1493 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1495 // If relayout data has not been allocated yet and the client is requesting
1496 // to disable it, do nothing
1497 if( mRelayoutData || relayoutEnabled )
1499 EnsureRelayoutData();
1501 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1503 mRelayoutData->relayoutEnabled = relayoutEnabled;
1507 bool Actor::IsRelayoutEnabled() const
1509 // Assume that if relayout data has not been allocated yet then
1510 // relayout is disabled
1511 return mRelayoutData && mRelayoutData->relayoutEnabled;
1514 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1516 EnsureRelayoutData();
1518 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1520 if( dimension & ( 1 << i ) )
1522 mRelayoutData->dimensionDirty[ i ] = dirty;
1527 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1529 if ( mRelayoutData )
1531 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1533 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1543 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1545 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1548 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1550 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1553 unsigned int Actor::AddRenderer( Renderer& renderer )
1557 mRenderers = new RendererContainer;
1560 unsigned int index = mRenderers->size();
1561 RendererPtr rendererPtr = RendererPtr( &renderer );
1562 mRenderers->push_back( rendererPtr );
1563 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1567 unsigned int Actor::GetRendererCount() const
1569 unsigned int rendererCount(0);
1572 rendererCount = mRenderers->size();
1575 return rendererCount;
1578 RendererPtr Actor::GetRendererAt( unsigned int index )
1580 RendererPtr renderer;
1581 if( index < GetRendererCount() )
1583 renderer = ( *mRenderers )[ index ];
1589 void Actor::RemoveRenderer( Renderer& renderer )
1593 RendererIter end = mRenderers->end();
1594 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1596 if( (*iter).Get() == &renderer )
1598 mRenderers->erase( iter );
1599 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1606 void Actor::RemoveRenderer( unsigned int index )
1608 if( index < GetRendererCount() )
1610 RendererPtr renderer = ( *mRenderers )[ index ];
1611 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1612 mRenderers->erase( mRenderers->begin()+index );
1616 bool Actor::IsOverlay() const
1618 return ( DrawMode::OVERLAY_2D == mDrawMode );
1621 void Actor::SetDrawMode( DrawMode::Type drawMode )
1623 // this flag is not animatable so keep the value
1624 mDrawMode = drawMode;
1625 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1627 // mNode is being used in a separate thread; queue a message to set the value
1628 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1632 DrawMode::Type Actor::GetDrawMode() const
1637 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1639 // only valid when on-stage
1640 StagePtr stage = Stage::GetCurrent();
1641 if( stage && OnStage() )
1643 const RenderTaskList& taskList = stage->GetRenderTaskList();
1645 Vector2 converted( screenX, screenY );
1647 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1648 const int taskCount = taskList.GetTaskCount();
1649 for( int i = taskCount - 1; i >= 0; --i )
1651 Dali::RenderTask task = taskList.GetTask( i );
1652 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1654 // found a task where this conversion was ok so return
1662 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1664 bool retval = false;
1665 // only valid when on-stage
1668 CameraActor* camera = renderTask.GetCameraActor();
1672 renderTask.GetViewport( viewport );
1674 // need to translate coordinates to render tasks coordinate space
1675 Vector2 converted( screenX, screenY );
1676 if( renderTask.TranslateCoordinates( converted ) )
1678 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1685 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1687 // Early-out if mNode is NULL
1693 // Get the ModelView matrix
1695 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1697 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1698 Matrix invertedMvp( false/*don't init*/);
1699 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1700 bool success = invertedMvp.Invert();
1702 // Convert to GL coordinates
1703 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1708 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1715 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1721 if( XyPlaneIntersect( nearPos, farPos, local ) )
1723 Vector3 size = GetCurrentSize();
1724 localX = local.x + size.x * 0.5f;
1725 localY = local.y + size.y * 0.5f;
1736 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1739 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1741 Mathematical Formulation
1743 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1745 ( p - c ) dot ( p - c ) = r^2
1747 Given a ray with a point of origin 'o', and a direction vector 'd':
1749 ray(t) = o + td, t >= 0
1751 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1753 (o + td - c ) dot ( o + td - c ) = r^2
1755 To solve for t we first expand the above into a more recognisable quadratic equation form
1757 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1766 B = 2( o - c ) dot d
1767 C = ( o - c ) dot ( o - c ) - r^2
1769 which can be solved using a standard quadratic formula.
1771 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1773 Practical Simplification
1775 In a renderer, we often differentiate between world space and object space. In the object space
1776 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1777 into object space, the mathematical solution presented above can be simplified significantly.
1779 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1783 and we can find the t at which the (transformed) ray intersects the sphere by
1785 ( o + td ) dot ( o + td ) = r^2
1787 According to the reasoning above, we expand the above quadratic equation into the general form
1791 which now has coefficients:
1798 // Early out if mNode is NULL
1804 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1806 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1807 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1808 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1810 // Compute the radius is not needed, square radius it's enough.
1811 const Vector3& size( mNode->GetSize( bufferIndex ) );
1813 // Scale the sphere.
1814 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1816 const float width = size.width * scale.width;
1817 const float height = size.height * scale.height;
1819 float squareSphereRadius = 0.5f * ( width * width + height * height );
1821 float a = rayDir.Dot( rayDir ); // a
1822 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1823 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1825 return ( b2 * b2 - a * c ) >= 0.f;
1828 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1832 if( OnStage() && NULL != mNode )
1834 // Transforms the ray to the local reference system.
1835 // Calculate the inverse of Model matrix
1836 Matrix invModelMatrix( false/*don't init*/);
1838 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1839 invModelMatrix = mNode->GetWorldMatrix(0);
1840 invModelMatrix.Invert();
1842 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1843 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1845 // Test with the actor's XY plane (Normal = 0 0 1 1).
1847 float a = -rayOriginLocal.z;
1848 float b = rayDirLocal.z;
1850 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1852 // Ray travels distance * rayDirLocal to intersect with plane.
1855 const Vector3& size = mNode->GetSize( bufferIndex );
1857 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1858 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1860 // Test with the actor's geometry.
1861 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1868 void Actor::SetLeaveRequired( bool required )
1870 mLeaveRequired = required;
1873 bool Actor::GetLeaveRequired() const
1875 return mLeaveRequired;
1878 void Actor::SetKeyboardFocusable( bool focusable )
1880 mKeyboardFocusable = focusable;
1883 bool Actor::IsKeyboardFocusable() const
1885 return mKeyboardFocusable;
1888 bool Actor::GetTouchRequired() const
1890 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1893 bool Actor::GetHoverRequired() const
1895 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1898 bool Actor::GetWheelEventRequired() const
1900 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1903 bool Actor::IsHittable() const
1905 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1908 ActorGestureData& Actor::GetGestureData()
1910 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1911 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1912 if( NULL == mGestureData )
1914 mGestureData = new ActorGestureData;
1916 return *mGestureData;
1919 bool Actor::IsGestureRequred( Gesture::Type type ) const
1921 return mGestureData && mGestureData->IsGestureRequred( type );
1924 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1926 bool consumed = false;
1928 if( !mTouchSignal.Empty() )
1930 Dali::Actor handle( this );
1931 consumed = mTouchSignal.Emit( handle, touch );
1934 if( !mTouchedSignal.Empty() )
1936 Dali::Actor handle( this );
1937 consumed |= mTouchedSignal.Emit( handle, event );
1942 // Notification for derived classes
1943 consumed = OnTouchEvent( event ); // TODO
1949 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1951 bool consumed = false;
1953 if( !mHoveredSignal.Empty() )
1955 Dali::Actor handle( this );
1956 consumed = mHoveredSignal.Emit( handle, event );
1961 // Notification for derived classes
1962 consumed = OnHoverEvent( event );
1968 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1970 bool consumed = false;
1972 if( !mWheelEventSignal.Empty() )
1974 Dali::Actor handle( this );
1975 consumed = mWheelEventSignal.Emit( handle, event );
1980 // Notification for derived classes
1981 consumed = OnWheelEvent( event );
1987 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1989 if( ! mVisibilityChangedSignal.Empty() )
1991 Dali::Actor handle( this );
1992 mVisibilityChangedSignal.Emit( handle, visible, type );
1996 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1998 if( ! mLayoutDirectionChangedSignal.Empty() )
2000 Dali::Actor handle( this );
2001 mLayoutDirectionChangedSignal.Emit( handle, type );
2005 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
2007 return mTouchedSignal;
2010 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
2012 return mTouchSignal;
2015 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2017 return mHoveredSignal;
2020 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
2022 return mWheelEventSignal;
2025 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2027 return mOnStageSignal;
2030 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2032 return mOffStageSignal;
2035 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2037 return mOnRelayoutSignal;
2040 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
2042 return mVisibilityChangedSignal;
2045 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
2047 return mLayoutDirectionChangedSignal;
2050 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2052 bool connected( true );
2053 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2055 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2057 actor->TouchedSignal().Connect( tracker, functor );
2059 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2061 actor->HoveredSignal().Connect( tracker, functor );
2063 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2065 actor->WheelEventSignal().Connect( tracker, functor );
2067 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2069 actor->OnStageSignal().Connect( tracker, functor );
2071 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2073 actor->OffStageSignal().Connect( tracker, functor );
2075 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2077 actor->OnRelayoutSignal().Connect( tracker, functor );
2079 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2081 actor->TouchSignal().Connect( tracker, functor );
2085 // signalName does not match any signal
2092 Actor::Actor( DerivedType derivedType )
2097 mParentOrigin( NULL ),
2098 mAnchorPoint( NULL ),
2099 mRelayoutData( NULL ),
2100 mGestureData( NULL ),
2101 mTargetOrientation( Quaternion::IDENTITY ),
2102 mTargetColor( Color::WHITE ),
2103 mTargetSize( Vector3::ZERO ),
2104 mTargetPosition( Vector3::ZERO ),
2105 mTargetScale( Vector3::ONE ),
2107 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2110 mIsRoot( ROOT_LAYER == derivedType ),
2111 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2112 mIsOnStage( false ),
2114 mLeaveRequired( false ),
2115 mKeyboardFocusable( false ),
2116 mDerivedRequiresTouch( false ),
2117 mDerivedRequiresHover( false ),
2118 mDerivedRequiresWheelEvent( false ),
2119 mOnStageSignalled( false ),
2120 mInsideOnSizeSet( false ),
2121 mInheritPosition( true ),
2122 mInheritOrientation( true ),
2123 mInheritScale( true ),
2124 mPositionUsesAnchorPoint( true ),
2126 mInheritLayoutDirection( true ),
2127 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2128 mDrawMode( DrawMode::NORMAL ),
2129 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2130 mColorMode( Node::DEFAULT_COLOR_MODE ),
2131 mClippingMode( ClippingMode::DISABLED )
2135 void Actor::Initialize()
2137 // Node creation, keep raw-pointer to Node for messaging
2138 mNode = CreateNode();
2139 OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
2140 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
2144 GetEventThreadServices().RegisterObject( this );
2149 // Remove mParent pointers from children even if we're destroying core,
2150 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2153 ActorConstIter endIter = mChildren->end();
2154 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2156 (*iter)->SetParent( NULL );
2162 // Guard to allow handle destruction after Core has been destroyed
2163 if( EventThreadServices::IsCoreRunning() )
2167 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2168 mNode = NULL; // Node is about to be destroyed
2171 GetEventThreadServices().UnregisterObject( this );
2174 // Cleanup optional gesture data
2175 delete mGestureData;
2177 // Cleanup optional parent origin and anchor
2178 delete mParentOrigin;
2179 delete mAnchorPoint;
2181 // Delete optional relayout data
2184 delete mRelayoutData;
2188 void Actor::ConnectToStage( unsigned int parentDepth )
2190 // This container is used instead of walking the Actor hierarchy.
2191 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2192 ActorContainer connectionList;
2194 StagePtr stage = Stage::GetCurrent();
2197 stage->RequestRebuildDepthTree();
2200 // This stage is atomic i.e. not interrupted by user callbacks.
2201 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2203 // Notify applications about the newly connected actors.
2204 const ActorIter endIter = connectionList.end();
2205 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2207 (*iter)->NotifyStageConnection();
2213 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2215 DALI_ASSERT_ALWAYS( !OnStage() );
2220 ConnectToSceneGraph();
2222 // Notification for internal derived classes
2223 OnStageConnectionInternal();
2225 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2226 connectionList.push_back( ActorPtr( this ) );
2228 // Recursively connect children
2231 ActorConstIter endIter = mChildren->end();
2232 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2234 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2240 * This method is called when the Actor is connected to the Stage.
2241 * The parent must have added its Node to the scene-graph.
2242 * The child must connect its Node to the parent's Node.
2243 * This is recursive; the child calls ConnectToStage() for its children.
2245 void Actor::ConnectToSceneGraph()
2247 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2251 // Reparent Node in next Update
2252 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2255 // Request relayout on all actors that are added to the scenegraph
2258 // Notification for Object::Observers
2262 void Actor::NotifyStageConnection()
2264 // Actors can be removed (in a callback), before the on-stage stage is reported.
2265 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2266 if( OnStage() && !mOnStageSignalled )
2268 // Notification for external (CustomActor) derived classes
2269 OnStageConnectionExternal( mDepth );
2271 if( !mOnStageSignal.Empty() )
2273 Dali::Actor handle( this );
2274 mOnStageSignal.Emit( handle );
2277 // Guard against Remove during callbacks
2280 mOnStageSignalled = true; // signal required next time Actor is removed
2285 void Actor::DisconnectFromStage()
2287 // This container is used instead of walking the Actor hierachy.
2288 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2289 ActorContainer disconnectionList;
2291 StagePtr stage = Stage::GetCurrent();
2294 stage->RequestRebuildDepthTree();
2297 // This stage is atomic i.e. not interrupted by user callbacks
2298 RecursiveDisconnectFromStage( disconnectionList );
2300 // Notify applications about the newly disconnected actors.
2301 const ActorIter endIter = disconnectionList.end();
2302 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2304 (*iter)->NotifyStageDisconnection();
2308 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2310 DALI_ASSERT_ALWAYS( OnStage() );
2312 // Recursively disconnect children
2315 ActorConstIter endIter = mChildren->end();
2316 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2318 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2322 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2323 disconnectionList.push_back( ActorPtr( this ) );
2325 // Notification for internal derived classes
2326 OnStageDisconnectionInternal();
2328 DisconnectFromSceneGraph();
2334 * This method is called by an actor or its parent, before a node removal message is sent.
2335 * This is recursive; the child calls DisconnectFromStage() for its children.
2337 void Actor::DisconnectFromSceneGraph()
2339 // Notification for Object::Observers
2340 OnSceneObjectRemove();
2343 void Actor::NotifyStageDisconnection()
2345 // Actors can be added (in a callback), before the off-stage state is reported.
2346 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2347 // only do this step if there is a stage, i.e. Core is not being shut down
2348 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2350 // Notification for external (CustomeActor) derived classes
2351 OnStageDisconnectionExternal();
2353 if( !mOffStageSignal.Empty() )
2355 Dali::Actor handle( this );
2356 mOffStageSignal.Emit( handle );
2359 // Guard against Add during callbacks
2362 mOnStageSignalled = false; // signal required next time Actor is added
2367 bool Actor::IsNodeConnected() const
2369 bool connected( false );
2371 if( OnStage() && ( NULL != mNode ) )
2373 if( IsRoot() || mNode->GetParent() )
2382 // This method initiates traversal of the actor tree using depth-first
2383 // traversal to set a depth index based on traversal order. It sends a
2384 // single message to update manager to update all the actor's nodes in
2385 // this tree with the depth index. The sceneGraphNodeDepths vector's
2386 // elements are ordered by depth, and could be used to reduce sorting
2387 // in the update thread.
2388 void Actor::RebuildDepthTree()
2390 DALI_LOG_TIMER_START(depthTimer);
2392 // Vector of scene-graph nodes and their depths to send to UpdateManager
2393 // in a single message
2394 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2397 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2399 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2400 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2403 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
2405 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2406 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
2408 // Create/add to children of this node
2411 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2413 Actor* childActor = (*it).Get();
2415 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2420 unsigned int Actor::GetDefaultPropertyCount() const
2422 return DEFAULT_PROPERTY_COUNT;
2425 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2427 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2429 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2431 indices.PushBack( i );
2435 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2437 if( index < DEFAULT_PROPERTY_COUNT )
2439 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2445 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2447 Property::Index index = Property::INVALID_INDEX;
2449 // Look for name in default properties
2450 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2452 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2453 if( 0 == name.compare( property->name ) )
2463 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2465 if( index < DEFAULT_PROPERTY_COUNT )
2467 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2473 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2475 if( index < DEFAULT_PROPERTY_COUNT )
2477 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2483 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2485 if( index < DEFAULT_PROPERTY_COUNT )
2487 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2493 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2495 if( index < DEFAULT_PROPERTY_COUNT )
2497 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2500 // index out of range...return Property::NONE
2501 return Property::NONE;
2504 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2508 case Dali::Actor::Property::PARENT_ORIGIN:
2510 Property::Type type = property.GetType();
2511 if( type == Property::VECTOR3 )
2513 SetParentOrigin( property.Get< Vector3 >() );
2515 else if ( type == Property::STRING )
2517 std::string parentOriginString;
2518 property.Get( parentOriginString );
2519 Vector3 parentOrigin;
2520 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2522 SetParentOrigin( parentOrigin );
2528 case Dali::Actor::Property::PARENT_ORIGIN_X:
2530 SetParentOriginX( property.Get< float >() );
2534 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2536 SetParentOriginY( property.Get< float >() );
2540 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2542 SetParentOriginZ( property.Get< float >() );
2546 case Dali::Actor::Property::ANCHOR_POINT:
2548 Property::Type type = property.GetType();
2549 if( type == Property::VECTOR3 )
2551 SetAnchorPoint( property.Get< Vector3 >() );
2553 else if ( type == Property::STRING )
2555 std::string anchorPointString;
2556 property.Get( anchorPointString );
2558 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2560 SetAnchorPoint( anchor );
2566 case Dali::Actor::Property::ANCHOR_POINT_X:
2568 SetAnchorPointX( property.Get< float >() );
2572 case Dali::Actor::Property::ANCHOR_POINT_Y:
2574 SetAnchorPointY( property.Get< float >() );
2578 case Dali::Actor::Property::ANCHOR_POINT_Z:
2580 SetAnchorPointZ( property.Get< float >() );
2584 case Dali::Actor::Property::SIZE:
2586 SetSize( property.Get< Vector3 >() );
2590 case Dali::Actor::Property::SIZE_WIDTH:
2592 SetWidth( property.Get< float >() );
2596 case Dali::Actor::Property::SIZE_HEIGHT:
2598 SetHeight( property.Get< float >() );
2602 case Dali::Actor::Property::SIZE_DEPTH:
2604 SetDepth( property.Get< float >() );
2608 case Dali::Actor::Property::POSITION:
2610 SetPosition( property.Get< Vector3 >() );
2614 case Dali::Actor::Property::POSITION_X:
2616 SetX( property.Get< float >() );
2620 case Dali::Actor::Property::POSITION_Y:
2622 SetY( property.Get< float >() );
2626 case Dali::Actor::Property::POSITION_Z:
2628 SetZ( property.Get< float >() );
2632 case Dali::Actor::Property::ORIENTATION:
2634 SetOrientation( property.Get< Quaternion >() );
2638 case Dali::Actor::Property::SCALE:
2640 SetScale( property.Get< Vector3 >() );
2644 case Dali::Actor::Property::SCALE_X:
2646 SetScaleX( property.Get< float >() );
2650 case Dali::Actor::Property::SCALE_Y:
2652 SetScaleY( property.Get< float >() );
2656 case Dali::Actor::Property::SCALE_Z:
2658 SetScaleZ( property.Get< float >() );
2662 case Dali::Actor::Property::VISIBLE:
2664 SetVisible( property.Get< bool >() );
2668 case Dali::Actor::Property::COLOR:
2670 SetColor( property.Get< Vector4 >() );
2674 case Dali::Actor::Property::COLOR_RED:
2676 SetColorRed( property.Get< float >() );
2680 case Dali::Actor::Property::COLOR_GREEN:
2682 SetColorGreen( property.Get< float >() );
2686 case Dali::Actor::Property::COLOR_BLUE:
2688 SetColorBlue( property.Get< float >() );
2692 case Dali::Actor::Property::COLOR_ALPHA:
2693 case Dali::DevelActor::Property::OPACITY:
2696 if( property.Get( value ) )
2698 SetOpacity( value );
2703 case Dali::Actor::Property::NAME:
2705 SetName( property.Get< std::string >() );
2709 case Dali::Actor::Property::SENSITIVE:
2711 SetSensitive( property.Get< bool >() );
2715 case Dali::Actor::Property::LEAVE_REQUIRED:
2717 SetLeaveRequired( property.Get< bool >() );
2721 case Dali::Actor::Property::INHERIT_POSITION:
2723 SetInheritPosition( property.Get< bool >() );
2727 case Dali::Actor::Property::INHERIT_ORIENTATION:
2729 SetInheritOrientation( property.Get< bool >() );
2733 case Dali::Actor::Property::INHERIT_SCALE:
2735 SetInheritScale( property.Get< bool >() );
2739 case Dali::Actor::Property::COLOR_MODE:
2741 ColorMode mode = mColorMode;
2742 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2744 SetColorMode( mode );
2749 case Dali::Actor::Property::POSITION_INHERITANCE:
2751 PositionInheritanceMode mode = mPositionInheritanceMode;
2752 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2754 SetPositionInheritanceMode( mode );
2759 case Dali::Actor::Property::DRAW_MODE:
2761 DrawMode::Type mode = mDrawMode;
2762 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2764 SetDrawMode( mode );
2769 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2771 SetSizeModeFactor( property.Get< Vector3 >() );
2775 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2777 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2778 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2780 SetResizePolicy( type, Dimension::WIDTH );
2785 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2787 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2788 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2790 SetResizePolicy( type, Dimension::HEIGHT );
2795 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2797 SizeScalePolicy::Type type;
2798 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2800 SetSizeScalePolicy( type );
2805 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2807 if( property.Get< bool >() )
2809 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2814 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2816 if( property.Get< bool >() )
2818 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2823 case Dali::Actor::Property::PADDING:
2825 Vector4 padding = property.Get< Vector4 >();
2826 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2827 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2831 case Dali::Actor::Property::MINIMUM_SIZE:
2833 Vector2 size = property.Get< Vector2 >();
2834 SetMinimumSize( size.x, Dimension::WIDTH );
2835 SetMinimumSize( size.y, Dimension::HEIGHT );
2839 case Dali::Actor::Property::MAXIMUM_SIZE:
2841 Vector2 size = property.Get< Vector2 >();
2842 SetMaximumSize( size.x, Dimension::WIDTH );
2843 SetMaximumSize( size.y, Dimension::HEIGHT );
2847 case Dali::DevelActor::Property::SIBLING_ORDER:
2851 if( property.Get( value ) )
2853 SetSiblingOrder( value );
2858 case Dali::Actor::Property::CLIPPING_MODE:
2860 ClippingMode::Type convertedValue = mClippingMode;
2861 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2863 mClippingMode = convertedValue;
2866 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2872 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2875 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2877 mPositionUsesAnchorPoint = value;
2880 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2886 case Dali::Actor::Property::LAYOUT_DIRECTION:
2888 Dali::LayoutDirection::Type direction = mLayoutDirection;
2889 mInheritLayoutDirection = false;
2891 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2893 InheritLayoutDirectionRecursively( this, direction, true );
2898 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2901 if( property.Get( value ) )
2903 SetInheritLayoutDirection( value );
2910 // this can happen in the case of a non-animatable default property so just do nothing
2916 // TODO: This method needs to be removed
2917 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2919 switch( entry.GetType() )
2921 case Property::BOOLEAN:
2923 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2924 DALI_ASSERT_DEBUG( NULL != property );
2926 // property is being used in a separate thread; queue a message to set the property
2927 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2932 case Property::INTEGER:
2934 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2935 DALI_ASSERT_DEBUG( NULL != property );
2937 // property is being used in a separate thread; queue a message to set the property
2938 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2943 case Property::FLOAT:
2945 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2946 DALI_ASSERT_DEBUG( NULL != property );
2948 // property is being used in a separate thread; queue a message to set the property
2949 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2954 case Property::VECTOR2:
2956 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2957 DALI_ASSERT_DEBUG( NULL != property );
2959 // property is being used in a separate thread; queue a message to set the property
2960 if(entry.componentIndex == 0)
2962 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2964 else if(entry.componentIndex == 1)
2966 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2970 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2976 case Property::VECTOR3:
2978 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2979 DALI_ASSERT_DEBUG( NULL != property );
2981 // property is being used in a separate thread; queue a message to set the property
2982 if(entry.componentIndex == 0)
2984 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2986 else if(entry.componentIndex == 1)
2988 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2990 else if(entry.componentIndex == 2)
2992 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2996 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
3002 case Property::VECTOR4:
3004 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
3005 DALI_ASSERT_DEBUG( NULL != property );
3007 // property is being used in a separate thread; queue a message to set the property
3008 if(entry.componentIndex == 0)
3010 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3012 else if(entry.componentIndex == 1)
3014 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3016 else if(entry.componentIndex == 2)
3018 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3020 else if(entry.componentIndex == 3)
3022 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3026 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3032 case Property::ROTATION:
3034 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3035 DALI_ASSERT_DEBUG( NULL != property );
3037 // property is being used in a separate thread; queue a message to set the property
3038 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
3043 case Property::MATRIX:
3045 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3046 DALI_ASSERT_DEBUG( NULL != property );
3048 // property is being used in a separate thread; queue a message to set the property
3049 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
3054 case Property::MATRIX3:
3056 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3057 DALI_ASSERT_DEBUG( NULL != property );
3059 // property is being used in a separate thread; queue a message to set the property
3060 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
3067 // nothing to do for other types
3072 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3074 Property::Value value;
3076 if( ! GetCachedPropertyValue( index, value ) )
3078 // If property value is not stored in the event-side, then it must be a scene-graph only property
3079 GetCurrentPropertyValue( index, value );
3085 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3087 Property::Value value;
3089 if( ! GetCurrentPropertyValue( index, value ) )
3091 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3092 GetCachedPropertyValue( index, value );
3098 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3100 switch( animationType )
3103 case Animation::BETWEEN:
3107 case Dali::Actor::Property::SIZE:
3109 if( value.Get( mTargetSize ) )
3111 // Notify deriving classes
3112 OnSizeAnimation( animation, mTargetSize );
3117 case Dali::Actor::Property::SIZE_WIDTH:
3119 if( value.Get( mTargetSize.width ) )
3121 // Notify deriving classes
3122 OnSizeAnimation( animation, mTargetSize );
3127 case Dali::Actor::Property::SIZE_HEIGHT:
3129 if( value.Get( mTargetSize.height ) )
3131 // Notify deriving classes
3132 OnSizeAnimation( animation, mTargetSize );
3137 case Dali::Actor::Property::SIZE_DEPTH:
3139 if( value.Get( mTargetSize.depth ) )
3141 // Notify deriving classes
3142 OnSizeAnimation( animation, mTargetSize );
3147 case Dali::Actor::Property::POSITION:
3149 value.Get( mTargetPosition );
3153 case Dali::Actor::Property::POSITION_X:
3155 value.Get( mTargetPosition.x );
3159 case Dali::Actor::Property::POSITION_Y:
3161 value.Get( mTargetPosition.y );
3165 case Dali::Actor::Property::POSITION_Z:
3167 value.Get( mTargetPosition.z );
3171 case Dali::Actor::Property::ORIENTATION:
3173 value.Get( mTargetOrientation );
3177 case Dali::Actor::Property::SCALE:
3179 value.Get( mTargetScale );
3183 case Dali::Actor::Property::SCALE_X:
3185 value.Get( mTargetScale.x );
3189 case Dali::Actor::Property::SCALE_Y:
3191 value.Get( mTargetScale.y );
3195 case Dali::Actor::Property::SCALE_Z:
3197 value.Get( mTargetScale.z );
3201 case Dali::Actor::Property::VISIBLE:
3203 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3207 case Dali::Actor::Property::COLOR:
3209 value.Get( mTargetColor );
3213 case Dali::Actor::Property::COLOR_RED:
3215 value.Get( mTargetColor.r );
3219 case Dali::Actor::Property::COLOR_GREEN:
3221 value.Get( mTargetColor.g );
3225 case Dali::Actor::Property::COLOR_BLUE:
3227 value.Get( mTargetColor.b );
3231 case Dali::Actor::Property::COLOR_ALPHA:
3232 case Dali::DevelActor::Property::OPACITY:
3234 value.Get( mTargetColor.a );
3240 // Not an animatable property. Do nothing.
3251 case Dali::Actor::Property::SIZE:
3253 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3255 // Notify deriving classes
3256 OnSizeAnimation( animation, mTargetSize );
3261 case Dali::Actor::Property::SIZE_WIDTH:
3263 if( AdjustValue< float >( mTargetSize.width, value ) )
3265 // Notify deriving classes
3266 OnSizeAnimation( animation, mTargetSize );
3271 case Dali::Actor::Property::SIZE_HEIGHT:
3273 if( AdjustValue< float >( mTargetSize.height, value ) )
3275 // Notify deriving classes
3276 OnSizeAnimation( animation, mTargetSize );
3281 case Dali::Actor::Property::SIZE_DEPTH:
3283 if( AdjustValue< float >( mTargetSize.depth, value ) )
3285 // Notify deriving classes
3286 OnSizeAnimation( animation, mTargetSize );
3291 case Dali::Actor::Property::POSITION:
3293 AdjustValue< Vector3 >( mTargetPosition, value );
3297 case Dali::Actor::Property::POSITION_X:
3299 AdjustValue< float >( mTargetPosition.x, value );
3303 case Dali::Actor::Property::POSITION_Y:
3305 AdjustValue< float >( mTargetPosition.y, value );
3309 case Dali::Actor::Property::POSITION_Z:
3311 AdjustValue< float >( mTargetPosition.z, value );
3315 case Dali::Actor::Property::ORIENTATION:
3317 Quaternion relativeValue;
3318 if( value.Get( relativeValue ) )
3320 mTargetOrientation *= relativeValue;
3325 case Dali::Actor::Property::SCALE:
3327 AdjustValue< Vector3 >( mTargetScale, value );
3331 case Dali::Actor::Property::SCALE_X:
3333 AdjustValue< float >( mTargetScale.x, value );
3337 case Dali::Actor::Property::SCALE_Y:
3339 AdjustValue< float >( mTargetScale.y, value );
3343 case Dali::Actor::Property::SCALE_Z:
3345 AdjustValue< float >( mTargetScale.z, value );
3349 case Dali::Actor::Property::VISIBLE:
3351 bool relativeValue = false;
3352 if( value.Get( relativeValue ) )
3354 bool visible = mVisible || relativeValue;
3355 SetVisibleInternal( visible, SendMessage::FALSE );
3360 case Dali::Actor::Property::COLOR:
3362 AdjustValue< Vector4 >( mTargetColor, value );
3366 case Dali::Actor::Property::COLOR_RED:
3368 AdjustValue< float >( mTargetColor.r, value );
3372 case Dali::Actor::Property::COLOR_GREEN:
3374 AdjustValue< float >( mTargetColor.g, value );
3378 case Dali::Actor::Property::COLOR_BLUE:
3380 AdjustValue< float >( mTargetColor.b, value );
3384 case Dali::Actor::Property::COLOR_ALPHA:
3385 case Dali::DevelActor::Property::OPACITY:
3387 AdjustValue< float >( mTargetColor.a, value );
3393 // Not an animatable property. Do nothing.
3402 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3407 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3409 // This method should only return an object connected to the scene-graph
3410 return OnStage() ? mNode : NULL;
3413 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3415 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3417 const PropertyBase* property( NULL );
3419 // This method should only return a property of an object connected to the scene-graph
3425 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3427 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3428 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3430 property = animatable->GetSceneGraphProperty();
3432 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3433 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3435 CustomPropertyMetadata* custom = FindCustomProperty( index );
3436 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3438 property = custom->GetSceneGraphProperty();
3440 else if( NULL != mNode )
3444 case Dali::Actor::Property::SIZE:
3445 property = &mNode->mSize;
3448 case Dali::Actor::Property::SIZE_WIDTH:
3449 property = &mNode->mSize;
3452 case Dali::Actor::Property::SIZE_HEIGHT:
3453 property = &mNode->mSize;
3456 case Dali::Actor::Property::SIZE_DEPTH:
3457 property = &mNode->mSize;
3460 case Dali::Actor::Property::POSITION:
3461 property = &mNode->mPosition;
3464 case Dali::Actor::Property::POSITION_X:
3465 property = &mNode->mPosition;
3468 case Dali::Actor::Property::POSITION_Y:
3469 property = &mNode->mPosition;
3472 case Dali::Actor::Property::POSITION_Z:
3473 property = &mNode->mPosition;
3476 case Dali::Actor::Property::ORIENTATION:
3477 property = &mNode->mOrientation;
3480 case Dali::Actor::Property::SCALE:
3481 property = &mNode->mScale;
3484 case Dali::Actor::Property::SCALE_X:
3485 property = &mNode->mScale;
3488 case Dali::Actor::Property::SCALE_Y:
3489 property = &mNode->mScale;
3492 case Dali::Actor::Property::SCALE_Z:
3493 property = &mNode->mScale;
3496 case Dali::Actor::Property::VISIBLE:
3497 property = &mNode->mVisible;
3500 case Dali::Actor::Property::COLOR:
3501 property = &mNode->mColor;
3504 case Dali::Actor::Property::COLOR_RED:
3505 property = &mNode->mColor;
3508 case Dali::Actor::Property::COLOR_GREEN:
3509 property = &mNode->mColor;
3512 case Dali::Actor::Property::COLOR_BLUE:
3513 property = &mNode->mColor;
3516 case Dali::Actor::Property::COLOR_ALPHA:
3517 case Dali::DevelActor::Property::OPACITY:
3518 property = &mNode->mColor;
3529 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3531 const PropertyInputImpl* property( NULL );
3533 // This method should only return a property of an object connected to the scene-graph
3539 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3541 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3542 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3544 property = animatable->GetSceneGraphProperty();
3546 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3547 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3549 CustomPropertyMetadata* custom = FindCustomProperty( index );
3550 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3551 property = custom->GetSceneGraphProperty();
3553 else if( NULL != mNode )
3557 case Dali::Actor::Property::PARENT_ORIGIN:
3558 property = &mNode->mParentOrigin;
3561 case Dali::Actor::Property::PARENT_ORIGIN_X:
3562 property = &mNode->mParentOrigin;
3565 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3566 property = &mNode->mParentOrigin;
3569 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3570 property = &mNode->mParentOrigin;
3573 case Dali::Actor::Property::ANCHOR_POINT:
3574 property = &mNode->mAnchorPoint;
3577 case Dali::Actor::Property::ANCHOR_POINT_X:
3578 property = &mNode->mAnchorPoint;
3581 case Dali::Actor::Property::ANCHOR_POINT_Y:
3582 property = &mNode->mAnchorPoint;
3585 case Dali::Actor::Property::ANCHOR_POINT_Z:
3586 property = &mNode->mAnchorPoint;
3589 case Dali::Actor::Property::SIZE:
3590 property = &mNode->mSize;
3593 case Dali::Actor::Property::SIZE_WIDTH:
3594 property = &mNode->mSize;
3597 case Dali::Actor::Property::SIZE_HEIGHT:
3598 property = &mNode->mSize;
3601 case Dali::Actor::Property::SIZE_DEPTH:
3602 property = &mNode->mSize;
3605 case Dali::Actor::Property::POSITION:
3606 property = &mNode->mPosition;
3609 case Dali::Actor::Property::POSITION_X:
3610 property = &mNode->mPosition;
3613 case Dali::Actor::Property::POSITION_Y:
3614 property = &mNode->mPosition;
3617 case Dali::Actor::Property::POSITION_Z:
3618 property = &mNode->mPosition;
3621 case Dali::Actor::Property::WORLD_POSITION:
3622 property = &mNode->mWorldPosition;
3625 case Dali::Actor::Property::WORLD_POSITION_X:
3626 property = &mNode->mWorldPosition;
3629 case Dali::Actor::Property::WORLD_POSITION_Y:
3630 property = &mNode->mWorldPosition;
3633 case Dali::Actor::Property::WORLD_POSITION_Z:
3634 property = &mNode->mWorldPosition;
3637 case Dali::Actor::Property::ORIENTATION:
3638 property = &mNode->mOrientation;
3641 case Dali::Actor::Property::WORLD_ORIENTATION:
3642 property = &mNode->mWorldOrientation;
3645 case Dali::Actor::Property::SCALE:
3646 property = &mNode->mScale;
3649 case Dali::Actor::Property::SCALE_X:
3650 property = &mNode->mScale;
3653 case Dali::Actor::Property::SCALE_Y:
3654 property = &mNode->mScale;
3657 case Dali::Actor::Property::SCALE_Z:
3658 property = &mNode->mScale;
3661 case Dali::Actor::Property::WORLD_SCALE:
3662 property = &mNode->mWorldScale;
3665 case Dali::Actor::Property::VISIBLE:
3666 property = &mNode->mVisible;
3669 case Dali::Actor::Property::COLOR:
3670 property = &mNode->mColor;
3673 case Dali::Actor::Property::COLOR_RED:
3674 property = &mNode->mColor;
3677 case Dali::Actor::Property::COLOR_GREEN:
3678 property = &mNode->mColor;
3681 case Dali::Actor::Property::COLOR_BLUE:
3682 property = &mNode->mColor;
3685 case Dali::Actor::Property::COLOR_ALPHA:
3686 case Dali::DevelActor::Property::OPACITY:
3688 property = &mNode->mColor;
3692 case Dali::Actor::Property::WORLD_COLOR:
3693 property = &mNode->mWorldColor;
3696 case Dali::Actor::Property::WORLD_MATRIX:
3697 property = &mNode->mWorldMatrix;
3708 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3710 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3712 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3714 // check whether the animatable property is registered already, if not then register one.
3715 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3716 if( animatableProperty )
3718 componentIndex = animatableProperty->componentIndex;
3725 case Dali::Actor::Property::PARENT_ORIGIN_X:
3726 case Dali::Actor::Property::ANCHOR_POINT_X:
3727 case Dali::Actor::Property::SIZE_WIDTH:
3728 case Dali::Actor::Property::POSITION_X:
3729 case Dali::Actor::Property::WORLD_POSITION_X:
3730 case Dali::Actor::Property::SCALE_X:
3731 case Dali::Actor::Property::COLOR_RED:
3737 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3738 case Dali::Actor::Property::ANCHOR_POINT_Y:
3739 case Dali::Actor::Property::SIZE_HEIGHT:
3740 case Dali::Actor::Property::POSITION_Y:
3741 case Dali::Actor::Property::WORLD_POSITION_Y:
3742 case Dali::Actor::Property::SCALE_Y:
3743 case Dali::Actor::Property::COLOR_GREEN:
3749 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3750 case Dali::Actor::Property::ANCHOR_POINT_Z:
3751 case Dali::Actor::Property::SIZE_DEPTH:
3752 case Dali::Actor::Property::POSITION_Z:
3753 case Dali::Actor::Property::WORLD_POSITION_Z:
3754 case Dali::Actor::Property::SCALE_Z:
3755 case Dali::Actor::Property::COLOR_BLUE:
3761 case Dali::Actor::Property::COLOR_ALPHA:
3762 case Dali::DevelActor::Property::OPACITY:
3776 return componentIndex;
3779 void Actor::SetParent( Actor* parent )
3783 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3787 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3790 // Instruct each actor to create a corresponding node in the scene graph
3791 ConnectToStage( parent->GetHierarchyDepth() );
3794 // Resolve the name and index for the child properties if any
3795 ResolveChildProperties();
3797 else // parent being set to NULL
3799 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3803 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3806 DALI_ASSERT_ALWAYS( mNode != NULL );
3810 // Disconnect the Node & its children from the scene-graph.
3811 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3814 // Instruct each actor to discard pointers to the scene-graph
3815 DisconnectFromStage();
3820 SceneGraph::Node* Actor::CreateNode() const
3825 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3828 Actor* actor = dynamic_cast< Actor* >( object );
3832 if( 0 == actionName.compare( ACTION_SHOW ) )
3834 actor->SetVisible( true );
3837 else if( 0 == actionName.compare( ACTION_HIDE ) )
3839 actor->SetVisible( false );
3847 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3849 bool valueSet = true;
3853 case Dali::Actor::Property::PARENT_ORIGIN:
3855 value = GetCurrentParentOrigin();
3859 case Dali::Actor::Property::PARENT_ORIGIN_X:
3861 value = GetCurrentParentOrigin().x;
3865 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3867 value = GetCurrentParentOrigin().y;
3871 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3873 value = GetCurrentParentOrigin().z;
3877 case Dali::Actor::Property::ANCHOR_POINT:
3879 value = GetCurrentAnchorPoint();
3883 case Dali::Actor::Property::ANCHOR_POINT_X:
3885 value = GetCurrentAnchorPoint().x;
3889 case Dali::Actor::Property::ANCHOR_POINT_Y:
3891 value = GetCurrentAnchorPoint().y;
3895 case Dali::Actor::Property::ANCHOR_POINT_Z:
3897 value = GetCurrentAnchorPoint().z;
3901 case Dali::Actor::Property::SIZE:
3903 value = GetTargetSize();
3907 case Dali::Actor::Property::SIZE_WIDTH:
3909 value = GetTargetSize().width;
3913 case Dali::Actor::Property::SIZE_HEIGHT:
3915 value = GetTargetSize().height;
3919 case Dali::Actor::Property::SIZE_DEPTH:
3921 value = GetTargetSize().depth;
3925 case Dali::Actor::Property::POSITION:
3927 value = GetTargetPosition();
3931 case Dali::Actor::Property::POSITION_X:
3933 value = GetTargetPosition().x;
3937 case Dali::Actor::Property::POSITION_Y:
3939 value = GetTargetPosition().y;
3943 case Dali::Actor::Property::POSITION_Z:
3945 value = GetTargetPosition().z;
3949 case Dali::Actor::Property::ORIENTATION:
3951 value = mTargetOrientation;
3955 case Dali::Actor::Property::SCALE:
3957 value = mTargetScale;
3961 case Dali::Actor::Property::SCALE_X:
3963 value = mTargetScale.x;
3967 case Dali::Actor::Property::SCALE_Y:
3969 value = mTargetScale.y;
3973 case Dali::Actor::Property::SCALE_Z:
3975 value = mTargetScale.z;
3979 case Dali::Actor::Property::VISIBLE:
3985 case Dali::Actor::Property::COLOR:
3987 value = mTargetColor;
3991 case Dali::Actor::Property::COLOR_RED:
3993 value = mTargetColor.r;
3997 case Dali::Actor::Property::COLOR_GREEN:
3999 value = mTargetColor.g;
4003 case Dali::Actor::Property::COLOR_BLUE:
4005 value = mTargetColor.b;
4009 case Dali::Actor::Property::COLOR_ALPHA:
4010 case Dali::DevelActor::Property::OPACITY:
4012 value = mTargetColor.a;
4016 case Dali::Actor::Property::NAME:
4022 case Dali::Actor::Property::SENSITIVE:
4024 value = IsSensitive();
4028 case Dali::Actor::Property::LEAVE_REQUIRED:
4030 value = GetLeaveRequired();
4034 case Dali::Actor::Property::INHERIT_POSITION:
4036 value = IsPositionInherited();
4040 case Dali::Actor::Property::INHERIT_ORIENTATION:
4042 value = IsOrientationInherited();
4046 case Dali::Actor::Property::INHERIT_SCALE:
4048 value = IsScaleInherited();
4052 case Dali::Actor::Property::COLOR_MODE:
4054 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4058 case Dali::Actor::Property::POSITION_INHERITANCE:
4060 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4064 case Dali::Actor::Property::DRAW_MODE:
4066 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4070 case Dali::Actor::Property::SIZE_MODE_FACTOR:
4072 value = GetSizeModeFactor();
4076 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4078 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4082 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4084 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4088 case Dali::Actor::Property::SIZE_SCALE_POLICY:
4090 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4094 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4096 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4100 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4102 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4106 case Dali::Actor::Property::PADDING:
4108 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4109 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4110 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4114 case Dali::Actor::Property::MINIMUM_SIZE:
4116 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4120 case Dali::Actor::Property::MAXIMUM_SIZE:
4122 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4126 case Dali::Actor::Property::CLIPPING_MODE:
4128 value = mClippingMode;
4132 case Dali::DevelActor::Property::SIBLING_ORDER:
4134 value = static_cast<int>( GetSiblingOrder() );
4138 case Dali::DevelActor::Property::SCREEN_POSITION:
4140 value = GetCurrentScreenPosition();
4144 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4146 value = mPositionUsesAnchorPoint;
4150 case Dali::Actor::Property::LAYOUT_DIRECTION:
4152 value = mLayoutDirection;
4156 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
4158 value = IsLayoutDirectionInherited();
4164 // Must be a scene-graph only property
4173 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
4175 bool valueSet = true;
4179 case Dali::Actor::Property::SIZE:
4181 value = GetCurrentSize();
4185 case Dali::Actor::Property::SIZE_WIDTH:
4187 value = GetCurrentSize().width;
4191 case Dali::Actor::Property::SIZE_HEIGHT:
4193 value = GetCurrentSize().height;
4197 case Dali::Actor::Property::SIZE_DEPTH:
4199 value = GetCurrentSize().depth;
4203 case Dali::Actor::Property::POSITION:
4205 value = GetCurrentPosition();
4209 case Dali::Actor::Property::POSITION_X:
4211 value = GetCurrentPosition().x;
4215 case Dali::Actor::Property::POSITION_Y:
4217 value = GetCurrentPosition().y;
4221 case Dali::Actor::Property::POSITION_Z:
4223 value = GetCurrentPosition().z;
4227 case Dali::Actor::Property::WORLD_POSITION:
4229 value = GetCurrentWorldPosition();
4233 case Dali::Actor::Property::WORLD_POSITION_X:
4235 value = GetCurrentWorldPosition().x;
4239 case Dali::Actor::Property::WORLD_POSITION_Y:
4241 value = GetCurrentWorldPosition().y;
4245 case Dali::Actor::Property::WORLD_POSITION_Z:
4247 value = GetCurrentWorldPosition().z;
4251 case Dali::Actor::Property::ORIENTATION:
4253 value = GetCurrentOrientation();
4257 case Dali::Actor::Property::WORLD_ORIENTATION:
4259 value = GetCurrentWorldOrientation();
4263 case Dali::Actor::Property::SCALE:
4265 value = GetCurrentScale();
4269 case Dali::Actor::Property::SCALE_X:
4271 value = GetCurrentScale().x;
4275 case Dali::Actor::Property::SCALE_Y:
4277 value = GetCurrentScale().y;
4281 case Dali::Actor::Property::SCALE_Z:
4283 value = GetCurrentScale().z;
4287 case Dali::Actor::Property::WORLD_SCALE:
4289 value = GetCurrentWorldScale();
4293 case Dali::Actor::Property::COLOR:
4295 value = GetCurrentColor();
4299 case Dali::Actor::Property::COLOR_RED:
4301 value = GetCurrentColor().r;
4305 case Dali::Actor::Property::COLOR_GREEN:
4307 value = GetCurrentColor().g;
4311 case Dali::Actor::Property::COLOR_BLUE:
4313 value = GetCurrentColor().b;
4317 case Dali::Actor::Property::COLOR_ALPHA:
4318 case Dali::DevelActor::Property::OPACITY:
4320 value = GetCurrentColor().a;
4324 case Dali::Actor::Property::WORLD_COLOR:
4326 value = GetCurrentWorldColor();
4330 case Dali::Actor::Property::WORLD_MATRIX:
4332 value = GetCurrentWorldMatrix();
4336 case Dali::Actor::Property::VISIBLE:
4338 value = IsVisible();
4344 // Must be an event-side only property
4353 void Actor::EnsureRelayoutData()
4355 // Assign relayout data.
4356 if( !mRelayoutData )
4358 mRelayoutData = new RelayoutData();
4362 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4364 // Check if actor is dependent on parent
4365 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4367 if( ( dimension & ( 1 << i ) ) )
4369 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4370 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4380 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4382 // Check if actor is dependent on children
4383 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4385 if( ( dimension & ( 1 << i ) ) )
4387 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4388 switch( resizePolicy )
4390 case ResizePolicy::FIT_TO_CHILDREN:
4391 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4407 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4409 return Actor::RelayoutDependentOnChildren( dimension );
4412 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4414 // Check each possible dimension and see if it is dependent on the input one
4415 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4417 if( dimension & ( 1 << i ) )
4419 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4426 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4428 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4430 if( dimension & ( 1 << i ) )
4432 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4437 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4439 // If more than one dimension is requested, just return the first one found
4440 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4442 if( ( dimension & ( 1 << i ) ) )
4444 return mRelayoutData->negotiatedDimensions[ i ];
4448 return 0.0f; // Default
4451 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4453 EnsureRelayoutData();
4455 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4457 if( dimension & ( 1 << i ) )
4459 mRelayoutData->dimensionPadding[ i ] = padding;
4464 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4466 if ( mRelayoutData )
4468 // If more than one dimension is requested, just return the first one found
4469 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4471 if( ( dimension & ( 1 << i ) ) )
4473 return mRelayoutData->dimensionPadding[ i ];
4478 return GetDefaultDimensionPadding();
4481 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4483 EnsureRelayoutData();
4485 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4487 if( dimension & ( 1 << i ) )
4489 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4494 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4496 if ( mRelayoutData )
4498 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4500 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4510 float Actor::GetHeightForWidthBase( float width )
4512 float height = 0.0f;
4514 const Vector3 naturalSize = GetNaturalSize();
4515 if( naturalSize.width > 0.0f )
4517 height = naturalSize.height * width / naturalSize.width;
4519 else // we treat 0 as 1:1 aspect ratio
4527 float Actor::GetWidthForHeightBase( float height )
4531 const Vector3 naturalSize = GetNaturalSize();
4532 if( naturalSize.height > 0.0f )
4534 width = naturalSize.width * height / naturalSize.height;
4536 else // we treat 0 as 1:1 aspect ratio
4544 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4546 // Fill to parent, taking size mode factor into account
4547 switch( child.GetResizePolicy( dimension ) )
4549 case ResizePolicy::FILL_TO_PARENT:
4551 return GetLatestSize( dimension );
4554 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4556 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4559 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4561 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4566 return GetLatestSize( dimension );
4571 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4573 // Can be overridden in derived class
4574 return CalculateChildSizeBase( child, dimension );
4577 float Actor::GetHeightForWidth( float width )
4579 // Can be overridden in derived class
4580 return GetHeightForWidthBase( width );
4583 float Actor::GetWidthForHeight( float height )
4585 // Can be overridden in derived class
4586 return GetWidthForHeightBase( height );
4589 float Actor::GetLatestSize( Dimension::Type dimension ) const
4591 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4594 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4596 Vector2 padding = GetPadding( dimension );
4598 return GetLatestSize( dimension ) + padding.x + padding.y;
4601 float Actor::NegotiateFromParent( Dimension::Type dimension )
4603 Actor* parent = GetParent();
4606 Vector2 padding( GetPadding( dimension ) );
4607 Vector2 parentPadding( parent->GetPadding( dimension ) );
4608 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4614 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4616 float maxDimensionPoint = 0.0f;
4618 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4620 ActorPtr child = GetChildAt( i );
4622 if( !child->RelayoutDependentOnParent( dimension ) )
4624 // Calculate the min and max points that the children range across
4625 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4626 float dimensionSize = child->GetRelayoutSize( dimension );
4627 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4631 return maxDimensionPoint;
4634 float Actor::GetSize( Dimension::Type dimension ) const
4636 return GetDimensionValue( mTargetSize, dimension );
4639 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4641 return GetDimensionValue( GetNaturalSize(), dimension );
4644 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4646 switch( GetResizePolicy( dimension ) )
4648 case ResizePolicy::USE_NATURAL_SIZE:
4650 return GetNaturalSize( dimension );
4653 case ResizePolicy::FIXED:
4655 return GetDimensionValue( GetPreferredSize(), dimension );
4658 case ResizePolicy::USE_ASSIGNED_SIZE:
4660 return GetDimensionValue( maximumSize, dimension );
4663 case ResizePolicy::FILL_TO_PARENT:
4664 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4665 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4667 return NegotiateFromParent( dimension );
4670 case ResizePolicy::FIT_TO_CHILDREN:
4672 return NegotiateFromChildren( dimension );
4675 case ResizePolicy::DIMENSION_DEPENDENCY:
4677 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4680 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4682 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4685 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4687 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4699 return 0.0f; // Default
4702 float Actor::ClampDimension( float size, Dimension::Type dimension )
4704 const float minSize = GetMinimumSize( dimension );
4705 const float maxSize = GetMaximumSize( dimension );
4707 return std::max( minSize, std::min( size, maxSize ) );
4710 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4712 // Check if it needs to be negotiated
4713 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4715 // Check that we havn't gotten into an infinite loop
4716 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4717 bool recursionFound = false;
4718 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4720 if( *it == searchActor )
4722 recursionFound = true;
4727 if( !recursionFound )
4729 // Record the path that we have taken
4730 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4732 // Dimension dependency check
4733 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4735 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4737 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4739 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4743 // Parent dependency check
4744 Actor* parent = GetParent();
4745 if( parent && RelayoutDependentOnParent( dimension ) )
4747 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4750 // Children dependency check
4751 if( RelayoutDependentOnChildren( dimension ) )
4753 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4755 ActorPtr child = GetChildAt( i );
4757 // Only relayout child first if it is not dependent on this actor
4758 if( !child->RelayoutDependentOnParent( dimension ) )
4760 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4765 // For deriving classes
4766 OnCalculateRelayoutSize( dimension );
4768 // All dependencies checked, calculate the size and set negotiated flag
4769 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4771 SetNegotiatedDimension( newSize, dimension );
4772 SetLayoutNegotiated( true, dimension );
4774 // For deriving classes
4775 OnLayoutNegotiated( newSize, dimension );
4777 // This actor has been successfully processed, pop it off the recursion stack
4778 recursionStack.pop_back();
4782 // TODO: Break infinite loop
4783 SetLayoutNegotiated( true, dimension );
4788 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4790 // Negotiate all dimensions that require it
4791 ActorDimensionStack recursionStack;
4793 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4795 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4798 NegotiateDimension( dimension, allocatedSize, recursionStack );
4802 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4804 switch( mRelayoutData->sizeSetPolicy )
4806 case SizeScalePolicy::USE_SIZE_SET:
4811 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4813 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4814 const Vector3 naturalSize = GetNaturalSize();
4815 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4817 const float sizeRatio = size.width / size.height;
4818 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4820 if( naturalSizeRatio < sizeRatio )
4822 return Vector2( naturalSizeRatio * size.height, size.height );
4824 else if( naturalSizeRatio > sizeRatio )
4826 return Vector2( size.width, size.width / naturalSizeRatio );
4837 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4839 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4840 const Vector3 naturalSize = GetNaturalSize();
4841 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4843 const float sizeRatio = size.width / size.height;
4844 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4846 if( naturalSizeRatio < sizeRatio )
4848 return Vector2( size.width, size.width / naturalSizeRatio );
4850 else if( naturalSizeRatio > sizeRatio )
4852 return Vector2( naturalSizeRatio * size.height, size.height );
4871 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4873 // Do the set actor size
4874 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4876 // Adjust for size set policy
4877 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4879 // Lock the flag to stop recursive relayouts on set size
4880 mRelayoutData->insideRelayout = true;
4881 SetSize( negotiatedSize );
4882 mRelayoutData->insideRelayout = false;
4884 // Clear flags for all dimensions
4885 SetLayoutDirty( false );
4887 // Give deriving classes a chance to respond
4888 OnRelayout( negotiatedSize, container );
4890 if( !mOnRelayoutSignal.Empty() )
4892 Dali::Actor handle( this );
4893 mOnRelayoutSignal.Emit( handle );
4897 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4899 // Force a size negotiation for actors that has assigned size during relayout
4900 // This is required as otherwise the flags that force a relayout will not
4901 // necessarilly be set. This will occur if the actor has already been laid out.
4902 // The dirty flags are then cleared. Then if the actor is added back into the
4903 // relayout container afterwards, the dirty flags would still be clear...
4904 // causing a relayout to be skipped. Here we force any actors added to the
4905 // container to be relayed out.
4906 DALI_LOG_TIMER_START( NegSizeTimer1 );
4908 if( GetUseAssignedSize(Dimension::WIDTH ) )
4910 SetLayoutNegotiated( false, Dimension::WIDTH );
4912 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4914 SetLayoutNegotiated( false, Dimension::HEIGHT );
4917 // Do the negotiation
4918 NegotiateDimensions( allocatedSize );
4920 // Set the actor size
4921 SetNegotiatedSize( container );
4923 // Negotiate down to children
4924 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4926 ActorPtr child = GetChildAt( i );
4928 // Forces children that have already been laid out to be relayed out
4929 // if they have assigned size during relayout.
4930 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4932 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4933 child->SetLayoutDirty(true, Dimension::WIDTH);
4936 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4938 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4939 child->SetLayoutDirty(true, Dimension::HEIGHT);
4942 // Only relayout if required
4943 if( child->RelayoutRequired() )
4945 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4948 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4951 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4955 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4957 if( dimension & ( 1 << i ) )
4959 mRelayoutData->useAssignedSize[ i ] = use;
4965 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4967 if ( mRelayoutData )
4969 // If more than one dimension is requested, just return the first one found
4970 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4972 if( dimension & ( 1 << i ) )
4974 return mRelayoutData->useAssignedSize[ i ];
4982 void Actor::RelayoutRequest( Dimension::Type dimension )
4984 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4985 if( relayoutController )
4987 Dali::Actor self( this );
4988 relayoutController->RequestRelayout( self, dimension );
4992 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4996 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
5000 void Actor::SetPreferredSize( const Vector2& size )
5002 EnsureRelayoutData();
5004 if( size.width > 0.0f )
5006 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
5009 if( size.height > 0.0f )
5011 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
5014 mRelayoutData->preferredSize = size;
5019 Vector2 Actor::GetPreferredSize() const
5021 if ( mRelayoutData )
5023 return Vector2( mRelayoutData->preferredSize );
5026 return GetDefaultPreferredSize();
5029 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
5031 EnsureRelayoutData();
5033 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5035 if( dimension & ( 1 << i ) )
5037 mRelayoutData->minimumSize[ i ] = size;
5044 float Actor::GetMinimumSize( Dimension::Type dimension ) const
5046 if ( mRelayoutData )
5048 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5050 if( dimension & ( 1 << i ) )
5052 return mRelayoutData->minimumSize[ i ];
5057 return 0.0f; // Default
5060 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5062 EnsureRelayoutData();
5064 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5066 if( dimension & ( 1 << i ) )
5068 mRelayoutData->maximumSize[ i ] = size;
5075 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5077 if ( mRelayoutData )
5079 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5081 if( dimension & ( 1 << i ) )
5083 return mRelayoutData->maximumSize[ i ];
5088 return FLT_MAX; // Default
5091 Object* Actor::GetParentObject() const
5096 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5098 if( mVisible != visible )
5100 if( sendMessage == SendMessage::TRUE && NULL != mNode )
5102 // mNode is being used in a separate thread; queue a message to set the value & base value
5103 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5108 // Emit the signal on this actor and all its children
5109 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5113 void Actor::SetSiblingOrder( unsigned int order )
5117 ActorContainer& siblings = *(mParent->mChildren);
5118 unsigned int currentOrder = GetSiblingOrder();
5120 if( order != currentOrder )
5126 else if( order < siblings.size() -1 )
5128 if( order > currentOrder )
5130 RaiseAbove( *siblings[order] );
5134 LowerBelow( *siblings[order] );
5145 unsigned int Actor::GetSiblingOrder() const
5147 unsigned int order = 0;
5151 ActorContainer& siblings = *(mParent->mChildren);
5152 for( size_t i=0; i<siblings.size(); ++i )
5154 if( siblings[i] == this )
5165 void Actor::RequestRebuildDepthTree()
5169 StagePtr stage = Stage::GetCurrent();
5172 stage->RequestRebuildDepthTree();
5181 ActorContainer& siblings = *(mParent->mChildren);
5182 if( siblings.back() != this ) // If not already at end
5184 for( size_t i=0; i<siblings.size(); ++i )
5186 if( siblings[i] == this )
5189 ActorPtr next = siblings[i+1];
5190 siblings[i+1] = this;
5196 RequestRebuildDepthTree();
5200 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5208 ActorContainer& siblings = *(mParent->mChildren);
5209 if( siblings.front() != this ) // If not already at beginning
5211 for( size_t i=1; i<siblings.size(); ++i )
5213 if( siblings[i] == this )
5215 // Swap with previous
5216 ActorPtr previous = siblings[i-1];
5217 siblings[i-1] = this;
5218 siblings[i] = previous;
5223 RequestRebuildDepthTree();
5227 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5231 void Actor::RaiseToTop()
5235 ActorContainer& siblings = *(mParent->mChildren);
5236 if( siblings.back() != this ) // If not already at end
5238 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5239 if( iter != siblings.end() )
5241 siblings.erase(iter);
5242 siblings.push_back(ActorPtr(this));
5245 RequestRebuildDepthTree();
5249 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5253 void Actor::LowerToBottom()
5257 ActorContainer& siblings = *(mParent->mChildren);
5258 if( siblings.front() != this ) // If not already at bottom,
5260 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5262 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5263 if( iter != siblings.end() )
5265 siblings.erase(iter);
5266 siblings.insert(siblings.begin(), thisPtr);
5269 RequestRebuildDepthTree();
5273 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5277 void Actor::RaiseAbove( Internal::Actor& target )
5281 ActorContainer& siblings = *(mParent->mChildren);
5282 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5284 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5286 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5287 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5288 if( thisIter < targetIter )
5290 siblings.erase(thisIter);
5291 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5292 // invalidate thisIter)
5293 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5295 siblings.insert(targetIter, thisPtr);
5297 RequestRebuildDepthTree();
5302 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5306 void Actor::LowerBelow( Internal::Actor& target )
5310 ActorContainer& siblings = *(mParent->mChildren);
5311 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5313 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5315 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5316 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5318 if( thisIter > targetIter )
5320 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5321 siblings.insert(targetIter, thisPtr);
5323 RequestRebuildDepthTree();
5328 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5332 void Actor::SetInheritLayoutDirection( bool inherit )
5334 if( mInheritLayoutDirection != inherit )
5336 mInheritLayoutDirection = inherit;
5338 if( inherit && mParent )
5340 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5345 bool Actor::IsLayoutDirectionInherited() const
5347 return mInheritLayoutDirection;
5350 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5352 if( actor && ( actor->mInheritLayoutDirection || set ) )
5354 if( actor->mLayoutDirection != direction)
5356 actor->mLayoutDirection = direction;
5357 actor->EmitLayoutDirectionChangedSignal( direction );
5358 actor->RelayoutRequest();
5361 if( actor->GetChildCount() > 0 )
5363 ActorContainer& children = actor->GetChildrenInternal();
5364 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5366 InheritLayoutDirectionRecursively( *iter, direction );
5372 } // namespace Internal