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", STRING, 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", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
199 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
200 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
201 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
202 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
203 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
204 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
205 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
206 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
207 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
208 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
209 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
210 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
211 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
212 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
213 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
214 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
215 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
216 DALI_PROPERTY( "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 );
1160 void Actor::SetHeight( float height )
1162 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1164 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1165 mRelayoutData->preferredSize.height = height;
1169 mTargetSize.height = height;
1171 // node is being used in a separate thread; queue a message to set the value & base value
1172 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1178 void Actor::SetDepth( float depth )
1180 mTargetSize.depth = depth;
1182 // node is being used in a separate thread; queue a message to set the value & base value
1183 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1186 Vector3 Actor::GetTargetSize() const
1188 Vector3 size = mTargetSize;
1190 // Should return preferred size if size is fixed as set by SetSize
1191 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1193 size.width = GetPreferredSize().width;
1195 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1197 size.height = GetPreferredSize().height;
1203 const Vector3& Actor::GetCurrentSize() const
1205 // node is being used in a separate thread; copy the value from the previous update
1206 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1209 Vector3 Actor::GetNaturalSize() const
1211 // It is up to deriving classes to return the appropriate natural size
1212 return Vector3( 0.0f, 0.0f, 0.0f );
1215 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1217 EnsureRelayoutData();
1219 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1220 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1222 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1224 if( dimension & ( 1 << i ) )
1226 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1228 mRelayoutData->useAssignedSize[ i ] = true;
1232 mRelayoutData->resizePolicies[ i ] = policy;
1233 mRelayoutData->useAssignedSize[ i ] = false;
1238 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1240 if( dimension & Dimension::WIDTH )
1242 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1245 if( dimension & Dimension::HEIGHT )
1247 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1251 // If calling SetResizePolicy, assume we want relayout enabled
1252 SetRelayoutEnabled( true );
1254 // If the resize policy is set to be FIXED, the preferred size
1255 // should be overrided by the target size. Otherwise the target
1256 // size should be overrided by the preferred size.
1258 if( dimension & Dimension::WIDTH )
1260 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1262 mRelayoutData->preferredSize.width = mTargetSize.width;
1264 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1266 mTargetSize.width = mRelayoutData->preferredSize.width;
1270 if( dimension & Dimension::HEIGHT )
1272 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1274 mRelayoutData->preferredSize.height = mTargetSize.height;
1276 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1278 mTargetSize.height = mRelayoutData->preferredSize.height;
1282 OnSetResizePolicy( policy, dimension );
1284 // Trigger relayout on this control
1288 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1290 if ( mRelayoutData )
1292 // If more than one dimension is requested, just return the first one found
1293 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1295 if( ( dimension & ( 1 << i ) ) )
1297 if( mRelayoutData->useAssignedSize[ i ] )
1299 return ResizePolicy::USE_ASSIGNED_SIZE;
1303 return mRelayoutData->resizePolicies[ i ];
1309 return ResizePolicy::DEFAULT;
1312 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1314 EnsureRelayoutData();
1316 mRelayoutData->sizeSetPolicy = policy;
1318 // Trigger relayout on this control
1322 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1324 if ( mRelayoutData )
1326 return mRelayoutData->sizeSetPolicy;
1329 return DEFAULT_SIZE_SCALE_POLICY;
1332 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1334 EnsureRelayoutData();
1336 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1338 if( dimension & ( 1 << i ) )
1340 mRelayoutData->dimensionDependencies[ i ] = dependency;
1345 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1347 if ( mRelayoutData )
1349 // If more than one dimension is requested, just return the first one found
1350 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1352 if( ( dimension & ( 1 << i ) ) )
1354 return mRelayoutData->dimensionDependencies[ i ];
1359 return Dimension::ALL_DIMENSIONS; // Default
1362 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1364 // If relayout data has not been allocated yet and the client is requesting
1365 // to disable it, do nothing
1366 if( mRelayoutData || relayoutEnabled )
1368 EnsureRelayoutData();
1370 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1372 mRelayoutData->relayoutEnabled = relayoutEnabled;
1376 bool Actor::IsRelayoutEnabled() const
1378 // Assume that if relayout data has not been allocated yet then
1379 // relayout is disabled
1380 return mRelayoutData && mRelayoutData->relayoutEnabled;
1383 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1385 EnsureRelayoutData();
1387 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1389 if( dimension & ( 1 << i ) )
1391 mRelayoutData->dimensionDirty[ i ] = dirty;
1396 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1398 if ( mRelayoutData )
1400 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1402 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1412 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1414 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1417 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1419 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1422 uint32_t Actor::AddRenderer( Renderer& renderer )
1426 mRenderers = new RendererContainer;
1429 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1430 RendererPtr rendererPtr = RendererPtr( &renderer );
1431 mRenderers->push_back( rendererPtr );
1432 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1436 uint32_t Actor::GetRendererCount() const
1438 uint32_t rendererCount(0);
1441 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1444 return rendererCount;
1447 RendererPtr Actor::GetRendererAt( uint32_t index )
1449 RendererPtr renderer;
1450 if( index < GetRendererCount() )
1452 renderer = ( *mRenderers )[ index ];
1458 void Actor::RemoveRenderer( Renderer& renderer )
1462 RendererIter end = mRenderers->end();
1463 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1465 if( (*iter).Get() == &renderer )
1467 mRenderers->erase( iter );
1468 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1475 void Actor::RemoveRenderer( uint32_t index )
1477 if( index < GetRendererCount() )
1479 RendererPtr renderer = ( *mRenderers )[ index ];
1480 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1481 mRenderers->erase( mRenderers->begin()+index );
1485 bool Actor::IsOverlay() const
1487 return ( DrawMode::OVERLAY_2D == mDrawMode );
1490 void Actor::SetDrawMode( DrawMode::Type drawMode )
1492 // this flag is not animatable so keep the value
1493 mDrawMode = drawMode;
1495 // node is being used in a separate thread; queue a message to set the value
1496 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1499 DrawMode::Type Actor::GetDrawMode() const
1504 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1506 // only valid when on-stage
1507 if( mScene && OnStage() )
1509 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1511 Vector2 converted( screenX, screenY );
1513 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1514 uint32_t taskCount = taskList.GetTaskCount();
1515 for( uint32_t i = taskCount; i > 0; --i )
1517 RenderTaskPtr task = taskList.GetTask( i - 1 );
1518 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1520 // found a task where this conversion was ok so return
1528 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1530 bool retval = false;
1531 // only valid when on-stage
1534 CameraActor* camera = renderTask.GetCameraActor();
1538 renderTask.GetViewport( viewport );
1540 // need to translate coordinates to render tasks coordinate space
1541 Vector2 converted( screenX, screenY );
1542 if( renderTask.TranslateCoordinates( converted ) )
1544 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1551 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1553 // Early-out if not on stage
1559 // Get the ModelView matrix
1561 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1563 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1564 Matrix invertedMvp( false/*don't init*/);
1565 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1566 bool success = invertedMvp.Invert();
1568 // Convert to GL coordinates
1569 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1574 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1581 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1587 if( XyPlaneIntersect( nearPos, farPos, local ) )
1589 Vector3 size = GetCurrentSize();
1590 localX = local.x + size.x * 0.5f;
1591 localY = local.y + size.y * 0.5f;
1602 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1605 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1607 Mathematical Formulation
1609 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1611 ( p - c ) dot ( p - c ) = r^2
1613 Given a ray with a point of origin 'o', and a direction vector 'd':
1615 ray(t) = o + td, t >= 0
1617 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1619 (o + td - c ) dot ( o + td - c ) = r^2
1621 To solve for t we first expand the above into a more recognisable quadratic equation form
1623 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1632 B = 2( o - c ) dot d
1633 C = ( o - c ) dot ( o - c ) - r^2
1635 which can be solved using a standard quadratic formula.
1637 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1639 Practical Simplification
1641 In a renderer, we often differentiate between world space and object space. In the object space
1642 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1643 into object space, the mathematical solution presented above can be simplified significantly.
1645 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1649 and we can find the t at which the (transformed) ray intersects the sphere by
1651 ( o + td ) dot ( o + td ) = r^2
1653 According to the reasoning above, we expand the above quadratic equation into the general form
1657 which now has coefficients:
1664 // Early-out if not on stage
1670 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1672 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1673 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1674 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1676 // Compute the radius is not needed, square radius it's enough.
1677 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1679 // Scale the sphere.
1680 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1682 const float width = size.width * scale.width;
1683 const float height = size.height * scale.height;
1685 float squareSphereRadius = 0.5f * ( width * width + height * height );
1687 float a = rayDir.Dot( rayDir ); // a
1688 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1689 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1691 return ( b2 * b2 - a * c ) >= 0.f;
1694 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1700 // Transforms the ray to the local reference system.
1701 // Calculate the inverse of Model matrix
1702 Matrix invModelMatrix( false/*don't init*/);
1704 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1705 invModelMatrix = GetNode().GetWorldMatrix(0);
1706 invModelMatrix.Invert();
1708 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1709 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1711 // Test with the actor's XY plane (Normal = 0 0 1 1).
1713 float a = -rayOriginLocal.z;
1714 float b = rayDirLocal.z;
1716 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1718 // Ray travels distance * rayDirLocal to intersect with plane.
1721 const Vector3& size = GetNode().GetSize( bufferIndex );
1723 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1724 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1726 // Test with the actor's geometry.
1727 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1734 void Actor::SetLeaveRequired( bool required )
1736 mLeaveRequired = required;
1739 bool Actor::GetLeaveRequired() const
1741 return mLeaveRequired;
1744 void Actor::SetKeyboardFocusable( bool focusable )
1746 mKeyboardFocusable = focusable;
1749 bool Actor::IsKeyboardFocusable() const
1751 return mKeyboardFocusable;
1754 bool Actor::GetTouchRequired() const
1756 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1759 bool Actor::GetHoverRequired() const
1761 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1764 bool Actor::GetWheelEventRequired() const
1766 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1769 bool Actor::IsHittable() const
1771 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1774 ActorGestureData& Actor::GetGestureData()
1776 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1777 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1778 if( NULL == mGestureData )
1780 mGestureData = new ActorGestureData;
1782 return *mGestureData;
1785 bool Actor::IsGestureRequred( DevelGesture::Type type ) const
1787 return mGestureData && mGestureData->IsGestureRequred( type );
1790 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1792 bool consumed = false;
1794 if( !mTouchSignal.Empty() )
1796 Dali::Actor handle( this );
1797 consumed = mTouchSignal.Emit( handle, touch );
1800 if( !mTouchedSignal.Empty() )
1802 Dali::Actor handle( this );
1803 consumed |= mTouchedSignal.Emit( handle, event );
1808 // Notification for derived classes
1809 consumed = OnTouchEvent( event ); // TODO
1815 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1817 bool consumed = false;
1819 if( !mHoveredSignal.Empty() )
1821 Dali::Actor handle( this );
1822 consumed = mHoveredSignal.Emit( handle, event );
1827 // Notification for derived classes
1828 consumed = OnHoverEvent( event );
1834 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1836 bool consumed = false;
1838 if( !mWheelEventSignal.Empty() )
1840 Dali::Actor handle( this );
1841 consumed = mWheelEventSignal.Emit( handle, event );
1846 // Notification for derived classes
1847 consumed = OnWheelEvent( event );
1853 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1855 if( ! mVisibilityChangedSignal.Empty() )
1857 Dali::Actor handle( this );
1858 mVisibilityChangedSignal.Emit( handle, visible, type );
1862 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1864 if( ! mLayoutDirectionChangedSignal.Empty() )
1866 Dali::Actor handle( this );
1867 mLayoutDirectionChangedSignal.Emit( handle, type );
1871 void Actor::EmitChildAddedSignal( Actor& child )
1873 if( ! mChildAddedSignal.Empty() )
1875 Dali::Actor handle( &child );
1876 mChildAddedSignal.Emit( handle );
1880 void Actor::EmitChildRemovedSignal( Actor& child )
1882 if( ! mChildRemovedSignal.Empty() )
1884 Dali::Actor handle( &child );
1885 mChildRemovedSignal.Emit( handle );
1889 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1891 return mTouchedSignal;
1894 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1896 return mTouchSignal;
1899 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1901 return mHoveredSignal;
1904 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1906 return mWheelEventSignal;
1909 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1911 return mOnStageSignal;
1914 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1916 return mOffStageSignal;
1919 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1921 return mOnRelayoutSignal;
1924 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1926 return mVisibilityChangedSignal;
1929 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1931 return mLayoutDirectionChangedSignal;
1934 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1936 return mChildAddedSignal;
1939 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1941 return mChildRemovedSignal;
1944 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1946 return mChildOrderChangedSignal;
1949 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1951 bool connected( true );
1952 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1954 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1956 actor->TouchedSignal().Connect( tracker, functor );
1958 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1960 actor->HoveredSignal().Connect( tracker, functor );
1962 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1964 actor->WheelEventSignal().Connect( tracker, functor );
1966 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1968 actor->OnStageSignal().Connect( tracker, functor );
1970 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1972 actor->OffStageSignal().Connect( tracker, functor );
1974 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1976 actor->OnRelayoutSignal().Connect( tracker, functor );
1978 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1980 actor->TouchSignal().Connect( tracker, functor );
1982 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
1984 actor->VisibilityChangedSignal().Connect( tracker, functor );
1986 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
1988 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
1990 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
1992 actor->ChildAddedSignal().Connect( tracker, functor );
1994 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
1996 actor->ChildRemovedSignal().Connect( tracker, functor );
2000 // signalName does not match any signal
2007 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2013 mParentOrigin( NULL ),
2014 mAnchorPoint( NULL ),
2015 mRelayoutData( NULL ),
2016 mGestureData( NULL ),
2020 mWheelEventSignal(),
2023 mOnRelayoutSignal(),
2024 mVisibilityChangedSignal(),
2025 mLayoutDirectionChangedSignal(),
2026 mChildAddedSignal(),
2027 mChildRemovedSignal(),
2028 mChildOrderChangedSignal(),
2029 mTargetOrientation( Quaternion::IDENTITY ),
2030 mTargetColor( Color::WHITE ),
2031 mTargetSize( Vector3::ZERO ),
2032 mTargetPosition( Vector3::ZERO ),
2033 mTargetScale( Vector3::ONE ),
2037 mIsRoot( ROOT_LAYER == derivedType ),
2038 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2039 mIsOnStage( false ),
2041 mLeaveRequired( false ),
2042 mKeyboardFocusable( false ),
2043 mDerivedRequiresTouch( false ),
2044 mDerivedRequiresHover( false ),
2045 mDerivedRequiresWheelEvent( false ),
2046 mOnStageSignalled( false ),
2047 mInsideOnSizeSet( false ),
2048 mInheritPosition( true ),
2049 mInheritOrientation( true ),
2050 mInheritScale( true ),
2051 mPositionUsesAnchorPoint( true ),
2053 mInheritLayoutDirection( true ),
2054 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2055 mDrawMode( DrawMode::NORMAL ),
2056 mColorMode( Node::DEFAULT_COLOR_MODE ),
2057 mClippingMode( ClippingMode::DISABLED )
2061 void Actor::Initialize()
2065 GetEventThreadServices().RegisterObject( this );
2070 // Remove mParent pointers from children even if we're destroying core,
2071 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2074 ActorConstIter endIter = mChildren->end();
2075 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2077 (*iter)->SetParent( NULL );
2083 // Guard to allow handle destruction after Core has been destroyed
2084 if( EventThreadServices::IsCoreRunning() )
2086 // Root layer will destroy its node in its own destructor
2089 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2091 GetEventThreadServices().UnregisterObject( this );
2095 // Cleanup optional gesture data
2096 delete mGestureData;
2098 // Cleanup optional parent origin and anchor
2099 delete mParentOrigin;
2100 delete mAnchorPoint;
2102 // Delete optional relayout data
2103 delete mRelayoutData;
2106 void Actor::ConnectToStage( uint32_t parentDepth )
2108 // This container is used instead of walking the Actor hierarchy.
2109 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2110 ActorContainer connectionList;
2114 mScene->RequestRebuildDepthTree();
2117 // This stage is atomic i.e. not interrupted by user callbacks.
2118 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2120 // Notify applications about the newly connected actors.
2121 const ActorIter endIter = connectionList.end();
2122 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2124 (*iter)->NotifyStageConnection();
2130 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2132 DALI_ASSERT_ALWAYS( !OnStage() );
2135 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2137 ConnectToSceneGraph();
2139 // Notification for internal derived classes
2140 OnStageConnectionInternal();
2142 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2143 connectionList.push_back( ActorPtr( this ) );
2145 // Recursively connect children
2148 ActorConstIter endIter = mChildren->end();
2149 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2151 (*iter)->SetScene( *mScene );
2152 (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2158 * This method is called when the Actor is connected to the Stage.
2159 * The parent must have added its Node to the scene-graph.
2160 * The child must connect its Node to the parent's Node.
2161 * This is recursive; the child calls ConnectToStage() for its children.
2163 void Actor::ConnectToSceneGraph()
2165 DALI_ASSERT_DEBUG( mParent != NULL);
2167 // Reparent Node in next Update
2168 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2170 // Request relayout on all actors that are added to the scenegraph
2173 // Notification for Object::Observers
2177 void Actor::NotifyStageConnection()
2179 // Actors can be removed (in a callback), before the on-stage stage is reported.
2180 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2181 if( OnStage() && !mOnStageSignalled )
2183 // Notification for external (CustomActor) derived classes
2184 OnStageConnectionExternal( mDepth );
2186 if( !mOnStageSignal.Empty() )
2188 Dali::Actor handle( this );
2189 mOnStageSignal.Emit( handle );
2192 // Guard against Remove during callbacks
2195 mOnStageSignalled = true; // signal required next time Actor is removed
2200 void Actor::DisconnectFromStage()
2202 // This container is used instead of walking the Actor hierachy.
2203 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2204 ActorContainer disconnectionList;
2208 mScene->RequestRebuildDepthTree();
2211 // This stage is atomic i.e. not interrupted by user callbacks
2212 RecursiveDisconnectFromStage( disconnectionList );
2214 // Notify applications about the newly disconnected actors.
2215 const ActorIter endIter = disconnectionList.end();
2216 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2218 (*iter)->NotifyStageDisconnection();
2222 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2224 // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2227 // Recursively disconnect children
2230 ActorConstIter endIter = mChildren->end();
2231 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2233 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2237 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2238 disconnectionList.push_back( ActorPtr( this ) );
2240 // Notification for internal derived classes
2241 OnStageDisconnectionInternal();
2243 DisconnectFromSceneGraph();
2247 * This method is called by an actor or its parent, before a node removal message is sent.
2248 * This is recursive; the child calls DisconnectFromStage() for its children.
2250 void Actor::DisconnectFromSceneGraph()
2252 // Notification for Object::Observers
2253 OnSceneObjectRemove();
2256 void Actor::NotifyStageDisconnection()
2258 // Actors can be added (in a callback), before the off-stage state is reported.
2259 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2260 // only do this step if there is a stage, i.e. Core is not being shut down
2261 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2263 // Notification for external (CustomeActor) derived classes
2264 OnStageDisconnectionExternal();
2266 if( !mOffStageSignal.Empty() )
2268 Dali::Actor handle( this );
2269 mOffStageSignal.Emit( handle );
2272 // Guard against Add during callbacks
2275 mOnStageSignalled = false; // signal required next time Actor is added
2280 bool Actor::IsNodeConnected() const
2282 bool connected( false );
2286 if( IsRoot() || GetNode().GetParent() )
2295 // This method initiates traversal of the actor tree using depth-first
2296 // traversal to set a depth index based on traversal order. It sends a
2297 // single message to update manager to update all the actor's nodes in
2298 // this tree with the depth index. The sceneGraphNodeDepths vector's
2299 // elements are ordered by depth, and could be used to reduce sorting
2300 // in the update thread.
2301 void Actor::RebuildDepthTree()
2303 DALI_LOG_TIMER_START(depthTimer);
2305 // Vector of scene-graph nodes and their depths to send to UpdateManager
2306 // in a single message
2307 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2309 int32_t depthIndex = 1;
2310 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2312 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2313 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2316 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2318 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2319 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2321 // Create/add to children of this node
2324 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2326 Actor* childActor = (*it).Get();
2328 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2333 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2337 case Dali::Actor::Property::PARENT_ORIGIN:
2339 Property::Type type = property.GetType();
2340 if( type == Property::VECTOR3 )
2342 SetParentOrigin( property.Get< Vector3 >() );
2344 else if ( type == Property::STRING )
2346 std::string parentOriginString;
2347 property.Get( parentOriginString );
2348 Vector3 parentOrigin;
2349 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2351 SetParentOrigin( parentOrigin );
2357 case Dali::Actor::Property::PARENT_ORIGIN_X:
2359 SetParentOriginX( property.Get< float >() );
2363 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2365 SetParentOriginY( property.Get< float >() );
2369 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2371 SetParentOriginZ( property.Get< float >() );
2375 case Dali::Actor::Property::ANCHOR_POINT:
2377 Property::Type type = property.GetType();
2378 if( type == Property::VECTOR3 )
2380 SetAnchorPoint( property.Get< Vector3 >() );
2382 else if ( type == Property::STRING )
2384 std::string anchorPointString;
2385 property.Get( anchorPointString );
2387 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2389 SetAnchorPoint( anchor );
2395 case Dali::Actor::Property::ANCHOR_POINT_X:
2397 SetAnchorPointX( property.Get< float >() );
2401 case Dali::Actor::Property::ANCHOR_POINT_Y:
2403 SetAnchorPointY( property.Get< float >() );
2407 case Dali::Actor::Property::ANCHOR_POINT_Z:
2409 SetAnchorPointZ( property.Get< float >() );
2413 case Dali::Actor::Property::SIZE:
2415 SetSize( property.Get< Vector3 >() );
2419 case Dali::Actor::Property::SIZE_WIDTH:
2421 SetWidth( property.Get< float >() );
2425 case Dali::Actor::Property::SIZE_HEIGHT:
2427 SetHeight( property.Get< float >() );
2431 case Dali::Actor::Property::SIZE_DEPTH:
2433 SetDepth( property.Get< float >() );
2437 case Dali::Actor::Property::POSITION:
2439 SetPosition( property.Get< Vector3 >() );
2443 case Dali::Actor::Property::POSITION_X:
2445 SetX( property.Get< float >() );
2449 case Dali::Actor::Property::POSITION_Y:
2451 SetY( property.Get< float >() );
2455 case Dali::Actor::Property::POSITION_Z:
2457 SetZ( property.Get< float >() );
2461 case Dali::Actor::Property::ORIENTATION:
2463 SetOrientation( property.Get< Quaternion >() );
2467 case Dali::Actor::Property::SCALE:
2469 SetScale( property.Get< Vector3 >() );
2473 case Dali::Actor::Property::SCALE_X:
2475 SetScaleX( property.Get< float >() );
2479 case Dali::Actor::Property::SCALE_Y:
2481 SetScaleY( property.Get< float >() );
2485 case Dali::Actor::Property::SCALE_Z:
2487 SetScaleZ( property.Get< float >() );
2491 case Dali::Actor::Property::VISIBLE:
2493 SetVisible( property.Get< bool >() );
2497 case Dali::Actor::Property::COLOR:
2499 SetColor( property.Get< Vector4 >() );
2503 case Dali::Actor::Property::COLOR_RED:
2505 SetColorRed( property.Get< float >() );
2509 case Dali::Actor::Property::COLOR_GREEN:
2511 SetColorGreen( property.Get< float >() );
2515 case Dali::Actor::Property::COLOR_BLUE:
2517 SetColorBlue( property.Get< float >() );
2521 case Dali::Actor::Property::COLOR_ALPHA:
2522 case Dali::DevelActor::Property::OPACITY:
2525 if( property.Get( value ) )
2527 SetOpacity( value );
2532 case Dali::Actor::Property::NAME:
2534 SetName( property.Get< std::string >() );
2538 case Dali::Actor::Property::SENSITIVE:
2540 SetSensitive( property.Get< bool >() );
2544 case Dali::Actor::Property::LEAVE_REQUIRED:
2546 SetLeaveRequired( property.Get< bool >() );
2550 case Dali::Actor::Property::INHERIT_POSITION:
2552 SetInheritPosition( property.Get< bool >() );
2556 case Dali::Actor::Property::INHERIT_ORIENTATION:
2558 SetInheritOrientation( property.Get< bool >() );
2562 case Dali::Actor::Property::INHERIT_SCALE:
2564 SetInheritScale( property.Get< bool >() );
2568 case Dali::Actor::Property::COLOR_MODE:
2570 ColorMode mode = mColorMode;
2571 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2573 SetColorMode( mode );
2578 case Dali::Actor::Property::DRAW_MODE:
2580 DrawMode::Type mode = mDrawMode;
2581 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2583 SetDrawMode( mode );
2588 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2590 SetSizeModeFactor( property.Get< Vector3 >() );
2594 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2596 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2597 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2599 SetResizePolicy( type, Dimension::WIDTH );
2604 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2606 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2607 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2609 SetResizePolicy( type, Dimension::HEIGHT );
2614 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2616 SizeScalePolicy::Type type = GetSizeScalePolicy();
2617 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2619 SetSizeScalePolicy( type );
2624 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2626 if( property.Get< bool >() )
2628 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2633 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2635 if( property.Get< bool >() )
2637 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2642 case Dali::Actor::Property::PADDING:
2644 Vector4 padding = property.Get< Vector4 >();
2645 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2646 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2650 case Dali::Actor::Property::MINIMUM_SIZE:
2652 Vector2 size = property.Get< Vector2 >();
2653 SetMinimumSize( size.x, Dimension::WIDTH );
2654 SetMinimumSize( size.y, Dimension::HEIGHT );
2658 case Dali::Actor::Property::MAXIMUM_SIZE:
2660 Vector2 size = property.Get< Vector2 >();
2661 SetMaximumSize( size.x, Dimension::WIDTH );
2662 SetMaximumSize( size.y, Dimension::HEIGHT );
2666 case Dali::DevelActor::Property::SIBLING_ORDER:
2670 if( property.Get( value ) )
2672 SetSiblingOrder( value );
2677 case Dali::Actor::Property::CLIPPING_MODE:
2679 ClippingMode::Type convertedValue = mClippingMode;
2680 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2682 mClippingMode = convertedValue;
2683 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2688 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2691 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2693 mPositionUsesAnchorPoint = value;
2694 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2699 case Dali::Actor::Property::LAYOUT_DIRECTION:
2701 Dali::LayoutDirection::Type direction = mLayoutDirection;
2702 mInheritLayoutDirection = false;
2704 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2706 InheritLayoutDirectionRecursively( this, direction, true );
2711 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2714 if( property.Get( value ) )
2716 SetInheritLayoutDirection( value );
2723 // this can happen in the case of a non-animatable default property so just do nothing
2729 // TODO: This method needs to be removed
2730 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2732 switch( entry.GetType() )
2734 case Property::BOOLEAN:
2736 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2737 DALI_ASSERT_DEBUG( NULL != property );
2739 // property is being used in a separate thread; queue a message to set the property
2740 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2745 case Property::INTEGER:
2747 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2748 DALI_ASSERT_DEBUG( NULL != property );
2750 // property is being used in a separate thread; queue a message to set the property
2751 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2756 case Property::FLOAT:
2758 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2759 DALI_ASSERT_DEBUG( NULL != property );
2761 // property is being used in a separate thread; queue a message to set the property
2762 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2767 case Property::VECTOR2:
2769 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2770 DALI_ASSERT_DEBUG( NULL != property );
2772 // property is being used in a separate thread; queue a message to set the property
2773 if(entry.componentIndex == 0)
2775 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2777 else if(entry.componentIndex == 1)
2779 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2783 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2789 case Property::VECTOR3:
2791 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2792 DALI_ASSERT_DEBUG( NULL != property );
2794 // property is being used in a separate thread; queue a message to set the property
2795 if(entry.componentIndex == 0)
2797 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2799 else if(entry.componentIndex == 1)
2801 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2803 else if(entry.componentIndex == 2)
2805 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2809 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2815 case Property::VECTOR4:
2817 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2818 DALI_ASSERT_DEBUG( NULL != property );
2820 // property is being used in a separate thread; queue a message to set the property
2821 if(entry.componentIndex == 0)
2823 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2825 else if(entry.componentIndex == 1)
2827 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2829 else if(entry.componentIndex == 2)
2831 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2833 else if(entry.componentIndex == 3)
2835 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2839 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2845 case Property::ROTATION:
2847 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2848 DALI_ASSERT_DEBUG( NULL != property );
2850 // property is being used in a separate thread; queue a message to set the property
2851 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2856 case Property::MATRIX:
2858 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2859 DALI_ASSERT_DEBUG( NULL != property );
2861 // property is being used in a separate thread; queue a message to set the property
2862 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2867 case Property::MATRIX3:
2869 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2870 DALI_ASSERT_DEBUG( NULL != property );
2872 // property is being used in a separate thread; queue a message to set the property
2873 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2880 // nothing to do for other types
2885 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2887 Property::Value value;
2889 if( ! GetCachedPropertyValue( index, value ) )
2891 // If property value is not stored in the event-side, then it must be a scene-graph only property
2892 GetCurrentPropertyValue( index, value );
2898 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2900 Property::Value value;
2902 if( ! GetCurrentPropertyValue( index, value ) )
2904 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2905 GetCachedPropertyValue( index, value );
2911 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2913 switch( animationType )
2916 case Animation::BETWEEN:
2920 case Dali::Actor::Property::SIZE:
2922 if( value.Get( mTargetSize ) )
2926 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
2928 mRelayoutData->preferredSize.width = mTargetSize.width;
2931 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
2933 mRelayoutData->preferredSize.height = mTargetSize.height;
2937 // Notify deriving classes
2938 OnSizeAnimation( animation, mTargetSize );
2943 case Dali::Actor::Property::SIZE_WIDTH:
2945 if( value.Get( mTargetSize.width ) )
2947 if( mRelayoutData && GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
2949 mRelayoutData->preferredSize.width = mTargetSize.width;
2952 // Notify deriving classes
2953 OnSizeAnimation( animation, mTargetSize );
2958 case Dali::Actor::Property::SIZE_HEIGHT:
2960 if( value.Get( mTargetSize.height ) )
2962 if( mRelayoutData && GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
2964 mRelayoutData->preferredSize.height = mTargetSize.height;
2967 // Notify deriving classes
2968 OnSizeAnimation( animation, mTargetSize );
2973 case Dali::Actor::Property::SIZE_DEPTH:
2975 if( value.Get( mTargetSize.depth ) )
2977 // Notify deriving classes
2978 OnSizeAnimation( animation, mTargetSize );
2983 case Dali::Actor::Property::POSITION:
2985 value.Get( mTargetPosition );
2989 case Dali::Actor::Property::POSITION_X:
2991 value.Get( mTargetPosition.x );
2995 case Dali::Actor::Property::POSITION_Y:
2997 value.Get( mTargetPosition.y );
3001 case Dali::Actor::Property::POSITION_Z:
3003 value.Get( mTargetPosition.z );
3007 case Dali::Actor::Property::ORIENTATION:
3009 value.Get( mTargetOrientation );
3013 case Dali::Actor::Property::SCALE:
3015 value.Get( mTargetScale );
3019 case Dali::Actor::Property::SCALE_X:
3021 value.Get( mTargetScale.x );
3025 case Dali::Actor::Property::SCALE_Y:
3027 value.Get( mTargetScale.y );
3031 case Dali::Actor::Property::SCALE_Z:
3033 value.Get( mTargetScale.z );
3037 case Dali::Actor::Property::VISIBLE:
3039 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3043 case Dali::Actor::Property::COLOR:
3045 value.Get( mTargetColor );
3049 case Dali::Actor::Property::COLOR_RED:
3051 value.Get( mTargetColor.r );
3055 case Dali::Actor::Property::COLOR_GREEN:
3057 value.Get( mTargetColor.g );
3061 case Dali::Actor::Property::COLOR_BLUE:
3063 value.Get( mTargetColor.b );
3067 case Dali::Actor::Property::COLOR_ALPHA:
3068 case Dali::DevelActor::Property::OPACITY:
3070 value.Get( mTargetColor.a );
3076 // Not an animatable property. Do nothing.
3087 case Dali::Actor::Property::SIZE:
3089 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3093 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
3095 mRelayoutData->preferredSize.width = mTargetSize.width;
3098 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
3100 mRelayoutData->preferredSize.height = mTargetSize.height;
3104 // Notify deriving classes
3105 OnSizeAnimation( animation, mTargetSize );
3110 case Dali::Actor::Property::SIZE_WIDTH:
3112 if( AdjustValue< float >( mTargetSize.width, value ) )
3114 if( mRelayoutData && GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
3116 mRelayoutData->preferredSize.width = mTargetSize.width;
3119 // Notify deriving classes
3120 OnSizeAnimation( animation, mTargetSize );
3125 case Dali::Actor::Property::SIZE_HEIGHT:
3127 if( AdjustValue< float >( mTargetSize.height, value ) )
3129 if( mRelayoutData && GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
3131 mRelayoutData->preferredSize.height = mTargetSize.height;
3134 // Notify deriving classes
3135 OnSizeAnimation( animation, mTargetSize );
3140 case Dali::Actor::Property::SIZE_DEPTH:
3142 if( AdjustValue< float >( mTargetSize.depth, value ) )
3144 // Notify deriving classes
3145 OnSizeAnimation( animation, mTargetSize );
3150 case Dali::Actor::Property::POSITION:
3152 AdjustValue< Vector3 >( mTargetPosition, value );
3156 case Dali::Actor::Property::POSITION_X:
3158 AdjustValue< float >( mTargetPosition.x, value );
3162 case Dali::Actor::Property::POSITION_Y:
3164 AdjustValue< float >( mTargetPosition.y, value );
3168 case Dali::Actor::Property::POSITION_Z:
3170 AdjustValue< float >( mTargetPosition.z, value );
3174 case Dali::Actor::Property::ORIENTATION:
3176 Quaternion relativeValue;
3177 if( value.Get( relativeValue ) )
3179 mTargetOrientation *= relativeValue;
3184 case Dali::Actor::Property::SCALE:
3186 AdjustValue< Vector3 >( mTargetScale, value );
3190 case Dali::Actor::Property::SCALE_X:
3192 AdjustValue< float >( mTargetScale.x, value );
3196 case Dali::Actor::Property::SCALE_Y:
3198 AdjustValue< float >( mTargetScale.y, value );
3202 case Dali::Actor::Property::SCALE_Z:
3204 AdjustValue< float >( mTargetScale.z, value );
3208 case Dali::Actor::Property::VISIBLE:
3210 bool relativeValue = false;
3211 if( value.Get( relativeValue ) )
3213 bool visible = mVisible || relativeValue;
3214 SetVisibleInternal( visible, SendMessage::FALSE );
3219 case Dali::Actor::Property::COLOR:
3221 AdjustValue< Vector4 >( mTargetColor, value );
3225 case Dali::Actor::Property::COLOR_RED:
3227 AdjustValue< float >( mTargetColor.r, value );
3231 case Dali::Actor::Property::COLOR_GREEN:
3233 AdjustValue< float >( mTargetColor.g, value );
3237 case Dali::Actor::Property::COLOR_BLUE:
3239 AdjustValue< float >( mTargetColor.b, value );
3243 case Dali::Actor::Property::COLOR_ALPHA:
3244 case Dali::DevelActor::Property::OPACITY:
3246 AdjustValue< float >( mTargetColor.a, value );
3252 // Not an animatable property. Do nothing.
3261 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3263 const PropertyBase* property( NULL );
3267 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3268 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3269 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3270 case Dali::Actor::Property::SIZE_DEPTH:
3272 property = &GetNode().mSize;
3275 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3276 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3277 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3278 case Dali::Actor::Property::POSITION_Z:
3280 property = &GetNode().mPosition;
3283 case Dali::Actor::Property::ORIENTATION:
3285 property = &GetNode().mOrientation;
3288 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3289 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3290 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3291 case Dali::Actor::Property::SCALE_Z:
3293 property = &GetNode().mScale;
3296 case Dali::Actor::Property::VISIBLE:
3298 property = &GetNode().mVisible;
3301 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3302 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3303 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3304 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3305 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3306 case Dali::DevelActor::Property::OPACITY:
3308 property = &GetNode().mColor;
3318 // not our property, ask base
3319 property = Object::GetSceneObjectAnimatableProperty( index );
3325 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3327 const PropertyInputImpl* property( NULL );
3331 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3332 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3333 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3334 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3336 property = &GetNode().mParentOrigin;
3339 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3340 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3341 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3342 case Dali::Actor::Property::ANCHOR_POINT_Z:
3344 property = &GetNode().mAnchorPoint;
3347 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3348 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3349 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3350 case Dali::Actor::Property::WORLD_POSITION_Z:
3352 property = &GetNode().mWorldPosition;
3355 case Dali::Actor::Property::WORLD_ORIENTATION:
3357 property = &GetNode().mWorldOrientation;
3360 case Dali::Actor::Property::WORLD_SCALE:
3362 property = &GetNode().mWorldScale;
3365 case Dali::Actor::Property::WORLD_COLOR:
3367 property = &GetNode().mWorldColor;
3370 case Dali::Actor::Property::WORLD_MATRIX:
3372 property = &GetNode().mWorldMatrix;
3375 case Dali::DevelActor::Property::CULLED:
3377 property = &GetNode().mCulled;
3387 // reuse animatable property getter as animatable properties are inputs as well
3388 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3389 property = GetSceneObjectAnimatableProperty( index );
3395 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3397 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3401 case Dali::Actor::Property::PARENT_ORIGIN_X:
3402 case Dali::Actor::Property::ANCHOR_POINT_X:
3403 case Dali::Actor::Property::SIZE_WIDTH:
3404 case Dali::Actor::Property::POSITION_X:
3405 case Dali::Actor::Property::WORLD_POSITION_X:
3406 case Dali::Actor::Property::SCALE_X:
3407 case Dali::Actor::Property::COLOR_RED:
3413 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3414 case Dali::Actor::Property::ANCHOR_POINT_Y:
3415 case Dali::Actor::Property::SIZE_HEIGHT:
3416 case Dali::Actor::Property::POSITION_Y:
3417 case Dali::Actor::Property::WORLD_POSITION_Y:
3418 case Dali::Actor::Property::SCALE_Y:
3419 case Dali::Actor::Property::COLOR_GREEN:
3425 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3426 case Dali::Actor::Property::ANCHOR_POINT_Z:
3427 case Dali::Actor::Property::SIZE_DEPTH:
3428 case Dali::Actor::Property::POSITION_Z:
3429 case Dali::Actor::Property::WORLD_POSITION_Z:
3430 case Dali::Actor::Property::SCALE_Z:
3431 case Dali::Actor::Property::COLOR_BLUE:
3437 case Dali::Actor::Property::COLOR_ALPHA:
3438 case Dali::DevelActor::Property::OPACITY:
3450 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3453 componentIndex = Object::GetPropertyComponentIndex( index );
3456 return componentIndex;
3459 void Actor::SetParent( Actor* parent )
3463 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3467 mScene = parent->mScene;
3469 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3472 // Instruct each actor to create a corresponding node in the scene graph
3473 ConnectToStage( parent->GetHierarchyDepth() );
3476 // Resolve the name and index for the child properties if any
3477 ResolveChildProperties();
3479 else // parent being set to NULL
3481 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3485 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3488 // Disconnect the Node & its children from the scene-graph.
3489 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3491 // Instruct each actor to discard pointers to the scene-graph
3492 DisconnectFromStage();
3499 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3502 Actor* actor = dynamic_cast< Actor* >( object );
3506 if( 0 == actionName.compare( ACTION_SHOW ) )
3508 actor->SetVisible( true );
3511 else if( 0 == actionName.compare( ACTION_HIDE ) )
3513 actor->SetVisible( false );
3521 Rect<> Actor::CalculateScreenExtents( ) const
3523 auto screenPosition = GetCurrentScreenPosition();
3524 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3525 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3526 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3527 return { position.x, position.y, size.x, size.y };
3530 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3532 bool valueSet = true;
3536 case Dali::Actor::Property::PARENT_ORIGIN:
3538 value = GetCurrentParentOrigin();
3542 case Dali::Actor::Property::PARENT_ORIGIN_X:
3544 value = GetCurrentParentOrigin().x;
3548 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3550 value = GetCurrentParentOrigin().y;
3554 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3556 value = GetCurrentParentOrigin().z;
3560 case Dali::Actor::Property::ANCHOR_POINT:
3562 value = GetCurrentAnchorPoint();
3566 case Dali::Actor::Property::ANCHOR_POINT_X:
3568 value = GetCurrentAnchorPoint().x;
3572 case Dali::Actor::Property::ANCHOR_POINT_Y:
3574 value = GetCurrentAnchorPoint().y;
3578 case Dali::Actor::Property::ANCHOR_POINT_Z:
3580 value = GetCurrentAnchorPoint().z;
3584 case Dali::Actor::Property::SIZE:
3586 value = GetTargetSize();
3590 case Dali::Actor::Property::SIZE_WIDTH:
3592 value = GetTargetSize().width;
3596 case Dali::Actor::Property::SIZE_HEIGHT:
3598 value = GetTargetSize().height;
3602 case Dali::Actor::Property::SIZE_DEPTH:
3604 value = GetTargetSize().depth;
3608 case Dali::Actor::Property::POSITION:
3610 value = GetTargetPosition();
3614 case Dali::Actor::Property::POSITION_X:
3616 value = GetTargetPosition().x;
3620 case Dali::Actor::Property::POSITION_Y:
3622 value = GetTargetPosition().y;
3626 case Dali::Actor::Property::POSITION_Z:
3628 value = GetTargetPosition().z;
3632 case Dali::Actor::Property::ORIENTATION:
3634 value = mTargetOrientation;
3638 case Dali::Actor::Property::SCALE:
3640 value = mTargetScale;
3644 case Dali::Actor::Property::SCALE_X:
3646 value = mTargetScale.x;
3650 case Dali::Actor::Property::SCALE_Y:
3652 value = mTargetScale.y;
3656 case Dali::Actor::Property::SCALE_Z:
3658 value = mTargetScale.z;
3662 case Dali::Actor::Property::VISIBLE:
3668 case Dali::Actor::Property::COLOR:
3670 value = mTargetColor;
3674 case Dali::Actor::Property::COLOR_RED:
3676 value = mTargetColor.r;
3680 case Dali::Actor::Property::COLOR_GREEN:
3682 value = mTargetColor.g;
3686 case Dali::Actor::Property::COLOR_BLUE:
3688 value = mTargetColor.b;
3692 case Dali::Actor::Property::COLOR_ALPHA:
3693 case Dali::DevelActor::Property::OPACITY:
3695 value = mTargetColor.a;
3699 case Dali::Actor::Property::NAME:
3705 case Dali::Actor::Property::SENSITIVE:
3707 value = IsSensitive();
3711 case Dali::Actor::Property::LEAVE_REQUIRED:
3713 value = GetLeaveRequired();
3717 case Dali::Actor::Property::INHERIT_POSITION:
3719 value = IsPositionInherited();
3723 case Dali::Actor::Property::INHERIT_ORIENTATION:
3725 value = IsOrientationInherited();
3729 case Dali::Actor::Property::INHERIT_SCALE:
3731 value = IsScaleInherited();
3735 case Dali::Actor::Property::COLOR_MODE:
3737 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3741 case Dali::Actor::Property::DRAW_MODE:
3743 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3747 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3749 value = GetSizeModeFactor();
3753 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3755 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3759 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3761 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3765 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3767 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3771 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3773 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3777 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3779 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3783 case Dali::Actor::Property::PADDING:
3785 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3786 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3787 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3791 case Dali::Actor::Property::MINIMUM_SIZE:
3793 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3797 case Dali::Actor::Property::MAXIMUM_SIZE:
3799 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3803 case Dali::Actor::Property::CLIPPING_MODE:
3805 value = mClippingMode;
3809 case Dali::DevelActor::Property::SIBLING_ORDER:
3811 value = static_cast<int>( GetSiblingOrder() );
3815 case Dali::DevelActor::Property::SCREEN_POSITION:
3817 value = GetCurrentScreenPosition();
3821 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3823 value = mPositionUsesAnchorPoint;
3827 case Dali::Actor::Property::LAYOUT_DIRECTION:
3829 value = mLayoutDirection;
3833 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3835 value = IsLayoutDirectionInherited();
3841 // Must be a scene-graph only property
3850 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3852 bool valueSet = true;
3856 case Dali::Actor::Property::SIZE:
3858 value = GetCurrentSize();
3862 case Dali::Actor::Property::SIZE_WIDTH:
3864 value = GetCurrentSize().width;
3868 case Dali::Actor::Property::SIZE_HEIGHT:
3870 value = GetCurrentSize().height;
3874 case Dali::Actor::Property::SIZE_DEPTH:
3876 value = GetCurrentSize().depth;
3880 case Dali::Actor::Property::POSITION:
3882 value = GetCurrentPosition();
3886 case Dali::Actor::Property::POSITION_X:
3888 value = GetCurrentPosition().x;
3892 case Dali::Actor::Property::POSITION_Y:
3894 value = GetCurrentPosition().y;
3898 case Dali::Actor::Property::POSITION_Z:
3900 value = GetCurrentPosition().z;
3904 case Dali::Actor::Property::WORLD_POSITION:
3906 value = GetCurrentWorldPosition();
3910 case Dali::Actor::Property::WORLD_POSITION_X:
3912 value = GetCurrentWorldPosition().x;
3916 case Dali::Actor::Property::WORLD_POSITION_Y:
3918 value = GetCurrentWorldPosition().y;
3922 case Dali::Actor::Property::WORLD_POSITION_Z:
3924 value = GetCurrentWorldPosition().z;
3928 case Dali::Actor::Property::ORIENTATION:
3930 value = GetCurrentOrientation();
3934 case Dali::Actor::Property::WORLD_ORIENTATION:
3936 value = GetCurrentWorldOrientation();
3940 case Dali::Actor::Property::SCALE:
3942 value = GetCurrentScale();
3946 case Dali::Actor::Property::SCALE_X:
3948 value = GetCurrentScale().x;
3952 case Dali::Actor::Property::SCALE_Y:
3954 value = GetCurrentScale().y;
3958 case Dali::Actor::Property::SCALE_Z:
3960 value = GetCurrentScale().z;
3964 case Dali::Actor::Property::WORLD_SCALE:
3966 value = GetCurrentWorldScale();
3970 case Dali::Actor::Property::COLOR:
3972 value = GetCurrentColor();
3976 case Dali::Actor::Property::COLOR_RED:
3978 value = GetCurrentColor().r;
3982 case Dali::Actor::Property::COLOR_GREEN:
3984 value = GetCurrentColor().g;
3988 case Dali::Actor::Property::COLOR_BLUE:
3990 value = GetCurrentColor().b;
3994 case Dali::Actor::Property::COLOR_ALPHA:
3995 case Dali::DevelActor::Property::OPACITY:
3997 value = GetCurrentColor().a;
4001 case Dali::Actor::Property::WORLD_COLOR:
4003 value = GetCurrentWorldColor();
4007 case Dali::Actor::Property::WORLD_MATRIX:
4009 value = GetCurrentWorldMatrix();
4013 case Dali::Actor::Property::VISIBLE:
4015 value = IsVisible();
4019 case DevelActor::Property::CULLED:
4021 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4027 // Must be an event-side only property
4036 void Actor::EnsureRelayoutData()
4038 // Assign relayout data.
4039 if( !mRelayoutData )
4041 mRelayoutData = new RelayoutData();
4045 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4047 // Check if actor is dependent on parent
4048 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4050 if( ( dimension & ( 1 << i ) ) )
4052 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4053 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4063 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4065 // Check if actor is dependent on children
4066 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4068 if( ( dimension & ( 1 << i ) ) )
4070 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4071 switch( resizePolicy )
4073 case ResizePolicy::FIT_TO_CHILDREN:
4074 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4090 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4092 return Actor::RelayoutDependentOnChildren( dimension );
4095 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4097 // Check each possible dimension and see if it is dependent on the input one
4098 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4100 if( dimension & ( 1 << i ) )
4102 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4109 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4111 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4113 if( dimension & ( 1 << i ) )
4115 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4120 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4122 // If more than one dimension is requested, just return the first one found
4123 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4125 if( ( dimension & ( 1 << i ) ) )
4127 return mRelayoutData->negotiatedDimensions[ i ];
4131 return 0.0f; // Default
4134 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4136 EnsureRelayoutData();
4138 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4140 if( dimension & ( 1 << i ) )
4142 mRelayoutData->dimensionPadding[ i ] = padding;
4147 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4149 if ( mRelayoutData )
4151 // If more than one dimension is requested, just return the first one found
4152 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4154 if( ( dimension & ( 1 << i ) ) )
4156 return mRelayoutData->dimensionPadding[ i ];
4161 return GetDefaultDimensionPadding();
4164 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4166 EnsureRelayoutData();
4168 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4170 if( dimension & ( 1 << i ) )
4172 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4177 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4179 if ( mRelayoutData )
4181 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4183 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4193 float Actor::GetHeightForWidthBase( float width )
4195 float height = 0.0f;
4197 const Vector3 naturalSize = GetNaturalSize();
4198 if( naturalSize.width > 0.0f )
4200 height = naturalSize.height * width / naturalSize.width;
4202 else // we treat 0 as 1:1 aspect ratio
4210 float Actor::GetWidthForHeightBase( float height )
4214 const Vector3 naturalSize = GetNaturalSize();
4215 if( naturalSize.height > 0.0f )
4217 width = naturalSize.width * height / naturalSize.height;
4219 else // we treat 0 as 1:1 aspect ratio
4227 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4229 // Fill to parent, taking size mode factor into account
4230 switch( child.GetResizePolicy( dimension ) )
4232 case ResizePolicy::FILL_TO_PARENT:
4234 return GetLatestSize( dimension );
4237 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4239 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4242 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4244 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4249 return GetLatestSize( dimension );
4254 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4256 // Can be overridden in derived class
4257 return CalculateChildSizeBase( child, dimension );
4260 float Actor::GetHeightForWidth( float width )
4262 // Can be overridden in derived class
4263 return GetHeightForWidthBase( width );
4266 float Actor::GetWidthForHeight( float height )
4268 // Can be overridden in derived class
4269 return GetWidthForHeightBase( height );
4272 float Actor::GetLatestSize( Dimension::Type dimension ) const
4274 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4277 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4279 Vector2 padding = GetPadding( dimension );
4281 return GetLatestSize( dimension ) + padding.x + padding.y;
4284 float Actor::NegotiateFromParent( Dimension::Type dimension )
4286 Actor* parent = GetParent();
4289 Vector2 padding( GetPadding( dimension ) );
4290 Vector2 parentPadding( parent->GetPadding( dimension ) );
4291 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4297 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4299 float maxDimensionPoint = 0.0f;
4301 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4303 ActorPtr child = GetChildAt( i );
4305 if( !child->RelayoutDependentOnParent( dimension ) )
4307 // Calculate the min and max points that the children range across
4308 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4309 float dimensionSize = child->GetRelayoutSize( dimension );
4310 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4314 return maxDimensionPoint;
4317 float Actor::GetSize( Dimension::Type dimension ) const
4319 return GetDimensionValue( mTargetSize, dimension );
4322 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4324 return GetDimensionValue( GetNaturalSize(), dimension );
4327 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4329 switch( GetResizePolicy( dimension ) )
4331 case ResizePolicy::USE_NATURAL_SIZE:
4333 return GetNaturalSize( dimension );
4336 case ResizePolicy::FIXED:
4338 return GetDimensionValue( GetPreferredSize(), dimension );
4341 case ResizePolicy::USE_ASSIGNED_SIZE:
4343 return GetDimensionValue( maximumSize, dimension );
4346 case ResizePolicy::FILL_TO_PARENT:
4347 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4348 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4350 return NegotiateFromParent( dimension );
4353 case ResizePolicy::FIT_TO_CHILDREN:
4355 return NegotiateFromChildren( dimension );
4358 case ResizePolicy::DIMENSION_DEPENDENCY:
4360 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4363 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4365 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4368 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4370 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4382 return 0.0f; // Default
4385 float Actor::ClampDimension( float size, Dimension::Type dimension )
4387 const float minSize = GetMinimumSize( dimension );
4388 const float maxSize = GetMaximumSize( dimension );
4390 return std::max( minSize, std::min( size, maxSize ) );
4393 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4395 // Check if it needs to be negotiated
4396 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4398 // Check that we havn't gotten into an infinite loop
4399 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4400 bool recursionFound = false;
4401 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4403 if( *it == searchActor )
4405 recursionFound = true;
4410 if( !recursionFound )
4412 // Record the path that we have taken
4413 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4415 // Dimension dependency check
4416 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4418 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4420 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4422 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4426 // Parent dependency check
4427 Actor* parent = GetParent();
4428 if( parent && RelayoutDependentOnParent( dimension ) )
4430 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4433 // Children dependency check
4434 if( RelayoutDependentOnChildren( dimension ) )
4436 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4438 ActorPtr child = GetChildAt( i );
4440 // Only relayout child first if it is not dependent on this actor
4441 if( !child->RelayoutDependentOnParent( dimension ) )
4443 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4448 // For deriving classes
4449 OnCalculateRelayoutSize( dimension );
4451 // All dependencies checked, calculate the size and set negotiated flag
4452 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4454 SetNegotiatedDimension( newSize, dimension );
4455 SetLayoutNegotiated( true, dimension );
4457 // For deriving classes
4458 OnLayoutNegotiated( newSize, dimension );
4460 // This actor has been successfully processed, pop it off the recursion stack
4461 recursionStack.pop_back();
4465 // TODO: Break infinite loop
4466 SetLayoutNegotiated( true, dimension );
4471 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4473 // Negotiate all dimensions that require it
4474 ActorDimensionStack recursionStack;
4476 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4478 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4481 NegotiateDimension( dimension, allocatedSize, recursionStack );
4485 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4487 switch( mRelayoutData->sizeSetPolicy )
4489 case SizeScalePolicy::USE_SIZE_SET:
4494 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4496 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4497 const Vector3 naturalSize = GetNaturalSize();
4498 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4500 const float sizeRatio = size.width / size.height;
4501 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4503 if( naturalSizeRatio < sizeRatio )
4505 return Vector2( naturalSizeRatio * size.height, size.height );
4507 else if( naturalSizeRatio > sizeRatio )
4509 return Vector2( size.width, size.width / naturalSizeRatio );
4520 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4522 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4523 const Vector3 naturalSize = GetNaturalSize();
4524 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4526 const float sizeRatio = size.width / size.height;
4527 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4529 if( naturalSizeRatio < sizeRatio )
4531 return Vector2( size.width, size.width / naturalSizeRatio );
4533 else if( naturalSizeRatio > sizeRatio )
4535 return Vector2( naturalSizeRatio * size.height, size.height );
4554 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4556 // Do the set actor size
4557 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4559 // Adjust for size set policy
4560 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4562 // Lock the flag to stop recursive relayouts on set size
4563 mRelayoutData->insideRelayout = true;
4564 SetSize( negotiatedSize );
4565 mRelayoutData->insideRelayout = false;
4567 // Clear flags for all dimensions
4568 SetLayoutDirty( false );
4570 // Give deriving classes a chance to respond
4571 OnRelayout( negotiatedSize, container );
4573 if( !mOnRelayoutSignal.Empty() )
4575 Dali::Actor handle( this );
4576 mOnRelayoutSignal.Emit( handle );
4580 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4582 // Force a size negotiation for actors that has assigned size during relayout
4583 // This is required as otherwise the flags that force a relayout will not
4584 // necessarilly be set. This will occur if the actor has already been laid out.
4585 // The dirty flags are then cleared. Then if the actor is added back into the
4586 // relayout container afterwards, the dirty flags would still be clear...
4587 // causing a relayout to be skipped. Here we force any actors added to the
4588 // container to be relayed out.
4589 DALI_LOG_TIMER_START( NegSizeTimer1 );
4591 if( GetUseAssignedSize(Dimension::WIDTH ) )
4593 SetLayoutNegotiated( false, Dimension::WIDTH );
4595 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4597 SetLayoutNegotiated( false, Dimension::HEIGHT );
4600 // Do the negotiation
4601 NegotiateDimensions( allocatedSize );
4603 // Set the actor size
4604 SetNegotiatedSize( container );
4606 // Negotiate down to children
4607 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4609 ActorPtr child = GetChildAt( i );
4611 // Forces children that have already been laid out to be relayed out
4612 // if they have assigned size during relayout.
4613 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4615 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4616 child->SetLayoutDirty(true, Dimension::WIDTH);
4619 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4621 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4622 child->SetLayoutDirty(true, Dimension::HEIGHT);
4625 // Only relayout if required
4626 if( child->RelayoutRequired() )
4628 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4631 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4634 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4638 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4640 if( dimension & ( 1 << i ) )
4642 mRelayoutData->useAssignedSize[ i ] = use;
4648 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4650 if ( mRelayoutData )
4652 // If more than one dimension is requested, just return the first one found
4653 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4655 if( dimension & ( 1 << i ) )
4657 return mRelayoutData->useAssignedSize[ i ];
4665 void Actor::RelayoutRequest( Dimension::Type dimension )
4667 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4668 if( relayoutController )
4670 Dali::Actor self( this );
4671 relayoutController->RequestRelayout( self, dimension );
4675 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4679 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4683 void Actor::SetPreferredSize( const Vector2& size )
4685 EnsureRelayoutData();
4687 // If valid width or height, then set the resize policy to FIXED
4688 // 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,
4689 // then change to FIXED as well
4691 if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4693 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4696 if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4698 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4701 mRelayoutData->preferredSize = size;
4706 Vector2 Actor::GetPreferredSize() const
4708 if ( mRelayoutData )
4710 return Vector2( mRelayoutData->preferredSize );
4713 return GetDefaultPreferredSize();
4716 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4718 EnsureRelayoutData();
4720 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4722 if( dimension & ( 1 << i ) )
4724 mRelayoutData->minimumSize[ i ] = size;
4731 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4733 if ( mRelayoutData )
4735 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4737 if( dimension & ( 1 << i ) )
4739 return mRelayoutData->minimumSize[ i ];
4744 return 0.0f; // Default
4747 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4749 EnsureRelayoutData();
4751 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4753 if( dimension & ( 1 << i ) )
4755 mRelayoutData->maximumSize[ i ] = size;
4762 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4764 if ( mRelayoutData )
4766 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4768 if( dimension & ( 1 << i ) )
4770 return mRelayoutData->maximumSize[ i ];
4775 return FLT_MAX; // Default
4778 Object* Actor::GetParentObject() const
4783 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4785 if( mVisible != visible )
4787 if( sendMessage == SendMessage::TRUE )
4789 // node is being used in a separate thread; queue a message to set the value & base value
4790 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4795 // Emit the signal on this actor and all its children
4796 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4800 void Actor::SetSiblingOrder( uint32_t order )
4804 ActorContainer& siblings = *(mParent->mChildren);
4805 uint32_t currentOrder = GetSiblingOrder();
4807 if( order != currentOrder )
4813 else if( order < siblings.size() -1 )
4815 if( order > currentOrder )
4817 RaiseAbove( *siblings[order] );
4821 LowerBelow( *siblings[order] );
4832 uint32_t Actor::GetSiblingOrder() const
4838 ActorContainer& siblings = *(mParent->mChildren);
4839 for( std::size_t i = 0; i < siblings.size(); ++i )
4841 if( siblings[i] == this )
4843 order = static_cast<uint32_t>( i );
4852 void Actor::RequestRebuildDepthTree()
4858 mScene->RequestRebuildDepthTree();
4867 ActorContainer& siblings = *(mParent->mChildren);
4868 if( siblings.back() != this ) // If not already at end
4870 for( std::size_t i=0; i<siblings.size(); ++i )
4872 if( siblings[i] == this )
4875 ActorPtr next = siblings[i+1];
4876 siblings[i+1] = this;
4883 Dali::Actor handle( this );
4884 mParent->mChildOrderChangedSignal.Emit( handle );
4886 RequestRebuildDepthTree();
4890 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4898 ActorContainer& siblings = *(mParent->mChildren);
4899 if( siblings.front() != this ) // If not already at beginning
4901 for( std::size_t i=1; i<siblings.size(); ++i )
4903 if( siblings[i] == this )
4905 // Swap with previous
4906 ActorPtr previous = siblings[i-1];
4907 siblings[i-1] = this;
4908 siblings[i] = previous;
4914 Dali::Actor handle( this );
4915 mParent->mChildOrderChangedSignal.Emit( handle );
4917 RequestRebuildDepthTree();
4921 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4925 void Actor::RaiseToTop()
4929 ActorContainer& siblings = *(mParent->mChildren);
4930 if( siblings.back() != this ) // If not already at end
4932 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4933 if( iter != siblings.end() )
4935 siblings.erase(iter);
4936 siblings.push_back(ActorPtr(this));
4940 Dali::Actor handle( this );
4941 mParent->mChildOrderChangedSignal.Emit( handle );
4943 RequestRebuildDepthTree();
4947 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4951 void Actor::LowerToBottom()
4955 ActorContainer& siblings = *(mParent->mChildren);
4956 if( siblings.front() != this ) // If not already at bottom,
4958 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4960 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4961 if( iter != siblings.end() )
4963 siblings.erase(iter);
4964 siblings.insert(siblings.begin(), thisPtr);
4968 Dali::Actor handle( this );
4969 mParent->mChildOrderChangedSignal.Emit( handle );
4971 RequestRebuildDepthTree();
4975 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4979 void Actor::RaiseAbove( Internal::Actor& target )
4983 ActorContainer& siblings = *(mParent->mChildren);
4984 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
4986 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4988 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
4989 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
4990 if( thisIter < targetIter )
4992 siblings.erase(thisIter);
4993 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
4994 // invalidate thisIter)
4995 targetIter = std::find( siblings.begin(), siblings.end(), &target );
4997 siblings.insert(targetIter, thisPtr);
5000 Dali::Actor handle( this );
5001 mParent->mChildOrderChangedSignal.Emit( handle );
5003 RequestRebuildDepthTree();
5008 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5012 void Actor::LowerBelow( Internal::Actor& target )
5016 ActorContainer& siblings = *(mParent->mChildren);
5017 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5019 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5021 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5022 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5024 if( thisIter > targetIter )
5026 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5027 siblings.insert(targetIter, thisPtr);
5030 Dali::Actor handle( this );
5031 mParent->mChildOrderChangedSignal.Emit( handle );
5033 RequestRebuildDepthTree();
5038 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5042 void Actor::SetScene( Scene& scene )
5047 Scene& Actor::GetScene() const
5052 void Actor::SetInheritLayoutDirection( bool inherit )
5054 if( mInheritLayoutDirection != inherit )
5056 mInheritLayoutDirection = inherit;
5058 if( inherit && mParent )
5060 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5065 bool Actor::IsLayoutDirectionInherited() const
5067 return mInheritLayoutDirection;
5070 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5072 if( actor && ( actor->mInheritLayoutDirection || set ) )
5074 if( actor->mLayoutDirection != direction )
5076 actor->mLayoutDirection = direction;
5077 actor->EmitLayoutDirectionChangedSignal( direction );
5078 actor->RelayoutRequest();
5081 if( actor->GetChildCount() > 0 )
5083 ActorContainer& children = actor->GetChildrenInternal();
5084 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5086 InheritLayoutDirectionRecursively( *iter, direction );
5092 } // namespace Internal