2 * Copyright (c) 2020 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/common/scene-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/animation/constraint-impl.h>
48 #include <dali/internal/event/common/projection.h>
49 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
50 #include <dali/internal/update/common/animatable-property.h>
51 #include <dali/internal/update/nodes/node-messages.h>
52 #include <dali/internal/update/nodes/node-declarations.h>
53 #include <dali/internal/update/animation/scene-graph-constraint.h>
54 #include <dali/internal/event/events/actor-gesture-data.h>
55 #include <dali/internal/common/message.h>
56 #include <dali/integration-api/debug.h>
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::PropertyBase;
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
64 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
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( uint32_t 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", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "reservedProperty01", STRING, true, false, false, Dali::Actor::Property::RESERVED_PROPERTY_01 ) // This property was removed, but to keep binary compatibility and TypeRegister test app, remain it here.
198 DALI_PROPERTY( "drawMode", INTEGER, 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", INTEGER, 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( "culled", BOOLEAN, false, false, true, Dali::DevelActor::Property::CULLED )
217 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
221 const char* const SIGNAL_TOUCHED = "touched";
222 const char* const SIGNAL_HOVERED = "hovered";
223 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
224 const char* const SIGNAL_ON_STAGE = "onStage";
225 const char* const SIGNAL_OFF_STAGE = "offStage";
226 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
227 const char* const SIGNAL_TOUCH = "touch";
228 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
229 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
230 const char* const SIGNAL_CHILD_ADDED = "childAdded";
231 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
235 const char* const ACTION_SHOW = "show";
236 const char* const ACTION_HIDE = "hide";
238 BaseHandle CreateActor()
240 return Dali::Actor::New();
243 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
245 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
247 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
248 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
249 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
250 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
251 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
257 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
258 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
263 const Vector3& value;
266 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
267 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
268 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
269 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
270 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
276 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
278 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
279 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
280 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
281 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
282 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
283 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
285 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
287 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
288 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
290 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
299 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
301 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
305 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
307 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
310 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
312 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
315 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
317 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
319 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
321 uint32_t sizeIgnored = 0;
322 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
324 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
331 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
333 // Values are the same so just use the same table as anchor-point
334 return GetAnchorPointConstant( value, parentOrigin );
338 * @brief Extract a given dimension from a Vector2
340 * @param[in] values The values to extract from
341 * @param[in] dimension The dimension to extract
342 * @return Return the value for the dimension
344 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
348 case Dimension::WIDTH:
352 case Dimension::HEIGHT:
354 return values.height;
365 * @brief Extract a given dimension from a Vector3
367 * @param[in] values The values to extract from
368 * @param[in] dimension The dimension to extract
369 * @return Return the value for the dimension
371 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
373 return GetDimensionValue( values.GetVectorXY(), dimension );
377 * @brief Recursively emits the visibility-changed-signal on the actor tree.
378 * @param[in] actor The actor to emit the signal on
379 * @param[in] visible The new visibility of the actor
380 * @param[in] type Whether the actor's visible property has changed or a parent's
382 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
386 actor->EmitVisibilityChangedSignal( visible, type );
388 if( actor->GetChildCount() > 0 )
390 ActorContainer& children = actor->GetChildrenInternal();
391 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
393 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
399 } // unnamed namespace
401 ActorPtr Actor::New()
403 // pass a reference to actor, actor does not own its node
404 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
406 // Second-phase construction
412 const SceneGraph::Node* Actor::CreateNode()
414 // create node. Nodes are owned by the update manager
415 SceneGraph::Node* node = SceneGraph::Node::New();
416 OwnerPointer< SceneGraph::Node > transferOwnership( node );
417 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
418 AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
423 const std::string& Actor::GetName() const
428 void Actor::SetName( const std::string& name )
432 // ATTENTION: string for debug purposes is not thread safe.
433 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
436 uint32_t Actor::GetId() const
438 return GetNode().GetId();
441 bool Actor::OnStage() const
446 Dali::Layer Actor::GetLayer()
450 // Short-circuit for Layer derived actors
453 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
456 // Find the immediate Layer parent
457 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
459 if( parent->IsLayer() )
461 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
468 void Actor::Add( Actor& child )
470 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
471 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
475 mChildren = new ActorContainer;
478 Actor* const oldParent( child.mParent );
480 // child might already be ours
481 if( this != oldParent )
483 // if we already have parent, unparent us first
486 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
488 // Old parent may need to readjust to missing child
489 if( oldParent->RelayoutDependentOnChildren() )
491 oldParent->RelayoutRequest();
495 // Guard against Add() during previous OnChildRemove callback
498 // Do this first, since user callbacks from within SetParent() may need to remove child
499 mChildren->push_back( ActorPtr( &child ) );
501 // SetParent asserts that child can be added
502 child.SetParent( this );
504 // Notification for derived classes
506 EmitChildAddedSignal( child );
508 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
510 // Only put in a relayout request if there is a suitable dependency
511 if( RelayoutDependentOnChildren() )
519 void Actor::Remove( Actor& child )
521 if( (this == &child) || (!mChildren) )
523 // no children or removing itself
529 // Find the child in mChildren, and unparent it
530 ActorIter end = mChildren->end();
531 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
533 ActorPtr actor = (*iter);
535 if( actor.Get() == &child )
537 // Keep handle for OnChildRemove notification
540 // Do this first, since user callbacks from within SetParent() may need to add the child
541 mChildren->erase( iter );
543 DALI_ASSERT_DEBUG( actor->GetParent() == this );
544 actor->SetParent( NULL );
552 // Only put in a relayout request if there is a suitable dependency
553 if( RelayoutDependentOnChildren() )
559 // Notification for derived classes
560 OnChildRemove( child );
561 EmitChildRemovedSignal( child );
564 void Actor::Unparent()
568 // Remove this actor from the parent. The remove will put a relayout request in for
569 // the parent if required
570 mParent->Remove( *this );
571 // mParent is now NULL!
575 uint32_t Actor::GetChildCount() const
577 return ( NULL != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
580 ActorPtr Actor::GetChildAt( uint32_t index ) const
582 DALI_ASSERT_ALWAYS( index < GetChildCount() );
584 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
587 ActorPtr Actor::FindChildByName( const std::string& actorName )
590 if( actorName == mName )
596 ActorIter end = mChildren->end();
597 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
599 child = (*iter)->FindChildByName( actorName );
610 ActorPtr Actor::FindChildById( const uint32_t id )
619 ActorIter end = mChildren->end();
620 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
622 child = (*iter)->FindChildById( id );
633 void Actor::SetParentOrigin( const Vector3& origin )
635 // node is being used in a separate thread; queue a message to set the value & base value
636 SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
638 // Cache for event-thread access
641 // not allocated, check if different from default
642 if( ParentOrigin::DEFAULT != origin )
644 mParentOrigin = new Vector3( origin );
649 // check if different from current costs more than just set
650 *mParentOrigin = origin;
654 void Actor::SetParentOriginX( float x )
656 const Vector3& current = GetCurrentParentOrigin();
658 SetParentOrigin( Vector3( x, current.y, current.z ) );
661 void Actor::SetParentOriginY( float y )
663 const Vector3& current = GetCurrentParentOrigin();
665 SetParentOrigin( Vector3( current.x, y, current.z ) );
668 void Actor::SetParentOriginZ( float z )
670 const Vector3& current = GetCurrentParentOrigin();
672 SetParentOrigin( Vector3( current.x, current.y, z ) );
675 const Vector3& Actor::GetCurrentParentOrigin() const
677 // Cached for event-thread access
678 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
681 void Actor::SetAnchorPoint( const Vector3& anchor )
683 // node is being used in a separate thread; queue a message to set the value & base value
684 SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
686 // Cache for event-thread access
689 // not allocated, check if different from default
690 if( AnchorPoint::DEFAULT != anchor )
692 mAnchorPoint = new Vector3( anchor );
697 // check if different from current costs more than just set
698 *mAnchorPoint = anchor;
702 void Actor::SetAnchorPointX( float x )
704 const Vector3& current = GetCurrentAnchorPoint();
706 SetAnchorPoint( Vector3( x, current.y, current.z ) );
709 void Actor::SetAnchorPointY( float y )
711 const Vector3& current = GetCurrentAnchorPoint();
713 SetAnchorPoint( Vector3( current.x, y, current.z ) );
716 void Actor::SetAnchorPointZ( float z )
718 const Vector3& current = GetCurrentAnchorPoint();
720 SetAnchorPoint( Vector3( current.x, current.y, z ) );
723 const Vector3& Actor::GetCurrentAnchorPoint() const
725 // Cached for event-thread access
726 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
729 void Actor::SetPosition( float x, float y )
731 SetPosition( Vector3( x, y, 0.0f ) );
734 void Actor::SetPosition( float x, float y, float z )
736 SetPosition( Vector3( x, y, z ) );
739 void Actor::SetPosition( const Vector3& position )
741 mTargetPosition = position;
743 // node is being used in a separate thread; queue a message to set the value & base value
744 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
747 void Actor::SetX( float x )
749 mTargetPosition.x = x;
751 // node is being used in a separate thread; queue a message to set the value & base value
752 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
755 void Actor::SetY( float y )
757 mTargetPosition.y = y;
759 // node is being used in a separate thread; queue a message to set the value & base value
760 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
763 void Actor::SetZ( float z )
765 mTargetPosition.z = z;
767 // node is being used in a separate thread; queue a message to set the value & base value
768 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
771 void Actor::TranslateBy( const Vector3& distance )
773 mTargetPosition += distance;
775 // node is being used in a separate thread; queue a message to set the value & base value
776 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
779 const Vector3& Actor::GetCurrentPosition() const
781 // node is being used in a separate thread; copy the value from the previous update
782 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
785 const Vector3& Actor::GetTargetPosition() const
787 return mTargetPosition;
790 const Vector3& Actor::GetCurrentWorldPosition() const
792 // node is being used in a separate thread; copy the value from the previous update
793 return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
796 const Vector2 Actor::GetCurrentScreenPosition() const
798 if( mScene && OnStage() )
800 Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
801 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
802 worldPosition -= cameraPosition;
804 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
805 Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
806 Vector3 halfActorSize( actorSize * 0.5f );
807 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
809 return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
810 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
813 return Vector2::ZERO;
816 void Actor::SetInheritPosition( bool inherit )
818 if( mInheritPosition != inherit )
820 // non animatable so keep local copy
821 mInheritPosition = inherit;
822 SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
826 bool Actor::IsPositionInherited() const
828 return mInheritPosition;
831 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
833 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
834 normalizedAxis.Normalize();
836 Quaternion orientation( angle, normalizedAxis );
838 SetOrientation( orientation );
841 void Actor::SetOrientation( const Quaternion& orientation )
843 mTargetOrientation = orientation;
845 // node is being used in a separate thread; queue a message to set the value & base value
846 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
849 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
851 RotateBy( Quaternion(angle, axis) );
854 void Actor::RotateBy( const Quaternion& relativeRotation )
856 mTargetOrientation *= Quaternion( relativeRotation );
858 // node is being used in a separate thread; queue a message to set the value & base value
859 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
862 const Quaternion& Actor::GetCurrentOrientation() const
864 // node is being used in a separate thread; copy the value from the previous update
865 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
868 const Quaternion& Actor::GetCurrentWorldOrientation() const
870 // node is being used in a separate thread; copy the value from the previous update
871 return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
874 void Actor::SetScale( float scale )
876 SetScale( Vector3( scale, scale, scale ) );
879 void Actor::SetScale( float x, float y, float z )
881 SetScale( Vector3( x, y, z ) );
884 void Actor::SetScale( const Vector3& scale )
886 mTargetScale = scale;
888 // node is being used in a separate thread; queue a message to set the value & base value
889 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
892 void Actor::SetScaleX( float x )
896 // node is being used in a separate thread; queue a message to set the value & base value
897 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
900 void Actor::SetScaleY( float y )
904 // node is being used in a separate thread; queue a message to set the value & base value
905 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
908 void Actor::SetScaleZ( float z )
912 // node is being used in a separate thread; queue a message to set the value & base value
913 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
916 void Actor::ScaleBy(const Vector3& relativeScale)
918 mTargetScale *= relativeScale;
920 // node is being used in a separate thread; queue a message to set the value & base value
921 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
924 const Vector3& Actor::GetCurrentScale() const
926 // node is being used in a separate thread; copy the value from the previous update
927 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
930 const Vector3& Actor::GetCurrentWorldScale() const
932 // node is being used in a separate thread; copy the value from the previous update
933 return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
936 void Actor::SetInheritScale( bool inherit )
938 if( mInheritScale != inherit )
940 // non animatable so keep local copy
941 mInheritScale = inherit;
942 // node is being used in a separate thread; queue a message to set the value
943 SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
947 bool Actor::IsScaleInherited() const
949 return mInheritScale;
952 Matrix Actor::GetCurrentWorldMatrix() const
954 return GetNode().GetWorldMatrix(0);
957 void Actor::SetVisible( bool visible )
959 SetVisibleInternal( visible, SendMessage::TRUE );
962 bool Actor::IsVisible() const
964 // node is being used in a separate thread; copy the value from the previous update
965 return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
968 void Actor::SetOpacity( float opacity )
970 mTargetColor.a = opacity;
972 // node is being used in a separate thread; queue a message to set the value & base value
973 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
976 float Actor::GetCurrentOpacity() const
978 // node is being used in a separate thread; copy the value from the previous update
979 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
982 ClippingMode::Type Actor::GetClippingMode() const
984 return mClippingMode;
987 uint32_t Actor::GetSortingDepth()
992 const Vector4& Actor::GetCurrentWorldColor() const
994 return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
997 void Actor::SetColor( const Vector4& color )
999 mTargetColor = color;
1001 // node is being used in a separate thread; queue a message to set the value & base value
1002 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
1005 void Actor::SetColorRed( float red )
1007 mTargetColor.r = red;
1009 // node is being used in a separate thread; queue a message to set the value & base value
1010 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
1013 void Actor::SetColorGreen( float green )
1015 mTargetColor.g = green;
1017 // node is being used in a separate thread; queue a message to set the value & base value
1018 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green );
1021 void Actor::SetColorBlue( float blue )
1023 mTargetColor.b = blue;
1025 // node is being used in a separate thread; queue a message to set the value & base value
1026 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1029 const Vector4& Actor::GetCurrentColor() const
1031 // node is being used in a separate thread; copy the value from the previous update
1032 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
1035 void Actor::SetInheritOrientation( bool inherit )
1037 if( mInheritOrientation != inherit )
1039 // non animatable so keep local copy
1040 mInheritOrientation = inherit;
1041 // node is being used in a separate thread; queue a message to set the value
1042 SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
1046 bool Actor::IsOrientationInherited() const
1048 return mInheritOrientation;
1051 void Actor::SetSizeModeFactor( const Vector3& factor )
1053 EnsureRelayoutData();
1055 mRelayoutData->sizeModeFactor = factor;
1058 const Vector3& Actor::GetSizeModeFactor() const
1060 if ( mRelayoutData )
1062 return mRelayoutData->sizeModeFactor;
1065 return GetDefaultSizeModeFactor();
1068 void Actor::SetColorMode( ColorMode colorMode )
1070 // non animatable so keep local copy
1071 mColorMode = colorMode;
1072 // node is being used in a separate thread; queue a message to set the value
1073 SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
1076 ColorMode Actor::GetColorMode() const
1078 // we have cached copy
1082 void Actor::SetSize( float width, float height )
1084 SetSize( Vector2( width, height ) );
1087 void Actor::SetSize( float width, float height, float depth )
1089 SetSize( Vector3( width, height, depth ) );
1092 void Actor::SetSize( const Vector2& size )
1094 SetSize( Vector3( size.width, size.height, 0.f ) );
1097 void Actor::SetSizeInternal( const Vector2& size )
1099 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1102 void Actor::SetSize( const Vector3& size )
1104 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1106 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1107 SetPreferredSize( size.GetVectorXY() );
1111 SetSizeInternal( size );
1115 void Actor::SetSizeInternal( const Vector3& size )
1117 // dont allow recursive loop
1118 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1119 // 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
1120 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1121 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1122 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1126 // node is being used in a separate thread; queue a message to set the value & base value
1127 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1129 // Notification for derived classes
1130 mInsideOnSizeSet = true;
1131 OnSizeSet( mTargetSize );
1132 mInsideOnSizeSet = false;
1134 // Raise a relayout request if the flag is not locked
1135 if( mRelayoutData && !mRelayoutData->insideRelayout )
1142 void Actor::SetWidth( float width )
1144 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1146 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1147 mRelayoutData->preferredSize.width = width;
1151 mTargetSize.width = width;
1153 // node is being used in a separate thread; queue a message to set the value & base value
1154 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1157 mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
1162 void Actor::SetHeight( float height )
1164 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1166 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1167 mRelayoutData->preferredSize.height = height;
1171 mTargetSize.height = height;
1173 // node is being used in a separate thread; queue a message to set the value & base value
1174 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1177 mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
1182 void Actor::SetDepth( float depth )
1184 mTargetSize.depth = depth;
1186 mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
1188 // node is being used in a separate thread; queue a message to set the value & base value
1189 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1192 Vector3 Actor::GetTargetSize() const
1194 Vector3 size = mTargetSize;
1196 if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH )
1198 // Should return animated size if size is animated
1199 size.width = mAnimatedSize.width;
1203 // Should return preferred size if size is fixed as set by SetSize
1204 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1206 size.width = GetPreferredSize().width;
1210 if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT )
1212 size.height = mAnimatedSize.height;
1216 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1218 size.height = GetPreferredSize().height;
1222 if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH )
1224 size.depth = mAnimatedSize.depth;
1230 const Vector3& Actor::GetCurrentSize() const
1232 // node is being used in a separate thread; copy the value from the previous update
1233 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1236 Vector3 Actor::GetNaturalSize() const
1238 // It is up to deriving classes to return the appropriate natural size
1239 return Vector3( 0.0f, 0.0f, 0.0f );
1242 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1244 EnsureRelayoutData();
1246 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1247 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1249 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1251 if( dimension & ( 1 << i ) )
1253 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1255 mRelayoutData->useAssignedSize[ i ] = true;
1259 mRelayoutData->resizePolicies[ i ] = policy;
1260 mRelayoutData->useAssignedSize[ i ] = false;
1265 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1267 if( dimension & Dimension::WIDTH )
1269 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1272 if( dimension & Dimension::HEIGHT )
1274 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1278 // If calling SetResizePolicy, assume we want relayout enabled
1279 SetRelayoutEnabled( true );
1281 // If the resize policy is set to be FIXED, the preferred size
1282 // should be overrided by the target size. Otherwise the target
1283 // size should be overrided by the preferred size.
1285 if( dimension & Dimension::WIDTH )
1287 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1289 mRelayoutData->preferredSize.width = mTargetSize.width;
1291 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1293 mTargetSize.width = mRelayoutData->preferredSize.width;
1297 if( dimension & Dimension::HEIGHT )
1299 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1301 mRelayoutData->preferredSize.height = mTargetSize.height;
1303 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1305 mTargetSize.height = mRelayoutData->preferredSize.height;
1309 OnSetResizePolicy( policy, dimension );
1311 // Trigger relayout on this control
1315 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1317 if ( mRelayoutData )
1319 // If more than one dimension is requested, just return the first one found
1320 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1322 if( ( dimension & ( 1 << i ) ) )
1324 if( mRelayoutData->useAssignedSize[ i ] )
1326 return ResizePolicy::USE_ASSIGNED_SIZE;
1330 return mRelayoutData->resizePolicies[ i ];
1336 return ResizePolicy::DEFAULT;
1339 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1341 EnsureRelayoutData();
1343 mRelayoutData->sizeSetPolicy = policy;
1345 // Trigger relayout on this control
1349 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1351 if ( mRelayoutData )
1353 return mRelayoutData->sizeSetPolicy;
1356 return DEFAULT_SIZE_SCALE_POLICY;
1359 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1361 EnsureRelayoutData();
1363 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1365 if( dimension & ( 1 << i ) )
1367 mRelayoutData->dimensionDependencies[ i ] = dependency;
1372 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1374 if ( mRelayoutData )
1376 // If more than one dimension is requested, just return the first one found
1377 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1379 if( ( dimension & ( 1 << i ) ) )
1381 return mRelayoutData->dimensionDependencies[ i ];
1386 return Dimension::ALL_DIMENSIONS; // Default
1389 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1391 // If relayout data has not been allocated yet and the client is requesting
1392 // to disable it, do nothing
1393 if( mRelayoutData || relayoutEnabled )
1395 EnsureRelayoutData();
1397 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1399 mRelayoutData->relayoutEnabled = relayoutEnabled;
1403 bool Actor::IsRelayoutEnabled() const
1405 // Assume that if relayout data has not been allocated yet then
1406 // relayout is disabled
1407 return mRelayoutData && mRelayoutData->relayoutEnabled;
1410 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1412 EnsureRelayoutData();
1414 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1416 if( dimension & ( 1 << i ) )
1418 mRelayoutData->dimensionDirty[ i ] = dirty;
1423 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1425 if ( mRelayoutData )
1427 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1429 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1439 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1441 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1444 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1446 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1449 uint32_t Actor::AddRenderer( Renderer& renderer )
1453 mRenderers = new RendererContainer;
1456 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1457 RendererPtr rendererPtr = RendererPtr( &renderer );
1458 mRenderers->push_back( rendererPtr );
1459 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1463 uint32_t Actor::GetRendererCount() const
1465 uint32_t rendererCount(0);
1468 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1471 return rendererCount;
1474 RendererPtr Actor::GetRendererAt( uint32_t index )
1476 RendererPtr renderer;
1477 if( index < GetRendererCount() )
1479 renderer = ( *mRenderers )[ index ];
1485 void Actor::RemoveRenderer( Renderer& renderer )
1489 RendererIter end = mRenderers->end();
1490 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1492 if( (*iter).Get() == &renderer )
1494 mRenderers->erase( iter );
1495 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1502 void Actor::RemoveRenderer( uint32_t index )
1504 if( index < GetRendererCount() )
1506 RendererPtr renderer = ( *mRenderers )[ index ];
1507 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1508 mRenderers->erase( mRenderers->begin()+index );
1512 bool Actor::IsOverlay() const
1514 return ( DrawMode::OVERLAY_2D == mDrawMode );
1517 void Actor::SetDrawMode( DrawMode::Type drawMode )
1519 // this flag is not animatable so keep the value
1520 mDrawMode = drawMode;
1522 // node is being used in a separate thread; queue a message to set the value
1523 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1526 DrawMode::Type Actor::GetDrawMode() const
1531 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1533 // only valid when on-stage
1534 if( mScene && OnStage() )
1536 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1538 Vector2 converted( screenX, screenY );
1540 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1541 uint32_t taskCount = taskList.GetTaskCount();
1542 for( uint32_t i = taskCount; i > 0; --i )
1544 RenderTaskPtr task = taskList.GetTask( i - 1 );
1545 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1547 // found a task where this conversion was ok so return
1555 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1557 bool retval = false;
1558 // only valid when on-stage
1561 CameraActor* camera = renderTask.GetCameraActor();
1565 renderTask.GetViewport( viewport );
1567 // need to translate coordinates to render tasks coordinate space
1568 Vector2 converted( screenX, screenY );
1569 if( renderTask.TranslateCoordinates( converted ) )
1571 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1578 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1580 // Early-out if not on stage
1586 // Get the ModelView matrix
1588 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1590 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1591 Matrix invertedMvp( false/*don't init*/);
1592 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1593 bool success = invertedMvp.Invert();
1595 // Convert to GL coordinates
1596 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1601 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1608 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1614 if( XyPlaneIntersect( nearPos, farPos, local ) )
1616 Vector3 size = GetCurrentSize();
1617 localX = local.x + size.x * 0.5f;
1618 localY = local.y + size.y * 0.5f;
1629 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1632 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1634 Mathematical Formulation
1636 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1638 ( p - c ) dot ( p - c ) = r^2
1640 Given a ray with a point of origin 'o', and a direction vector 'd':
1642 ray(t) = o + td, t >= 0
1644 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1646 (o + td - c ) dot ( o + td - c ) = r^2
1648 To solve for t we first expand the above into a more recognisable quadratic equation form
1650 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1659 B = 2( o - c ) dot d
1660 C = ( o - c ) dot ( o - c ) - r^2
1662 which can be solved using a standard quadratic formula.
1664 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1666 Practical Simplification
1668 In a renderer, we often differentiate between world space and object space. In the object space
1669 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1670 into object space, the mathematical solution presented above can be simplified significantly.
1672 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1676 and we can find the t at which the (transformed) ray intersects the sphere by
1678 ( o + td ) dot ( o + td ) = r^2
1680 According to the reasoning above, we expand the above quadratic equation into the general form
1684 which now has coefficients:
1691 // Early-out if not on stage
1697 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1699 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1700 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1701 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1703 // Compute the radius is not needed, square radius it's enough.
1704 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1706 // Scale the sphere.
1707 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1709 const float width = size.width * scale.width;
1710 const float height = size.height * scale.height;
1712 float squareSphereRadius = 0.5f * ( width * width + height * height );
1714 float a = rayDir.Dot( rayDir ); // a
1715 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1716 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1718 return ( b2 * b2 - a * c ) >= 0.f;
1721 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1727 // Transforms the ray to the local reference system.
1728 // Calculate the inverse of Model matrix
1729 Matrix invModelMatrix( false/*don't init*/);
1731 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1732 invModelMatrix = GetNode().GetWorldMatrix(0);
1733 invModelMatrix.Invert();
1735 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1736 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1738 // Test with the actor's XY plane (Normal = 0 0 1 1).
1740 float a = -rayOriginLocal.z;
1741 float b = rayDirLocal.z;
1743 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1745 // Ray travels distance * rayDirLocal to intersect with plane.
1748 const Vector3& size = GetNode().GetSize( bufferIndex );
1750 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1751 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1753 // Test with the actor's geometry.
1754 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1761 void Actor::SetLeaveRequired( bool required )
1763 mLeaveRequired = required;
1766 bool Actor::GetLeaveRequired() const
1768 return mLeaveRequired;
1771 void Actor::SetKeyboardFocusable( bool focusable )
1773 mKeyboardFocusable = focusable;
1776 bool Actor::IsKeyboardFocusable() const
1778 return mKeyboardFocusable;
1781 bool Actor::GetTouchRequired() const
1783 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1786 bool Actor::GetHoverRequired() const
1788 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1791 bool Actor::GetWheelEventRequired() const
1793 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1796 bool Actor::IsHittable() const
1798 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1801 ActorGestureData& Actor::GetGestureData()
1803 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1804 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1805 if( NULL == mGestureData )
1807 mGestureData = new ActorGestureData;
1809 return *mGestureData;
1812 bool Actor::IsGestureRequred( DevelGesture::Type type ) const
1814 return mGestureData && mGestureData->IsGestureRequred( type );
1817 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1819 bool consumed = false;
1821 if( !mTouchSignal.Empty() )
1823 Dali::Actor handle( this );
1824 consumed = mTouchSignal.Emit( handle, touch );
1827 if( !mTouchedSignal.Empty() )
1829 Dali::Actor handle( this );
1830 consumed |= mTouchedSignal.Emit( handle, event );
1835 // Notification for derived classes
1836 consumed = OnTouchEvent( event ); // TODO
1842 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1844 bool consumed = false;
1846 if( !mHoveredSignal.Empty() )
1848 Dali::Actor handle( this );
1849 consumed = mHoveredSignal.Emit( handle, event );
1854 // Notification for derived classes
1855 consumed = OnHoverEvent( event );
1861 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1863 bool consumed = false;
1865 if( !mWheelEventSignal.Empty() )
1867 Dali::Actor handle( this );
1868 consumed = mWheelEventSignal.Emit( handle, event );
1873 // Notification for derived classes
1874 consumed = OnWheelEvent( event );
1880 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1882 if( ! mVisibilityChangedSignal.Empty() )
1884 Dali::Actor handle( this );
1885 mVisibilityChangedSignal.Emit( handle, visible, type );
1889 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1891 if( ! mLayoutDirectionChangedSignal.Empty() )
1893 Dali::Actor handle( this );
1894 mLayoutDirectionChangedSignal.Emit( handle, type );
1898 void Actor::EmitChildAddedSignal( Actor& child )
1900 if( ! mChildAddedSignal.Empty() )
1902 Dali::Actor handle( &child );
1903 mChildAddedSignal.Emit( handle );
1907 void Actor::EmitChildRemovedSignal( Actor& child )
1909 if( ! mChildRemovedSignal.Empty() )
1911 Dali::Actor handle( &child );
1912 mChildRemovedSignal.Emit( handle );
1916 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1918 return mTouchedSignal;
1921 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1923 return mTouchSignal;
1926 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1928 return mHoveredSignal;
1931 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1933 return mWheelEventSignal;
1936 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1938 return mOnStageSignal;
1941 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1943 return mOffStageSignal;
1946 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1948 return mOnRelayoutSignal;
1951 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1953 return mVisibilityChangedSignal;
1956 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1958 return mLayoutDirectionChangedSignal;
1961 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1963 return mChildAddedSignal;
1966 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1968 return mChildRemovedSignal;
1971 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1973 return mChildOrderChangedSignal;
1976 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1978 bool connected( true );
1979 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1981 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1983 actor->TouchedSignal().Connect( tracker, functor );
1985 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1987 actor->HoveredSignal().Connect( tracker, functor );
1989 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1991 actor->WheelEventSignal().Connect( tracker, functor );
1993 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1995 actor->OnStageSignal().Connect( tracker, functor );
1997 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1999 actor->OffStageSignal().Connect( tracker, functor );
2001 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2003 actor->OnRelayoutSignal().Connect( tracker, functor );
2005 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2007 actor->TouchSignal().Connect( tracker, functor );
2009 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
2011 actor->VisibilityChangedSignal().Connect( tracker, functor );
2013 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2015 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2017 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2019 actor->ChildAddedSignal().Connect( tracker, functor );
2021 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2023 actor->ChildRemovedSignal().Connect( tracker, functor );
2027 // signalName does not match any signal
2034 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2040 mParentOrigin( NULL ),
2041 mAnchorPoint( NULL ),
2042 mRelayoutData( NULL ),
2043 mGestureData( NULL ),
2047 mWheelEventSignal(),
2050 mOnRelayoutSignal(),
2051 mVisibilityChangedSignal(),
2052 mLayoutDirectionChangedSignal(),
2053 mChildAddedSignal(),
2054 mChildRemovedSignal(),
2055 mChildOrderChangedSignal(),
2056 mTargetOrientation( Quaternion::IDENTITY ),
2057 mTargetColor( Color::WHITE ),
2058 mTargetSize( Vector3::ZERO ),
2059 mTargetPosition( Vector3::ZERO ),
2060 mTargetScale( Vector3::ONE ),
2061 mAnimatedSize( Vector3::ZERO ),
2065 mUseAnimatedSize( AnimatedSizeFlag::CLEAR ),
2066 mIsRoot( ROOT_LAYER == derivedType ),
2067 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2068 mIsOnStage( false ),
2070 mLeaveRequired( false ),
2071 mKeyboardFocusable( false ),
2072 mDerivedRequiresTouch( false ),
2073 mDerivedRequiresHover( false ),
2074 mDerivedRequiresWheelEvent( false ),
2075 mOnStageSignalled( false ),
2076 mInsideOnSizeSet( false ),
2077 mInheritPosition( true ),
2078 mInheritOrientation( true ),
2079 mInheritScale( true ),
2080 mPositionUsesAnchorPoint( true ),
2082 mInheritLayoutDirection( true ),
2083 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2084 mDrawMode( DrawMode::NORMAL ),
2085 mColorMode( Node::DEFAULT_COLOR_MODE ),
2086 mClippingMode( ClippingMode::DISABLED )
2090 void Actor::Initialize()
2094 GetEventThreadServices().RegisterObject( this );
2099 // Remove mParent pointers from children even if we're destroying core,
2100 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2103 ActorConstIter endIter = mChildren->end();
2104 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2106 (*iter)->SetParent( NULL );
2112 // Guard to allow handle destruction after Core has been destroyed
2113 if( EventThreadServices::IsCoreRunning() )
2115 // Root layer will destroy its node in its own destructor
2118 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2120 GetEventThreadServices().UnregisterObject( this );
2124 // Cleanup optional gesture data
2125 delete mGestureData;
2127 // Cleanup optional parent origin and anchor
2128 delete mParentOrigin;
2129 delete mAnchorPoint;
2131 // Delete optional relayout data
2132 delete mRelayoutData;
2135 void Actor::ConnectToStage( uint32_t parentDepth )
2137 // This container is used instead of walking the Actor hierarchy.
2138 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2139 ActorContainer connectionList;
2143 mScene->RequestRebuildDepthTree();
2146 // This stage is atomic i.e. not interrupted by user callbacks.
2147 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2149 // Notify applications about the newly connected actors.
2150 const ActorIter endIter = connectionList.end();
2151 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2153 (*iter)->NotifyStageConnection();
2159 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2161 DALI_ASSERT_ALWAYS( !OnStage() );
2164 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2166 ConnectToSceneGraph();
2168 // Notification for internal derived classes
2169 OnStageConnectionInternal();
2171 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2172 connectionList.push_back( ActorPtr( this ) );
2174 // Recursively connect children
2177 ActorConstIter endIter = mChildren->end();
2178 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2180 (*iter)->SetScene( *mScene );
2181 (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2187 * This method is called when the Actor is connected to the Stage.
2188 * The parent must have added its Node to the scene-graph.
2189 * The child must connect its Node to the parent's Node.
2190 * This is recursive; the child calls ConnectToStage() for its children.
2192 void Actor::ConnectToSceneGraph()
2194 DALI_ASSERT_DEBUG( mParent != NULL);
2196 // Reparent Node in next Update
2197 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2199 // Request relayout on all actors that are added to the scenegraph
2202 // Notification for Object::Observers
2206 void Actor::NotifyStageConnection()
2208 // Actors can be removed (in a callback), before the on-stage stage is reported.
2209 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2210 if( OnStage() && !mOnStageSignalled )
2212 // Notification for external (CustomActor) derived classes
2213 OnStageConnectionExternal( mDepth );
2215 if( !mOnStageSignal.Empty() )
2217 Dali::Actor handle( this );
2218 mOnStageSignal.Emit( handle );
2221 // Guard against Remove during callbacks
2224 mOnStageSignalled = true; // signal required next time Actor is removed
2229 void Actor::DisconnectFromStage()
2231 // This container is used instead of walking the Actor hierachy.
2232 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2233 ActorContainer disconnectionList;
2237 mScene->RequestRebuildDepthTree();
2240 // This stage is atomic i.e. not interrupted by user callbacks
2241 RecursiveDisconnectFromStage( disconnectionList );
2243 // Notify applications about the newly disconnected actors.
2244 const ActorIter endIter = disconnectionList.end();
2245 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2247 (*iter)->NotifyStageDisconnection();
2251 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2253 // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2256 // Recursively disconnect children
2259 ActorConstIter endIter = mChildren->end();
2260 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2262 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2266 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2267 disconnectionList.push_back( ActorPtr( this ) );
2269 // Notification for internal derived classes
2270 OnStageDisconnectionInternal();
2272 DisconnectFromSceneGraph();
2276 * This method is called by an actor or its parent, before a node removal message is sent.
2277 * This is recursive; the child calls DisconnectFromStage() for its children.
2279 void Actor::DisconnectFromSceneGraph()
2281 // Notification for Object::Observers
2282 OnSceneObjectRemove();
2285 void Actor::NotifyStageDisconnection()
2287 // Actors can be added (in a callback), before the off-stage state is reported.
2288 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2289 // only do this step if there is a stage, i.e. Core is not being shut down
2290 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2292 // Notification for external (CustomeActor) derived classes
2293 OnStageDisconnectionExternal();
2295 if( !mOffStageSignal.Empty() )
2297 Dali::Actor handle( this );
2298 mOffStageSignal.Emit( handle );
2301 // Guard against Add during callbacks
2304 mOnStageSignalled = false; // signal required next time Actor is added
2309 bool Actor::IsNodeConnected() const
2311 bool connected( false );
2315 if( IsRoot() || GetNode().GetParent() )
2324 // This method initiates traversal of the actor tree using depth-first
2325 // traversal to set a depth index based on traversal order. It sends a
2326 // single message to update manager to update all the actor's nodes in
2327 // this tree with the depth index. The sceneGraphNodeDepths vector's
2328 // elements are ordered by depth, and could be used to reduce sorting
2329 // in the update thread.
2330 void Actor::RebuildDepthTree()
2332 DALI_LOG_TIMER_START(depthTimer);
2334 // Vector of scene-graph nodes and their depths to send to UpdateManager
2335 // in a single message
2336 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2338 int32_t depthIndex = 1;
2339 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2341 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2342 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2345 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2347 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2348 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2350 // Create/add to children of this node
2353 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2355 Actor* childActor = (*it).Get();
2357 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2362 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2366 case Dali::Actor::Property::PARENT_ORIGIN:
2368 Property::Type type = property.GetType();
2369 if( type == Property::VECTOR3 )
2371 SetParentOrigin( property.Get< Vector3 >() );
2373 else if ( type == Property::STRING )
2375 std::string parentOriginString;
2376 property.Get( parentOriginString );
2377 Vector3 parentOrigin;
2378 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2380 SetParentOrigin( parentOrigin );
2386 case Dali::Actor::Property::PARENT_ORIGIN_X:
2388 SetParentOriginX( property.Get< float >() );
2392 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2394 SetParentOriginY( property.Get< float >() );
2398 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2400 SetParentOriginZ( property.Get< float >() );
2404 case Dali::Actor::Property::ANCHOR_POINT:
2406 Property::Type type = property.GetType();
2407 if( type == Property::VECTOR3 )
2409 SetAnchorPoint( property.Get< Vector3 >() );
2411 else if ( type == Property::STRING )
2413 std::string anchorPointString;
2414 property.Get( anchorPointString );
2416 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2418 SetAnchorPoint( anchor );
2424 case Dali::Actor::Property::ANCHOR_POINT_X:
2426 SetAnchorPointX( property.Get< float >() );
2430 case Dali::Actor::Property::ANCHOR_POINT_Y:
2432 SetAnchorPointY( property.Get< float >() );
2436 case Dali::Actor::Property::ANCHOR_POINT_Z:
2438 SetAnchorPointZ( property.Get< float >() );
2442 case Dali::Actor::Property::SIZE:
2444 SetSize( property.Get< Vector3 >() );
2448 case Dali::Actor::Property::SIZE_WIDTH:
2450 SetWidth( property.Get< float >() );
2454 case Dali::Actor::Property::SIZE_HEIGHT:
2456 SetHeight( property.Get< float >() );
2460 case Dali::Actor::Property::SIZE_DEPTH:
2462 SetDepth( property.Get< float >() );
2466 case Dali::Actor::Property::POSITION:
2468 SetPosition( property.Get< Vector3 >() );
2472 case Dali::Actor::Property::POSITION_X:
2474 SetX( property.Get< float >() );
2478 case Dali::Actor::Property::POSITION_Y:
2480 SetY( property.Get< float >() );
2484 case Dali::Actor::Property::POSITION_Z:
2486 SetZ( property.Get< float >() );
2490 case Dali::Actor::Property::ORIENTATION:
2492 SetOrientation( property.Get< Quaternion >() );
2496 case Dali::Actor::Property::SCALE:
2498 SetScale( property.Get< Vector3 >() );
2502 case Dali::Actor::Property::SCALE_X:
2504 SetScaleX( property.Get< float >() );
2508 case Dali::Actor::Property::SCALE_Y:
2510 SetScaleY( property.Get< float >() );
2514 case Dali::Actor::Property::SCALE_Z:
2516 SetScaleZ( property.Get< float >() );
2520 case Dali::Actor::Property::VISIBLE:
2522 SetVisible( property.Get< bool >() );
2526 case Dali::Actor::Property::COLOR:
2528 Property::Type type = property.GetType();
2529 if( type == Property::VECTOR3 )
2531 Vector3 color = property.Get< Vector3 >();
2532 SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2534 else if( type == Property::VECTOR4 )
2536 SetColor( property.Get< Vector4 >() );
2541 case Dali::Actor::Property::COLOR_RED:
2543 SetColorRed( property.Get< float >() );
2547 case Dali::Actor::Property::COLOR_GREEN:
2549 SetColorGreen( property.Get< float >() );
2553 case Dali::Actor::Property::COLOR_BLUE:
2555 SetColorBlue( property.Get< float >() );
2559 case Dali::Actor::Property::COLOR_ALPHA:
2560 case Dali::DevelActor::Property::OPACITY:
2563 if( property.Get( value ) )
2565 SetOpacity( value );
2570 case Dali::Actor::Property::NAME:
2572 SetName( property.Get< std::string >() );
2576 case Dali::Actor::Property::SENSITIVE:
2578 SetSensitive( property.Get< bool >() );
2582 case Dali::Actor::Property::LEAVE_REQUIRED:
2584 SetLeaveRequired( property.Get< bool >() );
2588 case Dali::Actor::Property::INHERIT_POSITION:
2590 SetInheritPosition( property.Get< bool >() );
2594 case Dali::Actor::Property::INHERIT_ORIENTATION:
2596 SetInheritOrientation( property.Get< bool >() );
2600 case Dali::Actor::Property::INHERIT_SCALE:
2602 SetInheritScale( property.Get< bool >() );
2606 case Dali::Actor::Property::COLOR_MODE:
2608 ColorMode mode = mColorMode;
2609 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2611 SetColorMode( mode );
2616 case Dali::Actor::Property::DRAW_MODE:
2618 DrawMode::Type mode = mDrawMode;
2619 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2621 SetDrawMode( mode );
2626 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2628 SetSizeModeFactor( property.Get< Vector3 >() );
2632 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2634 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2635 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2637 SetResizePolicy( type, Dimension::WIDTH );
2642 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2644 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2645 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2647 SetResizePolicy( type, Dimension::HEIGHT );
2652 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2654 SizeScalePolicy::Type type = GetSizeScalePolicy();
2655 if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2657 SetSizeScalePolicy( type );
2662 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2664 if( property.Get< bool >() )
2666 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2671 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2673 if( property.Get< bool >() )
2675 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2680 case Dali::Actor::Property::PADDING:
2682 Vector4 padding = property.Get< Vector4 >();
2683 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2684 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2688 case Dali::Actor::Property::MINIMUM_SIZE:
2690 Vector2 size = property.Get< Vector2 >();
2691 SetMinimumSize( size.x, Dimension::WIDTH );
2692 SetMinimumSize( size.y, Dimension::HEIGHT );
2696 case Dali::Actor::Property::MAXIMUM_SIZE:
2698 Vector2 size = property.Get< Vector2 >();
2699 SetMaximumSize( size.x, Dimension::WIDTH );
2700 SetMaximumSize( size.y, Dimension::HEIGHT );
2704 case Dali::DevelActor::Property::SIBLING_ORDER:
2708 if( property.Get( value ) )
2710 SetSiblingOrder( value );
2715 case Dali::Actor::Property::CLIPPING_MODE:
2717 ClippingMode::Type convertedValue = mClippingMode;
2718 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2720 mClippingMode = convertedValue;
2721 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2726 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2729 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2731 mPositionUsesAnchorPoint = value;
2732 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2737 case Dali::Actor::Property::LAYOUT_DIRECTION:
2739 Dali::LayoutDirection::Type direction = mLayoutDirection;
2740 mInheritLayoutDirection = false;
2742 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2744 InheritLayoutDirectionRecursively( this, direction, true );
2749 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2752 if( property.Get( value ) )
2754 SetInheritLayoutDirection( value );
2761 // this can happen in the case of a non-animatable default property so just do nothing
2767 // TODO: This method needs to be removed
2768 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2770 switch( entry.GetType() )
2772 case Property::BOOLEAN:
2774 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2775 DALI_ASSERT_DEBUG( NULL != property );
2777 // property is being used in a separate thread; queue a message to set the property
2778 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2783 case Property::INTEGER:
2785 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2786 DALI_ASSERT_DEBUG( NULL != property );
2788 // property is being used in a separate thread; queue a message to set the property
2789 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2794 case Property::FLOAT:
2796 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2797 DALI_ASSERT_DEBUG( NULL != property );
2799 // property is being used in a separate thread; queue a message to set the property
2800 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2805 case Property::VECTOR2:
2807 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2808 DALI_ASSERT_DEBUG( NULL != property );
2810 // property is being used in a separate thread; queue a message to set the property
2811 if(entry.componentIndex == 0)
2813 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2815 else if(entry.componentIndex == 1)
2817 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2821 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2827 case Property::VECTOR3:
2829 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2830 DALI_ASSERT_DEBUG( NULL != property );
2832 // property is being used in a separate thread; queue a message to set the property
2833 if(entry.componentIndex == 0)
2835 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2837 else if(entry.componentIndex == 1)
2839 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2841 else if(entry.componentIndex == 2)
2843 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2847 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2853 case Property::VECTOR4:
2855 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2856 DALI_ASSERT_DEBUG( NULL != property );
2858 // property is being used in a separate thread; queue a message to set the property
2859 if(entry.componentIndex == 0)
2861 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2863 else if(entry.componentIndex == 1)
2865 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2867 else if(entry.componentIndex == 2)
2869 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2871 else if(entry.componentIndex == 3)
2873 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2877 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2883 case Property::ROTATION:
2885 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2886 DALI_ASSERT_DEBUG( NULL != property );
2888 // property is being used in a separate thread; queue a message to set the property
2889 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2894 case Property::MATRIX:
2896 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2897 DALI_ASSERT_DEBUG( NULL != property );
2899 // property is being used in a separate thread; queue a message to set the property
2900 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2905 case Property::MATRIX3:
2907 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2908 DALI_ASSERT_DEBUG( NULL != property );
2910 // property is being used in a separate thread; queue a message to set the property
2911 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2918 // nothing to do for other types
2923 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2925 Property::Value value;
2927 if( ! GetCachedPropertyValue( index, value ) )
2929 // If property value is not stored in the event-side, then it must be a scene-graph only property
2930 GetCurrentPropertyValue( index, value );
2936 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2938 Property::Value value;
2940 if( ! GetCurrentPropertyValue( index, value ) )
2942 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2943 GetCachedPropertyValue( index, value );
2949 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2951 switch( animationType )
2954 case Animation::BETWEEN:
2958 case Dali::Actor::Property::SIZE:
2960 if( value.Get( mTargetSize ) )
2962 mAnimatedSize = mTargetSize;
2963 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
2965 // Notify deriving classes
2966 OnSizeAnimation( animation, mTargetSize );
2971 case Dali::Actor::Property::SIZE_WIDTH:
2973 if( value.Get( mTargetSize.width ) )
2975 mAnimatedSize.width = mTargetSize.width;
2976 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
2978 // Notify deriving classes
2979 OnSizeAnimation( animation, mTargetSize );
2984 case Dali::Actor::Property::SIZE_HEIGHT:
2986 if( value.Get( mTargetSize.height ) )
2988 mAnimatedSize.height = mTargetSize.height;
2989 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
2991 // Notify deriving classes
2992 OnSizeAnimation( animation, mTargetSize );
2997 case Dali::Actor::Property::SIZE_DEPTH:
2999 if( value.Get( mTargetSize.depth ) )
3001 mAnimatedSize.depth = mTargetSize.depth;
3002 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3004 // Notify deriving classes
3005 OnSizeAnimation( animation, mTargetSize );
3010 case Dali::Actor::Property::POSITION:
3012 value.Get( mTargetPosition );
3016 case Dali::Actor::Property::POSITION_X:
3018 value.Get( mTargetPosition.x );
3022 case Dali::Actor::Property::POSITION_Y:
3024 value.Get( mTargetPosition.y );
3028 case Dali::Actor::Property::POSITION_Z:
3030 value.Get( mTargetPosition.z );
3034 case Dali::Actor::Property::ORIENTATION:
3036 value.Get( mTargetOrientation );
3040 case Dali::Actor::Property::SCALE:
3042 value.Get( mTargetScale );
3046 case Dali::Actor::Property::SCALE_X:
3048 value.Get( mTargetScale.x );
3052 case Dali::Actor::Property::SCALE_Y:
3054 value.Get( mTargetScale.y );
3058 case Dali::Actor::Property::SCALE_Z:
3060 value.Get( mTargetScale.z );
3064 case Dali::Actor::Property::VISIBLE:
3066 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3070 case Dali::Actor::Property::COLOR:
3072 value.Get( mTargetColor );
3076 case Dali::Actor::Property::COLOR_RED:
3078 value.Get( mTargetColor.r );
3082 case Dali::Actor::Property::COLOR_GREEN:
3084 value.Get( mTargetColor.g );
3088 case Dali::Actor::Property::COLOR_BLUE:
3090 value.Get( mTargetColor.b );
3094 case Dali::Actor::Property::COLOR_ALPHA:
3095 case Dali::DevelActor::Property::OPACITY:
3097 value.Get( mTargetColor.a );
3103 // Not an animatable property. Do nothing.
3114 case Dali::Actor::Property::SIZE:
3116 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3118 mAnimatedSize = mTargetSize;
3119 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3121 // Notify deriving classes
3122 OnSizeAnimation( animation, mTargetSize );
3127 case Dali::Actor::Property::SIZE_WIDTH:
3129 if( AdjustValue< float >( mTargetSize.width, value ) )
3131 mAnimatedSize.width = mTargetSize.width;
3132 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3134 // Notify deriving classes
3135 OnSizeAnimation( animation, mTargetSize );
3140 case Dali::Actor::Property::SIZE_HEIGHT:
3142 if( AdjustValue< float >( mTargetSize.height, value ) )
3144 mAnimatedSize.height = mTargetSize.height;
3145 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3147 // Notify deriving classes
3148 OnSizeAnimation( animation, mTargetSize );
3153 case Dali::Actor::Property::SIZE_DEPTH:
3155 if( AdjustValue< float >( mTargetSize.depth, value ) )
3157 mAnimatedSize.depth = mTargetSize.depth;
3158 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3160 // Notify deriving classes
3161 OnSizeAnimation( animation, mTargetSize );
3166 case Dali::Actor::Property::POSITION:
3168 AdjustValue< Vector3 >( mTargetPosition, value );
3172 case Dali::Actor::Property::POSITION_X:
3174 AdjustValue< float >( mTargetPosition.x, value );
3178 case Dali::Actor::Property::POSITION_Y:
3180 AdjustValue< float >( mTargetPosition.y, value );
3184 case Dali::Actor::Property::POSITION_Z:
3186 AdjustValue< float >( mTargetPosition.z, value );
3190 case Dali::Actor::Property::ORIENTATION:
3192 Quaternion relativeValue;
3193 if( value.Get( relativeValue ) )
3195 mTargetOrientation *= relativeValue;
3200 case Dali::Actor::Property::SCALE:
3202 AdjustValue< Vector3 >( mTargetScale, value );
3206 case Dali::Actor::Property::SCALE_X:
3208 AdjustValue< float >( mTargetScale.x, value );
3212 case Dali::Actor::Property::SCALE_Y:
3214 AdjustValue< float >( mTargetScale.y, value );
3218 case Dali::Actor::Property::SCALE_Z:
3220 AdjustValue< float >( mTargetScale.z, value );
3224 case Dali::Actor::Property::VISIBLE:
3226 bool relativeValue = false;
3227 if( value.Get( relativeValue ) )
3229 bool visible = mVisible || relativeValue;
3230 SetVisibleInternal( visible, SendMessage::FALSE );
3235 case Dali::Actor::Property::COLOR:
3237 AdjustValue< Vector4 >( mTargetColor, value );
3241 case Dali::Actor::Property::COLOR_RED:
3243 AdjustValue< float >( mTargetColor.r, value );
3247 case Dali::Actor::Property::COLOR_GREEN:
3249 AdjustValue< float >( mTargetColor.g, value );
3253 case Dali::Actor::Property::COLOR_BLUE:
3255 AdjustValue< float >( mTargetColor.b, value );
3259 case Dali::Actor::Property::COLOR_ALPHA:
3260 case Dali::DevelActor::Property::OPACITY:
3262 AdjustValue< float >( mTargetColor.a, value );
3268 // Not an animatable property. Do nothing.
3277 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3279 const PropertyBase* property( NULL );
3283 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3284 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3285 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3286 case Dali::Actor::Property::SIZE_DEPTH:
3288 property = &GetNode().mSize;
3291 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3292 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3293 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3294 case Dali::Actor::Property::POSITION_Z:
3296 property = &GetNode().mPosition;
3299 case Dali::Actor::Property::ORIENTATION:
3301 property = &GetNode().mOrientation;
3304 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3305 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3306 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3307 case Dali::Actor::Property::SCALE_Z:
3309 property = &GetNode().mScale;
3312 case Dali::Actor::Property::VISIBLE:
3314 property = &GetNode().mVisible;
3317 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3318 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3319 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3320 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3321 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3322 case Dali::DevelActor::Property::OPACITY:
3324 property = &GetNode().mColor;
3334 // not our property, ask base
3335 property = Object::GetSceneObjectAnimatableProperty( index );
3341 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3343 const PropertyInputImpl* property( NULL );
3347 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3348 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3349 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3350 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3352 property = &GetNode().mParentOrigin;
3355 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3356 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3357 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3358 case Dali::Actor::Property::ANCHOR_POINT_Z:
3360 property = &GetNode().mAnchorPoint;
3363 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3364 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3365 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3366 case Dali::Actor::Property::WORLD_POSITION_Z:
3368 property = &GetNode().mWorldPosition;
3371 case Dali::Actor::Property::WORLD_ORIENTATION:
3373 property = &GetNode().mWorldOrientation;
3376 case Dali::Actor::Property::WORLD_SCALE:
3378 property = &GetNode().mWorldScale;
3381 case Dali::Actor::Property::WORLD_COLOR:
3383 property = &GetNode().mWorldColor;
3386 case Dali::Actor::Property::WORLD_MATRIX:
3388 property = &GetNode().mWorldMatrix;
3391 case Dali::DevelActor::Property::CULLED:
3393 property = &GetNode().mCulled;
3403 // reuse animatable property getter as animatable properties are inputs as well
3404 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3405 property = GetSceneObjectAnimatableProperty( index );
3411 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3413 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3417 case Dali::Actor::Property::PARENT_ORIGIN_X:
3418 case Dali::Actor::Property::ANCHOR_POINT_X:
3419 case Dali::Actor::Property::SIZE_WIDTH:
3420 case Dali::Actor::Property::POSITION_X:
3421 case Dali::Actor::Property::WORLD_POSITION_X:
3422 case Dali::Actor::Property::SCALE_X:
3423 case Dali::Actor::Property::COLOR_RED:
3429 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3430 case Dali::Actor::Property::ANCHOR_POINT_Y:
3431 case Dali::Actor::Property::SIZE_HEIGHT:
3432 case Dali::Actor::Property::POSITION_Y:
3433 case Dali::Actor::Property::WORLD_POSITION_Y:
3434 case Dali::Actor::Property::SCALE_Y:
3435 case Dali::Actor::Property::COLOR_GREEN:
3441 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3442 case Dali::Actor::Property::ANCHOR_POINT_Z:
3443 case Dali::Actor::Property::SIZE_DEPTH:
3444 case Dali::Actor::Property::POSITION_Z:
3445 case Dali::Actor::Property::WORLD_POSITION_Z:
3446 case Dali::Actor::Property::SCALE_Z:
3447 case Dali::Actor::Property::COLOR_BLUE:
3453 case Dali::Actor::Property::COLOR_ALPHA:
3454 case Dali::DevelActor::Property::OPACITY:
3466 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3469 componentIndex = Object::GetPropertyComponentIndex( index );
3472 return componentIndex;
3475 void Actor::SetParent( Actor* parent )
3479 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3483 mScene = parent->mScene;
3485 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3488 // Instruct each actor to create a corresponding node in the scene graph
3489 ConnectToStage( parent->GetHierarchyDepth() );
3492 // Resolve the name and index for the child properties if any
3493 ResolveChildProperties();
3495 else // parent being set to NULL
3497 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3501 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3504 // Disconnect the Node & its children from the scene-graph.
3505 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3507 // Instruct each actor to discard pointers to the scene-graph
3508 DisconnectFromStage();
3515 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3518 Actor* actor = dynamic_cast< Actor* >( object );
3522 if( 0 == actionName.compare( ACTION_SHOW ) )
3524 actor->SetVisible( true );
3527 else if( 0 == actionName.compare( ACTION_HIDE ) )
3529 actor->SetVisible( false );
3537 Rect<> Actor::CalculateScreenExtents( ) const
3539 auto screenPosition = GetCurrentScreenPosition();
3540 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3541 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3542 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3543 return { position.x, position.y, size.x, size.y };
3546 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3548 bool valueSet = true;
3552 case Dali::Actor::Property::PARENT_ORIGIN:
3554 value = GetCurrentParentOrigin();
3558 case Dali::Actor::Property::PARENT_ORIGIN_X:
3560 value = GetCurrentParentOrigin().x;
3564 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3566 value = GetCurrentParentOrigin().y;
3570 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3572 value = GetCurrentParentOrigin().z;
3576 case Dali::Actor::Property::ANCHOR_POINT:
3578 value = GetCurrentAnchorPoint();
3582 case Dali::Actor::Property::ANCHOR_POINT_X:
3584 value = GetCurrentAnchorPoint().x;
3588 case Dali::Actor::Property::ANCHOR_POINT_Y:
3590 value = GetCurrentAnchorPoint().y;
3594 case Dali::Actor::Property::ANCHOR_POINT_Z:
3596 value = GetCurrentAnchorPoint().z;
3600 case Dali::Actor::Property::SIZE:
3602 value = GetTargetSize();
3606 case Dali::Actor::Property::SIZE_WIDTH:
3608 value = GetTargetSize().width;
3612 case Dali::Actor::Property::SIZE_HEIGHT:
3614 value = GetTargetSize().height;
3618 case Dali::Actor::Property::SIZE_DEPTH:
3620 value = GetTargetSize().depth;
3624 case Dali::Actor::Property::POSITION:
3626 value = GetTargetPosition();
3630 case Dali::Actor::Property::POSITION_X:
3632 value = GetTargetPosition().x;
3636 case Dali::Actor::Property::POSITION_Y:
3638 value = GetTargetPosition().y;
3642 case Dali::Actor::Property::POSITION_Z:
3644 value = GetTargetPosition().z;
3648 case Dali::Actor::Property::ORIENTATION:
3650 value = mTargetOrientation;
3654 case Dali::Actor::Property::SCALE:
3656 value = mTargetScale;
3660 case Dali::Actor::Property::SCALE_X:
3662 value = mTargetScale.x;
3666 case Dali::Actor::Property::SCALE_Y:
3668 value = mTargetScale.y;
3672 case Dali::Actor::Property::SCALE_Z:
3674 value = mTargetScale.z;
3678 case Dali::Actor::Property::VISIBLE:
3684 case Dali::Actor::Property::COLOR:
3686 value = mTargetColor;
3690 case Dali::Actor::Property::COLOR_RED:
3692 value = mTargetColor.r;
3696 case Dali::Actor::Property::COLOR_GREEN:
3698 value = mTargetColor.g;
3702 case Dali::Actor::Property::COLOR_BLUE:
3704 value = mTargetColor.b;
3708 case Dali::Actor::Property::COLOR_ALPHA:
3709 case Dali::DevelActor::Property::OPACITY:
3711 value = mTargetColor.a;
3715 case Dali::Actor::Property::NAME:
3721 case Dali::Actor::Property::SENSITIVE:
3723 value = IsSensitive();
3727 case Dali::Actor::Property::LEAVE_REQUIRED:
3729 value = GetLeaveRequired();
3733 case Dali::Actor::Property::INHERIT_POSITION:
3735 value = IsPositionInherited();
3739 case Dali::Actor::Property::INHERIT_ORIENTATION:
3741 value = IsOrientationInherited();
3745 case Dali::Actor::Property::INHERIT_SCALE:
3747 value = IsScaleInherited();
3751 case Dali::Actor::Property::COLOR_MODE:
3753 value = GetColorMode();
3757 case Dali::Actor::Property::DRAW_MODE:
3759 value = GetDrawMode();
3763 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3765 value = GetSizeModeFactor();
3769 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3771 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3775 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3777 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3781 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3783 value = GetSizeScalePolicy();
3787 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3789 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3793 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3795 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3799 case Dali::Actor::Property::PADDING:
3801 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3802 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3803 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3807 case Dali::Actor::Property::MINIMUM_SIZE:
3809 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3813 case Dali::Actor::Property::MAXIMUM_SIZE:
3815 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3819 case Dali::Actor::Property::CLIPPING_MODE:
3821 value = mClippingMode;
3825 case Dali::DevelActor::Property::SIBLING_ORDER:
3827 value = static_cast<int>( GetSiblingOrder() );
3831 case Dali::DevelActor::Property::SCREEN_POSITION:
3833 value = GetCurrentScreenPosition();
3837 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3839 value = mPositionUsesAnchorPoint;
3843 case Dali::Actor::Property::LAYOUT_DIRECTION:
3845 value = mLayoutDirection;
3849 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3851 value = IsLayoutDirectionInherited();
3857 // Must be a scene-graph only property
3866 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3868 bool valueSet = true;
3872 case Dali::Actor::Property::SIZE:
3874 value = GetCurrentSize();
3878 case Dali::Actor::Property::SIZE_WIDTH:
3880 value = GetCurrentSize().width;
3884 case Dali::Actor::Property::SIZE_HEIGHT:
3886 value = GetCurrentSize().height;
3890 case Dali::Actor::Property::SIZE_DEPTH:
3892 value = GetCurrentSize().depth;
3896 case Dali::Actor::Property::POSITION:
3898 value = GetCurrentPosition();
3902 case Dali::Actor::Property::POSITION_X:
3904 value = GetCurrentPosition().x;
3908 case Dali::Actor::Property::POSITION_Y:
3910 value = GetCurrentPosition().y;
3914 case Dali::Actor::Property::POSITION_Z:
3916 value = GetCurrentPosition().z;
3920 case Dali::Actor::Property::WORLD_POSITION:
3922 value = GetCurrentWorldPosition();
3926 case Dali::Actor::Property::WORLD_POSITION_X:
3928 value = GetCurrentWorldPosition().x;
3932 case Dali::Actor::Property::WORLD_POSITION_Y:
3934 value = GetCurrentWorldPosition().y;
3938 case Dali::Actor::Property::WORLD_POSITION_Z:
3940 value = GetCurrentWorldPosition().z;
3944 case Dali::Actor::Property::ORIENTATION:
3946 value = GetCurrentOrientation();
3950 case Dali::Actor::Property::WORLD_ORIENTATION:
3952 value = GetCurrentWorldOrientation();
3956 case Dali::Actor::Property::SCALE:
3958 value = GetCurrentScale();
3962 case Dali::Actor::Property::SCALE_X:
3964 value = GetCurrentScale().x;
3968 case Dali::Actor::Property::SCALE_Y:
3970 value = GetCurrentScale().y;
3974 case Dali::Actor::Property::SCALE_Z:
3976 value = GetCurrentScale().z;
3980 case Dali::Actor::Property::WORLD_SCALE:
3982 value = GetCurrentWorldScale();
3986 case Dali::Actor::Property::COLOR:
3988 value = GetCurrentColor();
3992 case Dali::Actor::Property::COLOR_RED:
3994 value = GetCurrentColor().r;
3998 case Dali::Actor::Property::COLOR_GREEN:
4000 value = GetCurrentColor().g;
4004 case Dali::Actor::Property::COLOR_BLUE:
4006 value = GetCurrentColor().b;
4010 case Dali::Actor::Property::COLOR_ALPHA:
4011 case Dali::DevelActor::Property::OPACITY:
4013 value = GetCurrentColor().a;
4017 case Dali::Actor::Property::WORLD_COLOR:
4019 value = GetCurrentWorldColor();
4023 case Dali::Actor::Property::WORLD_MATRIX:
4025 value = GetCurrentWorldMatrix();
4029 case Dali::Actor::Property::VISIBLE:
4031 value = IsVisible();
4035 case DevelActor::Property::CULLED:
4037 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4043 // Must be an event-side only property
4052 void Actor::EnsureRelayoutData()
4054 // Assign relayout data.
4055 if( !mRelayoutData )
4057 mRelayoutData = new RelayoutData();
4061 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4063 // Check if actor is dependent on parent
4064 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4066 if( ( dimension & ( 1 << i ) ) )
4068 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4069 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4079 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4081 // Check if actor is dependent on children
4082 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4084 if( ( dimension & ( 1 << i ) ) )
4086 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4087 switch( resizePolicy )
4089 case ResizePolicy::FIT_TO_CHILDREN:
4090 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4106 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4108 return Actor::RelayoutDependentOnChildren( dimension );
4111 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4113 // Check each possible dimension and see if it is dependent on the input one
4114 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4116 if( dimension & ( 1 << i ) )
4118 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4125 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4127 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4129 if( dimension & ( 1 << i ) )
4131 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4136 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4138 // If more than one dimension is requested, just return the first one found
4139 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4141 if( ( dimension & ( 1 << i ) ) )
4143 return mRelayoutData->negotiatedDimensions[ i ];
4147 return 0.0f; // Default
4150 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4152 EnsureRelayoutData();
4154 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4156 if( dimension & ( 1 << i ) )
4158 mRelayoutData->dimensionPadding[ i ] = padding;
4163 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4165 if ( mRelayoutData )
4167 // If more than one dimension is requested, just return the first one found
4168 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4170 if( ( dimension & ( 1 << i ) ) )
4172 return mRelayoutData->dimensionPadding[ i ];
4177 return GetDefaultDimensionPadding();
4180 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4182 EnsureRelayoutData();
4184 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4186 if( dimension & ( 1 << i ) )
4188 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4193 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4195 if ( mRelayoutData )
4197 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4199 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4209 float Actor::GetHeightForWidthBase( float width )
4211 float height = 0.0f;
4213 const Vector3 naturalSize = GetNaturalSize();
4214 if( naturalSize.width > 0.0f )
4216 height = naturalSize.height * width / naturalSize.width;
4218 else // we treat 0 as 1:1 aspect ratio
4226 float Actor::GetWidthForHeightBase( float height )
4230 const Vector3 naturalSize = GetNaturalSize();
4231 if( naturalSize.height > 0.0f )
4233 width = naturalSize.width * height / naturalSize.height;
4235 else // we treat 0 as 1:1 aspect ratio
4243 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4245 // Fill to parent, taking size mode factor into account
4246 switch( child.GetResizePolicy( dimension ) )
4248 case ResizePolicy::FILL_TO_PARENT:
4250 return GetLatestSize( dimension );
4253 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4255 return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4258 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4260 return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4265 return GetLatestSize( dimension );
4270 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4272 // Can be overridden in derived class
4273 return CalculateChildSizeBase( child, dimension );
4276 float Actor::GetHeightForWidth( float width )
4278 // Can be overridden in derived class
4279 return GetHeightForWidthBase( width );
4282 float Actor::GetWidthForHeight( float height )
4284 // Can be overridden in derived class
4285 return GetWidthForHeightBase( height );
4288 float Actor::GetLatestSize( Dimension::Type dimension ) const
4290 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4293 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4295 Vector2 padding = GetPadding( dimension );
4297 return GetLatestSize( dimension ) + padding.x + padding.y;
4300 float Actor::NegotiateFromParent( Dimension::Type dimension )
4302 Actor* parent = GetParent();
4305 Vector2 padding( GetPadding( dimension ) );
4306 Vector2 parentPadding( parent->GetPadding( dimension ) );
4307 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4313 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4315 float maxDimensionPoint = 0.0f;
4317 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4319 ActorPtr child = GetChildAt( i );
4321 if( !child->RelayoutDependentOnParent( dimension ) )
4323 // Calculate the min and max points that the children range across
4324 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4325 float dimensionSize = child->GetRelayoutSize( dimension );
4326 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4330 return maxDimensionPoint;
4333 float Actor::GetSize( Dimension::Type dimension ) const
4335 return GetDimensionValue( mTargetSize, dimension );
4338 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4340 return GetDimensionValue( GetNaturalSize(), dimension );
4343 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4345 switch( GetResizePolicy( dimension ) )
4347 case ResizePolicy::USE_NATURAL_SIZE:
4349 return GetNaturalSize( dimension );
4352 case ResizePolicy::FIXED:
4354 return GetDimensionValue( GetPreferredSize(), dimension );
4357 case ResizePolicy::USE_ASSIGNED_SIZE:
4359 return GetDimensionValue( maximumSize, dimension );
4362 case ResizePolicy::FILL_TO_PARENT:
4363 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4364 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4366 return NegotiateFromParent( dimension );
4369 case ResizePolicy::FIT_TO_CHILDREN:
4371 return NegotiateFromChildren( dimension );
4374 case ResizePolicy::DIMENSION_DEPENDENCY:
4376 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4379 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4381 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4384 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4386 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4398 return 0.0f; // Default
4401 float Actor::ClampDimension( float size, Dimension::Type dimension )
4403 const float minSize = GetMinimumSize( dimension );
4404 const float maxSize = GetMaximumSize( dimension );
4406 return std::max( minSize, std::min( size, maxSize ) );
4409 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4411 // Check if it needs to be negotiated
4412 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4414 // Check that we havn't gotten into an infinite loop
4415 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4416 bool recursionFound = false;
4417 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4419 if( *it == searchActor )
4421 recursionFound = true;
4426 if( !recursionFound )
4428 // Record the path that we have taken
4429 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4431 // Dimension dependency check
4432 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4434 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4436 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4438 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4442 // Parent dependency check
4443 Actor* parent = GetParent();
4444 if( parent && RelayoutDependentOnParent( dimension ) )
4446 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4449 // Children dependency check
4450 if( RelayoutDependentOnChildren( dimension ) )
4452 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4454 ActorPtr child = GetChildAt( i );
4456 // Only relayout child first if it is not dependent on this actor
4457 if( !child->RelayoutDependentOnParent( dimension ) )
4459 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4464 // For deriving classes
4465 OnCalculateRelayoutSize( dimension );
4467 // All dependencies checked, calculate the size and set negotiated flag
4468 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4470 SetNegotiatedDimension( newSize, dimension );
4471 SetLayoutNegotiated( true, dimension );
4473 // For deriving classes
4474 OnLayoutNegotiated( newSize, dimension );
4476 // This actor has been successfully processed, pop it off the recursion stack
4477 recursionStack.pop_back();
4481 // TODO: Break infinite loop
4482 SetLayoutNegotiated( true, dimension );
4487 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4489 // Negotiate all dimensions that require it
4490 ActorDimensionStack recursionStack;
4492 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4494 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4497 NegotiateDimension( dimension, allocatedSize, recursionStack );
4501 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4503 switch( mRelayoutData->sizeSetPolicy )
4505 case SizeScalePolicy::USE_SIZE_SET:
4510 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4512 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4513 const Vector3 naturalSize = GetNaturalSize();
4514 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4516 const float sizeRatio = size.width / size.height;
4517 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4519 if( naturalSizeRatio < sizeRatio )
4521 return Vector2( naturalSizeRatio * size.height, size.height );
4523 else if( naturalSizeRatio > sizeRatio )
4525 return Vector2( size.width, size.width / naturalSizeRatio );
4536 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4538 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4539 const Vector3 naturalSize = GetNaturalSize();
4540 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4542 const float sizeRatio = size.width / size.height;
4543 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4545 if( naturalSizeRatio < sizeRatio )
4547 return Vector2( size.width, size.width / naturalSizeRatio );
4549 else if( naturalSizeRatio > sizeRatio )
4551 return Vector2( naturalSizeRatio * size.height, size.height );
4570 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4572 // Do the set actor size
4573 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4575 // Adjust for size set policy
4576 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4578 // Lock the flag to stop recursive relayouts on set size
4579 mRelayoutData->insideRelayout = true;
4580 SetSize( negotiatedSize );
4581 mRelayoutData->insideRelayout = false;
4583 // Clear flags for all dimensions
4584 SetLayoutDirty( false );
4586 // Give deriving classes a chance to respond
4587 OnRelayout( negotiatedSize, container );
4589 if( !mOnRelayoutSignal.Empty() )
4591 Dali::Actor handle( this );
4592 mOnRelayoutSignal.Emit( handle );
4596 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4598 // Force a size negotiation for actors that has assigned size during relayout
4599 // This is required as otherwise the flags that force a relayout will not
4600 // necessarilly be set. This will occur if the actor has already been laid out.
4601 // The dirty flags are then cleared. Then if the actor is added back into the
4602 // relayout container afterwards, the dirty flags would still be clear...
4603 // causing a relayout to be skipped. Here we force any actors added to the
4604 // container to be relayed out.
4605 DALI_LOG_TIMER_START( NegSizeTimer1 );
4607 if( GetUseAssignedSize(Dimension::WIDTH ) )
4609 SetLayoutNegotiated( false, Dimension::WIDTH );
4611 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4613 SetLayoutNegotiated( false, Dimension::HEIGHT );
4616 // Do the negotiation
4617 NegotiateDimensions( allocatedSize );
4619 // Set the actor size
4620 SetNegotiatedSize( container );
4622 // Negotiate down to children
4623 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4625 ActorPtr child = GetChildAt( i );
4627 // Forces children that have already been laid out to be relayed out
4628 // if they have assigned size during relayout.
4629 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4631 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4632 child->SetLayoutDirty(true, Dimension::WIDTH);
4635 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4637 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4638 child->SetLayoutDirty(true, Dimension::HEIGHT);
4641 // Only relayout if required
4642 if( child->RelayoutRequired() )
4644 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4647 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4650 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4654 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4656 if( dimension & ( 1 << i ) )
4658 mRelayoutData->useAssignedSize[ i ] = use;
4664 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4666 if ( mRelayoutData )
4668 // If more than one dimension is requested, just return the first one found
4669 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4671 if( dimension & ( 1 << i ) )
4673 return mRelayoutData->useAssignedSize[ i ];
4681 void Actor::RelayoutRequest( Dimension::Type dimension )
4683 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4684 if( relayoutController )
4686 Dali::Actor self( this );
4687 relayoutController->RequestRelayout( self, dimension );
4691 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4695 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4699 void Actor::SetPreferredSize( const Vector2& size )
4701 EnsureRelayoutData();
4703 // If valid width or height, then set the resize policy to FIXED
4704 // A 0 width or height may also be required so if the resize policy has not been changed, i.e. is still set to DEFAULT,
4705 // then change to FIXED as well
4707 if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4709 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4712 if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4714 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4717 mRelayoutData->preferredSize = size;
4719 mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4724 Vector2 Actor::GetPreferredSize() const
4726 if ( mRelayoutData )
4728 return Vector2( mRelayoutData->preferredSize );
4731 return GetDefaultPreferredSize();
4734 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4736 EnsureRelayoutData();
4738 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4740 if( dimension & ( 1 << i ) )
4742 mRelayoutData->minimumSize[ i ] = size;
4749 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4751 if ( mRelayoutData )
4753 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4755 if( dimension & ( 1 << i ) )
4757 return mRelayoutData->minimumSize[ i ];
4762 return 0.0f; // Default
4765 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4767 EnsureRelayoutData();
4769 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4771 if( dimension & ( 1 << i ) )
4773 mRelayoutData->maximumSize[ i ] = size;
4780 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4782 if ( mRelayoutData )
4784 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4786 if( dimension & ( 1 << i ) )
4788 return mRelayoutData->maximumSize[ i ];
4793 return FLT_MAX; // Default
4796 Object* Actor::GetParentObject() const
4801 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4803 if( mVisible != visible )
4805 if( sendMessage == SendMessage::TRUE )
4807 // node is being used in a separate thread; queue a message to set the value & base value
4808 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4813 // Emit the signal on this actor and all its children
4814 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4818 void Actor::SetSiblingOrder( uint32_t order )
4822 ActorContainer& siblings = *(mParent->mChildren);
4823 uint32_t currentOrder = GetSiblingOrder();
4825 if( order != currentOrder )
4831 else if( order < siblings.size() -1 )
4833 if( order > currentOrder )
4835 RaiseAbove( *siblings[order] );
4839 LowerBelow( *siblings[order] );
4850 uint32_t Actor::GetSiblingOrder() const
4856 ActorContainer& siblings = *(mParent->mChildren);
4857 for( std::size_t i = 0; i < siblings.size(); ++i )
4859 if( siblings[i] == this )
4861 order = static_cast<uint32_t>( i );
4870 void Actor::RequestRebuildDepthTree()
4876 mScene->RequestRebuildDepthTree();
4885 ActorContainer& siblings = *(mParent->mChildren);
4886 if( siblings.back() != this ) // If not already at end
4888 for( std::size_t i=0; i<siblings.size(); ++i )
4890 if( siblings[i] == this )
4893 ActorPtr next = siblings[i+1];
4894 siblings[i+1] = this;
4901 Dali::Actor handle( this );
4902 mParent->mChildOrderChangedSignal.Emit( handle );
4904 RequestRebuildDepthTree();
4908 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4916 ActorContainer& siblings = *(mParent->mChildren);
4917 if( siblings.front() != this ) // If not already at beginning
4919 for( std::size_t i=1; i<siblings.size(); ++i )
4921 if( siblings[i] == this )
4923 // Swap with previous
4924 ActorPtr previous = siblings[i-1];
4925 siblings[i-1] = this;
4926 siblings[i] = previous;
4932 Dali::Actor handle( this );
4933 mParent->mChildOrderChangedSignal.Emit( handle );
4935 RequestRebuildDepthTree();
4939 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4943 void Actor::RaiseToTop()
4947 ActorContainer& siblings = *(mParent->mChildren);
4948 if( siblings.back() != this ) // If not already at end
4950 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4951 if( iter != siblings.end() )
4953 siblings.erase(iter);
4954 siblings.push_back(ActorPtr(this));
4958 Dali::Actor handle( this );
4959 mParent->mChildOrderChangedSignal.Emit( handle );
4961 RequestRebuildDepthTree();
4965 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4969 void Actor::LowerToBottom()
4973 ActorContainer& siblings = *(mParent->mChildren);
4974 if( siblings.front() != this ) // If not already at bottom,
4976 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4978 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4979 if( iter != siblings.end() )
4981 siblings.erase(iter);
4982 siblings.insert(siblings.begin(), thisPtr);
4986 Dali::Actor handle( this );
4987 mParent->mChildOrderChangedSignal.Emit( handle );
4989 RequestRebuildDepthTree();
4993 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4997 void Actor::RaiseAbove( Internal::Actor& target )
5001 ActorContainer& siblings = *(mParent->mChildren);
5002 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5004 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5006 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5007 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5008 if( thisIter < targetIter )
5010 siblings.erase(thisIter);
5011 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5012 // invalidate thisIter)
5013 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5015 siblings.insert(targetIter, thisPtr);
5018 Dali::Actor handle( this );
5019 mParent->mChildOrderChangedSignal.Emit( handle );
5021 RequestRebuildDepthTree();
5026 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5030 void Actor::LowerBelow( Internal::Actor& target )
5034 ActorContainer& siblings = *(mParent->mChildren);
5035 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5037 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5039 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5040 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5042 if( thisIter > targetIter )
5044 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5045 siblings.insert(targetIter, thisPtr);
5048 Dali::Actor handle( this );
5049 mParent->mChildOrderChangedSignal.Emit( handle );
5051 RequestRebuildDepthTree();
5056 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5060 void Actor::SetScene( Scene& scene )
5065 Scene& Actor::GetScene() const
5070 void Actor::SetInheritLayoutDirection( bool inherit )
5072 if( mInheritLayoutDirection != inherit )
5074 mInheritLayoutDirection = inherit;
5076 if( inherit && mParent )
5078 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5083 bool Actor::IsLayoutDirectionInherited() const
5085 return mInheritLayoutDirection;
5088 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5090 if( actor && ( actor->mInheritLayoutDirection || set ) )
5092 if( actor->mLayoutDirection != direction )
5094 actor->mLayoutDirection = direction;
5095 actor->EmitLayoutDirectionChangedSignal( direction );
5096 actor->RelayoutRequest();
5099 if( actor->GetChildCount() > 0 )
5101 ActorContainer& children = actor->GetChildrenInternal();
5102 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5104 InheritLayoutDirectionRecursively( *iter, direction );
5110 } // namespace Internal