2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/common/scene-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/animation/constraint-impl.h>
48 #include <dali/internal/event/common/projection.h>
49 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
50 #include <dali/internal/update/common/animatable-property.h>
51 #include <dali/internal/update/nodes/node-messages.h>
52 #include <dali/internal/update/nodes/node-declarations.h>
53 #include <dali/internal/update/animation/scene-graph-constraint.h>
54 #include <dali/internal/event/events/actor-gesture-data.h>
55 #include <dali/internal/common/message.h>
56 #include <dali/integration-api/debug.h>
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::PropertyBase;
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
64 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
75 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
76 inline const Vector3& GetDefaultSizeModeFactor()
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultPreferredSize()
87 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
88 inline const Vector2& GetDefaultDimensionPadding()
93 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
95 } // unnamed namespace
98 * Struct to collect relayout variables
100 struct Actor::RelayoutData
103 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
105 // Set size negotiation defaults
106 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
108 resizePolicies[ i ] = ResizePolicy::DEFAULT;
109 useAssignedSize[ i ] = false;
110 negotiatedDimensions[ i ] = 0.0f;
111 dimensionNegotiated[ i ] = false;
112 dimensionDirty[ i ] = false;
113 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
114 dimensionPadding[ i ] = GetDefaultDimensionPadding();
115 minimumSize[ i ] = 0.0f;
116 maximumSize[ i ] = FLT_MAX;
120 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
121 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
123 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
125 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
127 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
129 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
130 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
132 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
133 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
135 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
137 Vector2 preferredSize; ///< The preferred size of the actor
139 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
141 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
142 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
145 namespace // unnamed namespace
151 * We want to discourage the use of property strings (minimize string comparisons),
152 * particularly for the default properties.
153 * Name Type writable animatable constraint-input enum for index-checking
155 DALI_PROPERTY_TABLE_BEGIN
156 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
157 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
158 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
159 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
160 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
161 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
162 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
163 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
164 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
165 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
166 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
167 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
168 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
169 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
170 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
171 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
172 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
173 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
174 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
175 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
176 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
177 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
178 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
179 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
180 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
181 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
182 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
183 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
184 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
185 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
186 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
187 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
188 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
189 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
190 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
191 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
192 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
193 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
194 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
195 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
196 DALI_PROPERTY( "colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "reservedProperty01", STRING, true, false, false, Dali::Actor::Property::RESERVED_PROPERTY_01 ) // This property was removed, but to keep binary compatibility and TypeRegister test app, remain it here.
198 DALI_PROPERTY( "drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE )
199 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
200 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
201 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
202 DALI_PROPERTY( "sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
203 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
204 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
205 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
206 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
207 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
208 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
209 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
210 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
211 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
212 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
213 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
214 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
215 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
216 DALI_PROPERTY( "culled", BOOLEAN, false, false, true, Dali::DevelActor::Property::CULLED )
217 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
221 const char* const SIGNAL_TOUCHED = "touched";
222 const char* const SIGNAL_HOVERED = "hovered";
223 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
224 const char* const SIGNAL_ON_STAGE = "onStage";
225 const char* const SIGNAL_OFF_STAGE = "offStage";
226 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
227 const char* const SIGNAL_TOUCH = "touch";
228 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
229 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
230 const char* const SIGNAL_CHILD_ADDED = "childAdded";
231 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
235 const char* const ACTION_SHOW = "show";
236 const char* const ACTION_HIDE = "hide";
238 BaseHandle CreateActor()
240 return Dali::Actor::New();
243 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
245 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
247 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
248 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
249 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
250 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
251 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
257 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
258 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
263 const Vector3& value;
266 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
267 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
268 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
269 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
270 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
276 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
278 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
279 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
280 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
281 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
282 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
283 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
285 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
287 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
288 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
290 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
299 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
301 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
305 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
307 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
310 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
312 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
315 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
317 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
319 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
321 uint32_t sizeIgnored = 0;
322 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
324 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
331 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
333 // Values are the same so just use the same table as anchor-point
334 return GetAnchorPointConstant( value, parentOrigin );
338 * @brief Extract a given dimension from a Vector2
340 * @param[in] values The values to extract from
341 * @param[in] dimension The dimension to extract
342 * @return Return the value for the dimension
344 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
348 case Dimension::WIDTH:
352 case Dimension::HEIGHT:
354 return values.height;
365 * @brief Extract a given dimension from a Vector3
367 * @param[in] values The values to extract from
368 * @param[in] dimension The dimension to extract
369 * @return Return the value for the dimension
371 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
373 return GetDimensionValue( values.GetVectorXY(), dimension );
377 * @brief Recursively emits the visibility-changed-signal on the actor tree.
378 * @param[in] actor The actor to emit the signal on
379 * @param[in] visible The new visibility of the actor
380 * @param[in] type Whether the actor's visible property has changed or a parent's
382 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
386 actor->EmitVisibilityChangedSignal( visible, type );
388 if( actor->GetChildCount() > 0 )
390 ActorContainer& children = actor->GetChildrenInternal();
391 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
393 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
399 } // unnamed namespace
401 ActorPtr Actor::New()
403 // pass a reference to actor, actor does not own its node
404 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
406 // Second-phase construction
412 const SceneGraph::Node* Actor::CreateNode()
414 // create node. Nodes are owned by the update manager
415 SceneGraph::Node* node = SceneGraph::Node::New();
416 OwnerPointer< SceneGraph::Node > transferOwnership( node );
417 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
418 AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
423 const std::string& Actor::GetName() const
428 void Actor::SetName( const std::string& name )
432 // ATTENTION: string for debug purposes is not thread safe.
433 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
436 uint32_t Actor::GetId() const
438 return GetNode().GetId();
441 bool Actor::OnStage() const
446 Dali::Layer Actor::GetLayer()
450 // Short-circuit for Layer derived actors
453 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
456 // Find the immediate Layer parent
457 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
459 if( parent->IsLayer() )
461 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
468 void Actor::Add( Actor& child )
470 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
471 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
475 mChildren = new ActorContainer;
478 Actor* const oldParent( child.mParent );
480 // child might already be ours
481 if( this != oldParent )
483 // if we already have parent, unparent us first
486 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
488 // Old parent may need to readjust to missing child
489 if( oldParent->RelayoutDependentOnChildren() )
491 oldParent->RelayoutRequest();
495 // Guard against Add() during previous OnChildRemove callback
498 // Do this first, since user callbacks from within SetParent() may need to remove child
499 mChildren->push_back( ActorPtr( &child ) );
501 // SetParent asserts that child can be added
502 child.SetParent( this );
504 // Notification for derived classes
506 EmitChildAddedSignal( child );
508 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
510 // Only put in a relayout request if there is a suitable dependency
511 if( RelayoutDependentOnChildren() )
519 void Actor::Remove( Actor& child )
521 if( (this == &child) || (!mChildren) )
523 // no children or removing itself
529 // Find the child in mChildren, and unparent it
530 ActorIter end = mChildren->end();
531 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
533 ActorPtr actor = (*iter);
535 if( actor.Get() == &child )
537 // Keep handle for OnChildRemove notification
540 // Do this first, since user callbacks from within SetParent() may need to add the child
541 mChildren->erase( iter );
543 DALI_ASSERT_DEBUG( actor->GetParent() == this );
544 actor->SetParent( NULL );
552 // Only put in a relayout request if there is a suitable dependency
553 if( RelayoutDependentOnChildren() )
559 // Notification for derived classes
560 OnChildRemove( child );
561 EmitChildRemovedSignal( child );
564 void Actor::Unparent()
568 // Remove this actor from the parent. The remove will put a relayout request in for
569 // the parent if required
570 mParent->Remove( *this );
571 // mParent is now NULL!
575 uint32_t Actor::GetChildCount() const
577 return ( NULL != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
580 ActorPtr Actor::GetChildAt( uint32_t index ) const
582 DALI_ASSERT_ALWAYS( index < GetChildCount() );
584 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
587 ActorPtr Actor::FindChildByName( const std::string& actorName )
590 if( actorName == mName )
596 ActorIter end = mChildren->end();
597 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
599 child = (*iter)->FindChildByName( actorName );
610 ActorPtr Actor::FindChildById( const uint32_t id )
619 ActorIter end = mChildren->end();
620 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
622 child = (*iter)->FindChildById( id );
633 void Actor::SetParentOrigin( const Vector3& origin )
635 // node is being used in a separate thread; queue a message to set the value & base value
636 SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
638 // Cache for event-thread access
641 // not allocated, check if different from default
642 if( ParentOrigin::DEFAULT != origin )
644 mParentOrigin = new Vector3( origin );
649 // check if different from current costs more than just set
650 *mParentOrigin = origin;
654 void Actor::SetParentOriginX( float x )
656 const Vector3& current = GetCurrentParentOrigin();
658 SetParentOrigin( Vector3( x, current.y, current.z ) );
661 void Actor::SetParentOriginY( float y )
663 const Vector3& current = GetCurrentParentOrigin();
665 SetParentOrigin( Vector3( current.x, y, current.z ) );
668 void Actor::SetParentOriginZ( float z )
670 const Vector3& current = GetCurrentParentOrigin();
672 SetParentOrigin( Vector3( current.x, current.y, z ) );
675 const Vector3& Actor::GetCurrentParentOrigin() const
677 // Cached for event-thread access
678 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
681 void Actor::SetAnchorPoint( const Vector3& anchor )
683 // node is being used in a separate thread; queue a message to set the value & base value
684 SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
686 // Cache for event-thread access
689 // not allocated, check if different from default
690 if( AnchorPoint::DEFAULT != anchor )
692 mAnchorPoint = new Vector3( anchor );
697 // check if different from current costs more than just set
698 *mAnchorPoint = anchor;
702 void Actor::SetAnchorPointX( float x )
704 const Vector3& current = GetCurrentAnchorPoint();
706 SetAnchorPoint( Vector3( x, current.y, current.z ) );
709 void Actor::SetAnchorPointY( float y )
711 const Vector3& current = GetCurrentAnchorPoint();
713 SetAnchorPoint( Vector3( current.x, y, current.z ) );
716 void Actor::SetAnchorPointZ( float z )
718 const Vector3& current = GetCurrentAnchorPoint();
720 SetAnchorPoint( Vector3( current.x, current.y, z ) );
723 const Vector3& Actor::GetCurrentAnchorPoint() const
725 // Cached for event-thread access
726 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
729 void Actor::SetPosition( float x, float y )
731 SetPosition( Vector3( x, y, 0.0f ) );
734 void Actor::SetPosition( float x, float y, float z )
736 SetPosition( Vector3( x, y, z ) );
739 void Actor::SetPosition( const Vector3& position )
741 mTargetPosition = position;
743 // node is being used in a separate thread; queue a message to set the value & base value
744 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
747 void Actor::SetX( float x )
749 mTargetPosition.x = x;
751 // node is being used in a separate thread; queue a message to set the value & base value
752 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
755 void Actor::SetY( float y )
757 mTargetPosition.y = y;
759 // node is being used in a separate thread; queue a message to set the value & base value
760 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
763 void Actor::SetZ( float z )
765 mTargetPosition.z = z;
767 // node is being used in a separate thread; queue a message to set the value & base value
768 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
771 void Actor::TranslateBy( const Vector3& distance )
773 mTargetPosition += distance;
775 // node is being used in a separate thread; queue a message to set the value & base value
776 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
779 const Vector3& Actor::GetCurrentPosition() const
781 // node is being used in a separate thread; copy the value from the previous update
782 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
785 const Vector3& Actor::GetTargetPosition() const
787 return mTargetPosition;
790 const Vector3& Actor::GetCurrentWorldPosition() const
792 // node is being used in a separate thread; copy the value from the previous update
793 return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
796 const Vector2 Actor::GetCurrentScreenPosition() const
798 if( mScene && OnStage() )
800 Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
801 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
802 worldPosition -= cameraPosition;
804 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
805 Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
806 Vector3 halfActorSize( actorSize * 0.5f );
807 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
809 return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
810 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
813 return Vector2::ZERO;
816 void Actor::SetInheritPosition( bool inherit )
818 if( mInheritPosition != inherit )
820 // non animatable so keep local copy
821 mInheritPosition = inherit;
822 SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
826 bool Actor::IsPositionInherited() const
828 return mInheritPosition;
831 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
833 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
834 normalizedAxis.Normalize();
836 Quaternion orientation( angle, normalizedAxis );
838 SetOrientation( orientation );
841 void Actor::SetOrientation( const Quaternion& orientation )
843 mTargetOrientation = orientation;
845 // node is being used in a separate thread; queue a message to set the value & base value
846 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
849 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
851 RotateBy( Quaternion(angle, axis) );
854 void Actor::RotateBy( const Quaternion& relativeRotation )
856 mTargetOrientation *= Quaternion( relativeRotation );
858 // node is being used in a separate thread; queue a message to set the value & base value
859 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
862 const Quaternion& Actor::GetCurrentOrientation() const
864 // node is being used in a separate thread; copy the value from the previous update
865 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
868 const Quaternion& Actor::GetCurrentWorldOrientation() const
870 // node is being used in a separate thread; copy the value from the previous update
871 return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
874 void Actor::SetScale( float scale )
876 SetScale( Vector3( scale, scale, scale ) );
879 void Actor::SetScale( float x, float y, float z )
881 SetScale( Vector3( x, y, z ) );
884 void Actor::SetScale( const Vector3& scale )
886 mTargetScale = scale;
888 // node is being used in a separate thread; queue a message to set the value & base value
889 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
892 void Actor::SetScaleX( float x )
896 // node is being used in a separate thread; queue a message to set the value & base value
897 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
900 void Actor::SetScaleY( float y )
904 // node is being used in a separate thread; queue a message to set the value & base value
905 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
908 void Actor::SetScaleZ( float z )
912 // node is being used in a separate thread; queue a message to set the value & base value
913 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
916 void Actor::ScaleBy(const Vector3& relativeScale)
918 mTargetScale *= relativeScale;
920 // node is being used in a separate thread; queue a message to set the value & base value
921 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
924 const Vector3& Actor::GetCurrentScale() const
926 // node is being used in a separate thread; copy the value from the previous update
927 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
930 const Vector3& Actor::GetCurrentWorldScale() const
932 // node is being used in a separate thread; copy the value from the previous update
933 return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
936 void Actor::SetInheritScale( bool inherit )
938 if( mInheritScale != inherit )
940 // non animatable so keep local copy
941 mInheritScale = inherit;
942 // node is being used in a separate thread; queue a message to set the value
943 SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
947 bool Actor::IsScaleInherited() const
949 return mInheritScale;
952 Matrix Actor::GetCurrentWorldMatrix() const
954 return GetNode().GetWorldMatrix(0);
957 void Actor::SetVisible( bool visible )
959 SetVisibleInternal( visible, SendMessage::TRUE );
962 bool Actor::IsVisible() const
964 // node is being used in a separate thread; copy the value from the previous update
965 return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
968 void Actor::SetOpacity( float opacity )
970 mTargetColor.a = opacity;
972 // node is being used in a separate thread; queue a message to set the value & base value
973 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
976 float Actor::GetCurrentOpacity() const
978 // node is being used in a separate thread; copy the value from the previous update
979 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
982 ClippingMode::Type Actor::GetClippingMode() const
984 return mClippingMode;
987 uint32_t Actor::GetSortingDepth()
992 const Vector4& Actor::GetCurrentWorldColor() const
994 return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
997 void Actor::SetColor( const Vector4& color )
999 mTargetColor = color;
1001 // node is being used in a separate thread; queue a message to set the value & base value
1002 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
1005 void Actor::SetColorRed( float red )
1007 mTargetColor.r = red;
1009 // node is being used in a separate thread; queue a message to set the value & base value
1010 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
1013 void Actor::SetColorGreen( float green )
1015 mTargetColor.g = green;
1017 // node is being used in a separate thread; queue a message to set the value & base value
1018 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green );
1021 void Actor::SetColorBlue( float blue )
1023 mTargetColor.b = blue;
1025 // node is being used in a separate thread; queue a message to set the value & base value
1026 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1029 const Vector4& Actor::GetCurrentColor() const
1031 // node is being used in a separate thread; copy the value from the previous update
1032 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
1035 void Actor::SetInheritOrientation( bool inherit )
1037 if( mInheritOrientation != inherit )
1039 // non animatable so keep local copy
1040 mInheritOrientation = inherit;
1041 // node is being used in a separate thread; queue a message to set the value
1042 SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
1046 bool Actor::IsOrientationInherited() const
1048 return mInheritOrientation;
1051 void Actor::SetSizeModeFactor( const Vector3& factor )
1053 EnsureRelayoutData();
1055 mRelayoutData->sizeModeFactor = factor;
1058 const Vector3& Actor::GetSizeModeFactor() const
1060 if ( mRelayoutData )
1062 return mRelayoutData->sizeModeFactor;
1065 return GetDefaultSizeModeFactor();
1068 void Actor::SetColorMode( ColorMode colorMode )
1070 // non animatable so keep local copy
1071 mColorMode = colorMode;
1072 // node is being used in a separate thread; queue a message to set the value
1073 SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
1076 ColorMode Actor::GetColorMode() const
1078 // we have cached copy
1082 void Actor::SetSize( float width, float height )
1084 SetSize( Vector2( width, height ) );
1087 void Actor::SetSize( float width, float height, float depth )
1089 SetSize( Vector3( width, height, depth ) );
1092 void Actor::SetSize( const Vector2& size )
1094 SetSize( Vector3( size.width, size.height, 0.f ) );
1097 void Actor::SetSizeInternal( const Vector2& size )
1099 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1102 void Actor::SetSize( const Vector3& size )
1104 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1106 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1107 SetPreferredSize( size.GetVectorXY() );
1111 SetSizeInternal( size );
1115 void Actor::SetSizeInternal( const Vector3& size )
1117 // dont allow recursive loop
1118 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1119 // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
1120 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1121 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1122 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1126 // node is being used in a separate thread; queue a message to set the value & base value
1127 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1129 // Notification for derived classes
1130 mInsideOnSizeSet = true;
1131 OnSizeSet( mTargetSize );
1132 mInsideOnSizeSet = false;
1134 // Raise a relayout request if the flag is not locked
1135 if( mRelayoutData && !mRelayoutData->insideRelayout )
1142 void Actor::SetWidth( float width )
1144 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1146 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1147 mRelayoutData->preferredSize.width = width;
1151 mTargetSize.width = width;
1153 // node is being used in a separate thread; queue a message to set the value & base value
1154 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1157 mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
1162 void Actor::SetHeight( float height )
1164 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1166 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1167 mRelayoutData->preferredSize.height = height;
1171 mTargetSize.height = height;
1173 // node is being used in a separate thread; queue a message to set the value & base value
1174 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1177 mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
1182 void Actor::SetDepth( float depth )
1184 mTargetSize.depth = depth;
1186 mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
1188 // node is being used in a separate thread; queue a message to set the value & base value
1189 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1192 Vector3 Actor::GetTargetSize() const
1194 Vector3 size = mTargetSize;
1196 if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH )
1198 // Should return animated size if size is animated
1199 size.width = mAnimatedSize.width;
1203 // Should return preferred size if size is fixed as set by SetSize
1204 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1206 size.width = GetPreferredSize().width;
1210 if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT )
1212 size.height = mAnimatedSize.height;
1216 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1218 size.height = GetPreferredSize().height;
1222 if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH )
1224 size.depth = mAnimatedSize.depth;
1230 const Vector3& Actor::GetCurrentSize() const
1232 // node is being used in a separate thread; copy the value from the previous update
1233 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1236 Vector3 Actor::GetNaturalSize() const
1238 // It is up to deriving classes to return the appropriate natural size
1239 return Vector3( 0.0f, 0.0f, 0.0f );
1242 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1244 EnsureRelayoutData();
1246 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1247 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1249 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1251 if( dimension & ( 1 << i ) )
1253 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1255 mRelayoutData->useAssignedSize[ i ] = true;
1259 mRelayoutData->resizePolicies[ i ] = policy;
1260 mRelayoutData->useAssignedSize[ i ] = false;
1265 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1267 if( dimension & Dimension::WIDTH )
1269 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1272 if( dimension & Dimension::HEIGHT )
1274 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1278 // If calling SetResizePolicy, assume we want relayout enabled
1279 SetRelayoutEnabled( true );
1281 // If the resize policy is set to be FIXED, the preferred size
1282 // should be overrided by the target size. Otherwise the target
1283 // size should be overrided by the preferred size.
1285 if( dimension & Dimension::WIDTH )
1287 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1289 mRelayoutData->preferredSize.width = mTargetSize.width;
1291 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1293 mTargetSize.width = mRelayoutData->preferredSize.width;
1297 if( dimension & Dimension::HEIGHT )
1299 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1301 mRelayoutData->preferredSize.height = mTargetSize.height;
1303 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1305 mTargetSize.height = mRelayoutData->preferredSize.height;
1309 OnSetResizePolicy( policy, dimension );
1311 // Trigger relayout on this control
1315 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1317 if ( mRelayoutData )
1319 // If more than one dimension is requested, just return the first one found
1320 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1322 if( ( dimension & ( 1 << i ) ) )
1324 if( mRelayoutData->useAssignedSize[ i ] )
1326 return ResizePolicy::USE_ASSIGNED_SIZE;
1330 return mRelayoutData->resizePolicies[ i ];
1336 return ResizePolicy::DEFAULT;
1339 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1341 EnsureRelayoutData();
1343 mRelayoutData->sizeSetPolicy = policy;
1345 // Trigger relayout on this control
1349 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1351 if ( mRelayoutData )
1353 return mRelayoutData->sizeSetPolicy;
1356 return DEFAULT_SIZE_SCALE_POLICY;
1359 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1361 EnsureRelayoutData();
1363 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1365 if( dimension & ( 1 << i ) )
1367 mRelayoutData->dimensionDependencies[ i ] = dependency;
1372 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1374 if ( mRelayoutData )
1376 // If more than one dimension is requested, just return the first one found
1377 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1379 if( ( dimension & ( 1 << i ) ) )
1381 return mRelayoutData->dimensionDependencies[ i ];
1386 return Dimension::ALL_DIMENSIONS; // Default
1389 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1391 // If relayout data has not been allocated yet and the client is requesting
1392 // to disable it, do nothing
1393 if( mRelayoutData || relayoutEnabled )
1395 EnsureRelayoutData();
1397 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1399 mRelayoutData->relayoutEnabled = relayoutEnabled;
1403 bool Actor::IsRelayoutEnabled() const
1405 // Assume that if relayout data has not been allocated yet then
1406 // relayout is disabled
1407 return mRelayoutData && mRelayoutData->relayoutEnabled;
1410 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1412 EnsureRelayoutData();
1414 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1416 if( dimension & ( 1 << i ) )
1418 mRelayoutData->dimensionDirty[ i ] = dirty;
1423 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1425 if ( mRelayoutData )
1427 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1429 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1439 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1441 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1444 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1446 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1449 uint32_t Actor::AddRenderer( Renderer& renderer )
1453 mRenderers = new RendererContainer;
1456 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1457 RendererPtr rendererPtr = RendererPtr( &renderer );
1458 mRenderers->push_back( rendererPtr );
1459 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1463 uint32_t Actor::GetRendererCount() const
1465 uint32_t rendererCount(0);
1468 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1471 return rendererCount;
1474 RendererPtr Actor::GetRendererAt( uint32_t index )
1476 RendererPtr renderer;
1477 if( index < GetRendererCount() )
1479 renderer = ( *mRenderers )[ index ];
1485 void Actor::RemoveRenderer( Renderer& renderer )
1489 RendererIter end = mRenderers->end();
1490 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1492 if( (*iter).Get() == &renderer )
1494 mRenderers->erase( iter );
1495 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1502 void Actor::RemoveRenderer( uint32_t index )
1504 if( index < GetRendererCount() )
1506 RendererPtr renderer = ( *mRenderers )[ index ];
1507 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1508 mRenderers->erase( mRenderers->begin()+index );
1512 bool Actor::IsOverlay() const
1514 return ( DrawMode::OVERLAY_2D == mDrawMode );
1517 void Actor::SetDrawMode( DrawMode::Type drawMode )
1519 // this flag is not animatable so keep the value
1520 mDrawMode = drawMode;
1522 // node is being used in a separate thread; queue a message to set the value
1523 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1526 DrawMode::Type Actor::GetDrawMode() const
1531 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1533 // only valid when on-stage
1534 if( mScene && OnStage() )
1536 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1538 Vector2 converted( screenX, screenY );
1540 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1541 uint32_t taskCount = taskList.GetTaskCount();
1542 for( uint32_t i = taskCount; i > 0; --i )
1544 RenderTaskPtr task = taskList.GetTask( i - 1 );
1545 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1547 // found a task where this conversion was ok so return
1555 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1557 bool retval = false;
1558 // only valid when on-stage
1561 CameraActor* camera = renderTask.GetCameraActor();
1565 renderTask.GetViewport( viewport );
1567 // need to translate coordinates to render tasks coordinate space
1568 Vector2 converted( screenX, screenY );
1569 if( renderTask.TranslateCoordinates( converted ) )
1571 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1578 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1580 // Early-out if not on stage
1586 // Get the ModelView matrix
1588 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1590 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1591 Matrix invertedMvp( false/*don't init*/);
1592 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1593 bool success = invertedMvp.Invert();
1595 // Convert to GL coordinates
1596 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1601 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1608 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1614 if( XyPlaneIntersect( nearPos, farPos, local ) )
1616 Vector3 size = GetCurrentSize();
1617 localX = local.x + size.x * 0.5f;
1618 localY = local.y + size.y * 0.5f;
1629 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1632 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1634 Mathematical Formulation
1636 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1638 ( p - c ) dot ( p - c ) = r^2
1640 Given a ray with a point of origin 'o', and a direction vector 'd':
1642 ray(t) = o + td, t >= 0
1644 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1646 (o + td - c ) dot ( o + td - c ) = r^2
1648 To solve for t we first expand the above into a more recognisable quadratic equation form
1650 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1659 B = 2( o - c ) dot d
1660 C = ( o - c ) dot ( o - c ) - r^2
1662 which can be solved using a standard quadratic formula.
1664 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1666 Practical Simplification
1668 In a renderer, we often differentiate between world space and object space. In the object space
1669 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1670 into object space, the mathematical solution presented above can be simplified significantly.
1672 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1676 and we can find the t at which the (transformed) ray intersects the sphere by
1678 ( o + td ) dot ( o + td ) = r^2
1680 According to the reasoning above, we expand the above quadratic equation into the general form
1684 which now has coefficients:
1691 // Early-out if not on stage
1697 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1699 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1700 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1701 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1703 // Compute the radius is not needed, square radius it's enough.
1704 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1706 // Scale the sphere.
1707 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1709 const float width = size.width * scale.width;
1710 const float height = size.height * scale.height;
1712 float squareSphereRadius = 0.5f * ( width * width + height * height );
1714 float a = rayDir.Dot( rayDir ); // a
1715 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1716 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1718 return ( b2 * b2 - a * c ) >= 0.f;
1721 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1727 // Transforms the ray to the local reference system.
1728 // Calculate the inverse of Model matrix
1729 Matrix invModelMatrix( false/*don't init*/);
1731 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1732 invModelMatrix = GetNode().GetWorldMatrix(0);
1733 invModelMatrix.Invert();
1735 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1736 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1738 // Test with the actor's XY plane (Normal = 0 0 1 1).
1740 float a = -rayOriginLocal.z;
1741 float b = rayDirLocal.z;
1743 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1745 // Ray travels distance * rayDirLocal to intersect with plane.
1748 const Vector3& size = GetNode().GetSize( bufferIndex );
1750 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1751 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1753 // Test with the actor's geometry.
1754 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1761 void Actor::SetLeaveRequired( bool required )
1763 mLeaveRequired = required;
1766 bool Actor::GetLeaveRequired() const
1768 return mLeaveRequired;
1771 void Actor::SetKeyboardFocusable( bool focusable )
1773 mKeyboardFocusable = focusable;
1776 bool Actor::IsKeyboardFocusable() const
1778 return mKeyboardFocusable;
1781 bool Actor::GetTouchRequired() const
1783 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1786 bool Actor::GetHoverRequired() const
1788 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1791 bool Actor::GetWheelEventRequired() const
1793 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1796 bool Actor::IsHittable() const
1798 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1801 ActorGestureData& Actor::GetGestureData()
1803 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1804 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1805 if( NULL == mGestureData )
1807 mGestureData = new ActorGestureData;
1809 return *mGestureData;
1812 bool Actor::IsGestureRequred( DevelGesture::Type type ) const
1814 return mGestureData && mGestureData->IsGestureRequred( type );
1817 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1819 bool consumed = false;
1821 if( !mTouchSignal.Empty() )
1823 Dali::Actor handle( this );
1824 consumed = mTouchSignal.Emit( handle, touch );
1827 if( !mTouchedSignal.Empty() )
1829 Dali::Actor handle( this );
1830 consumed |= mTouchedSignal.Emit( handle, event );
1835 // Notification for derived classes
1836 consumed = OnTouchEvent( event ); // TODO
1842 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1844 bool consumed = false;
1846 if( !mHoveredSignal.Empty() )
1848 Dali::Actor handle( this );
1849 consumed = mHoveredSignal.Emit( handle, event );
1854 // Notification for derived classes
1855 consumed = OnHoverEvent( event );
1861 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1863 bool consumed = false;
1865 if( !mWheelEventSignal.Empty() )
1867 Dali::Actor handle( this );
1868 consumed = mWheelEventSignal.Emit( handle, event );
1873 // Notification for derived classes
1874 consumed = OnWheelEvent( event );
1880 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1882 if( ! mVisibilityChangedSignal.Empty() )
1884 Dali::Actor handle( this );
1885 mVisibilityChangedSignal.Emit( handle, visible, type );
1889 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1891 if( ! mLayoutDirectionChangedSignal.Empty() )
1893 Dali::Actor handle( this );
1894 mLayoutDirectionChangedSignal.Emit( handle, type );
1898 void Actor::EmitChildAddedSignal( Actor& child )
1900 if( ! mChildAddedSignal.Empty() )
1902 Dali::Actor handle( &child );
1903 mChildAddedSignal.Emit( handle );
1907 void Actor::EmitChildRemovedSignal( Actor& child )
1909 if( ! mChildRemovedSignal.Empty() )
1911 Dali::Actor handle( &child );
1912 mChildRemovedSignal.Emit( handle );
1916 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1918 return mTouchedSignal;
1921 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1923 return mTouchSignal;
1926 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1928 return mHoveredSignal;
1931 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1933 return mWheelEventSignal;
1936 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1938 return mOnStageSignal;
1941 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1943 return mOffStageSignal;
1946 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1948 return mOnRelayoutSignal;
1951 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1953 return mVisibilityChangedSignal;
1956 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1958 return mLayoutDirectionChangedSignal;
1961 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1963 return mChildAddedSignal;
1966 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1968 return mChildRemovedSignal;
1971 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1973 return mChildOrderChangedSignal;
1976 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1978 bool connected( true );
1979 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1981 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1983 actor->TouchedSignal().Connect( tracker, functor );
1985 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1987 actor->HoveredSignal().Connect( tracker, functor );
1989 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1991 actor->WheelEventSignal().Connect( tracker, functor );
1993 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1995 actor->OnStageSignal().Connect( tracker, functor );
1997 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1999 actor->OffStageSignal().Connect( tracker, functor );
2001 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2003 actor->OnRelayoutSignal().Connect( tracker, functor );
2005 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2007 actor->TouchSignal().Connect( tracker, functor );
2009 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
2011 actor->VisibilityChangedSignal().Connect( tracker, functor );
2013 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2015 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2017 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2019 actor->ChildAddedSignal().Connect( tracker, functor );
2021 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2023 actor->ChildRemovedSignal().Connect( tracker, functor );
2027 // signalName does not match any signal
2034 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2040 mParentOrigin( NULL ),
2041 mAnchorPoint( NULL ),
2042 mRelayoutData( NULL ),
2043 mGestureData( NULL ),
2047 mWheelEventSignal(),
2050 mOnRelayoutSignal(),
2051 mVisibilityChangedSignal(),
2052 mLayoutDirectionChangedSignal(),
2053 mChildAddedSignal(),
2054 mChildRemovedSignal(),
2055 mChildOrderChangedSignal(),
2056 mTargetOrientation( Quaternion::IDENTITY ),
2057 mTargetColor( Color::WHITE ),
2058 mTargetSize( Vector3::ZERO ),
2059 mTargetPosition( Vector3::ZERO ),
2060 mTargetScale( Vector3::ONE ),
2061 mAnimatedSize( Vector3::ZERO ),
2065 mUseAnimatedSize( AnimatedSizeFlag::CLEAR ),
2066 mIsRoot( ROOT_LAYER == derivedType ),
2067 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2068 mIsOnStage( false ),
2070 mLeaveRequired( false ),
2071 mKeyboardFocusable( false ),
2072 mDerivedRequiresTouch( false ),
2073 mDerivedRequiresHover( false ),
2074 mDerivedRequiresWheelEvent( false ),
2075 mOnStageSignalled( false ),
2076 mInsideOnSizeSet( false ),
2077 mInheritPosition( true ),
2078 mInheritOrientation( true ),
2079 mInheritScale( true ),
2080 mPositionUsesAnchorPoint( true ),
2082 mInheritLayoutDirection( true ),
2083 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2084 mDrawMode( DrawMode::NORMAL ),
2085 mColorMode( Node::DEFAULT_COLOR_MODE ),
2086 mClippingMode( ClippingMode::DISABLED )
2090 void Actor::Initialize()
2094 GetEventThreadServices().RegisterObject( this );
2099 // Remove mParent pointers from children even if we're destroying core,
2100 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2103 ActorConstIter endIter = mChildren->end();
2104 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2106 (*iter)->SetParent( NULL );
2112 // Guard to allow handle destruction after Core has been destroyed
2113 if( EventThreadServices::IsCoreRunning() )
2115 // Root layer will destroy its node in its own destructor
2118 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2120 GetEventThreadServices().UnregisterObject( this );
2124 // Cleanup optional gesture data
2125 delete mGestureData;
2127 // Cleanup optional parent origin and anchor
2128 delete mParentOrigin;
2129 delete mAnchorPoint;
2131 // Delete optional relayout data
2132 delete mRelayoutData;
2135 void Actor::ConnectToStage( uint32_t parentDepth )
2137 // This container is used instead of walking the Actor hierarchy.
2138 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2139 ActorContainer connectionList;
2143 mScene->RequestRebuildDepthTree();
2146 // This stage is atomic i.e. not interrupted by user callbacks.
2147 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2149 // Notify applications about the newly connected actors.
2150 const ActorIter endIter = connectionList.end();
2151 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2153 (*iter)->NotifyStageConnection();
2159 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2161 DALI_ASSERT_ALWAYS( !OnStage() );
2164 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2166 ConnectToSceneGraph();
2168 // Notification for internal derived classes
2169 OnStageConnectionInternal();
2171 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2172 connectionList.push_back( ActorPtr( this ) );
2174 // Recursively connect children
2177 ActorConstIter endIter = mChildren->end();
2178 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2180 (*iter)->SetScene( *mScene );
2181 (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2187 * This method is called when the Actor is connected to the Stage.
2188 * The parent must have added its Node to the scene-graph.
2189 * The child must connect its Node to the parent's Node.
2190 * This is recursive; the child calls ConnectToStage() for its children.
2192 void Actor::ConnectToSceneGraph()
2194 DALI_ASSERT_DEBUG( mParent != NULL);
2196 // Reparent Node in next Update
2197 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2199 // Request relayout on all actors that are added to the scenegraph
2202 // Notification for Object::Observers
2206 void Actor::NotifyStageConnection()
2208 // Actors can be removed (in a callback), before the on-stage stage is reported.
2209 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2210 if( OnStage() && !mOnStageSignalled )
2212 // Notification for external (CustomActor) derived classes
2213 OnStageConnectionExternal( mDepth );
2215 if( !mOnStageSignal.Empty() )
2217 Dali::Actor handle( this );
2218 mOnStageSignal.Emit( handle );
2221 // Guard against Remove during callbacks
2224 mOnStageSignalled = true; // signal required next time Actor is removed
2229 void Actor::DisconnectFromStage()
2231 // This container is used instead of walking the Actor hierachy.
2232 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2233 ActorContainer disconnectionList;
2237 mScene->RequestRebuildDepthTree();
2240 // This stage is atomic i.e. not interrupted by user callbacks
2241 RecursiveDisconnectFromStage( disconnectionList );
2243 // Notify applications about the newly disconnected actors.
2244 const ActorIter endIter = disconnectionList.end();
2245 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2247 (*iter)->NotifyStageDisconnection();
2251 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2253 // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2256 // Recursively disconnect children
2259 ActorConstIter endIter = mChildren->end();
2260 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2262 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2266 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2267 disconnectionList.push_back( ActorPtr( this ) );
2269 // Notification for internal derived classes
2270 OnStageDisconnectionInternal();
2272 DisconnectFromSceneGraph();
2276 * This method is called by an actor or its parent, before a node removal message is sent.
2277 * This is recursive; the child calls DisconnectFromStage() for its children.
2279 void Actor::DisconnectFromSceneGraph()
2281 // Notification for Object::Observers
2282 OnSceneObjectRemove();
2285 void Actor::NotifyStageDisconnection()
2287 // Actors can be added (in a callback), before the off-stage state is reported.
2288 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2289 // only do this step if there is a stage, i.e. Core is not being shut down
2290 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2292 // Notification for external (CustomeActor) derived classes
2293 OnStageDisconnectionExternal();
2295 if( !mOffStageSignal.Empty() )
2297 Dali::Actor handle( this );
2298 mOffStageSignal.Emit( handle );
2301 // Guard against Add during callbacks
2304 mOnStageSignalled = false; // signal required next time Actor is added
2309 bool Actor::IsNodeConnected() const
2311 bool connected( false );
2315 if( IsRoot() || GetNode().GetParent() )
2324 // This method initiates traversal of the actor tree using depth-first
2325 // traversal to set a depth index based on traversal order. It sends a
2326 // single message to update manager to update all the actor's nodes in
2327 // this tree with the depth index. The sceneGraphNodeDepths vector's
2328 // elements are ordered by depth, and could be used to reduce sorting
2329 // in the update thread.
2330 void Actor::RebuildDepthTree()
2332 DALI_LOG_TIMER_START(depthTimer);
2334 // Vector of scene-graph nodes and their depths to send to UpdateManager
2335 // in a single message
2336 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2338 int32_t depthIndex = 1;
2339 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2341 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2342 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2345 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2347 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2348 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2350 // Create/add to children of this node
2353 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2355 Actor* childActor = (*it).Get();
2357 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2362 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2366 case Dali::Actor::Property::PARENT_ORIGIN:
2368 Property::Type type = property.GetType();
2369 if( type == Property::VECTOR3 )
2371 SetParentOrigin( property.Get< Vector3 >() );
2373 else if ( type == Property::STRING )
2375 std::string parentOriginString;
2376 property.Get( parentOriginString );
2377 Vector3 parentOrigin;
2378 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2380 SetParentOrigin( parentOrigin );
2386 case Dali::Actor::Property::PARENT_ORIGIN_X:
2388 SetParentOriginX( property.Get< float >() );
2392 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2394 SetParentOriginY( property.Get< float >() );
2398 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2400 SetParentOriginZ( property.Get< float >() );
2404 case Dali::Actor::Property::ANCHOR_POINT:
2406 Property::Type type = property.GetType();
2407 if( type == Property::VECTOR3 )
2409 SetAnchorPoint( property.Get< Vector3 >() );
2411 else if ( type == Property::STRING )
2413 std::string anchorPointString;
2414 property.Get( anchorPointString );
2416 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2418 SetAnchorPoint( anchor );
2424 case Dali::Actor::Property::ANCHOR_POINT_X:
2426 SetAnchorPointX( property.Get< float >() );
2430 case Dali::Actor::Property::ANCHOR_POINT_Y:
2432 SetAnchorPointY( property.Get< float >() );
2436 case Dali::Actor::Property::ANCHOR_POINT_Z:
2438 SetAnchorPointZ( property.Get< float >() );
2442 case Dali::Actor::Property::SIZE:
2444 Property::Type type = property.GetType();
2445 if( type == Property::VECTOR2 )
2447 SetSize( property.Get< Vector2 >() );
2449 else if ( type == Property::VECTOR3 )
2451 SetSize( property.Get< Vector3 >() );
2456 case Dali::Actor::Property::SIZE_WIDTH:
2458 SetWidth( property.Get< float >() );
2462 case Dali::Actor::Property::SIZE_HEIGHT:
2464 SetHeight( property.Get< float >() );
2468 case Dali::Actor::Property::SIZE_DEPTH:
2470 SetDepth( property.Get< float >() );
2474 case Dali::Actor::Property::POSITION:
2476 Property::Type type = property.GetType();
2477 if( type == Property::VECTOR2 )
2479 Vector2 position = property.Get< Vector2 >();
2480 SetPosition( Vector3( position.x, position.y, 0.0f ) );
2482 else if ( type == Property::VECTOR3 )
2484 SetPosition( property.Get< Vector3 >() );
2489 case Dali::Actor::Property::POSITION_X:
2491 SetX( property.Get< float >() );
2495 case Dali::Actor::Property::POSITION_Y:
2497 SetY( property.Get< float >() );
2501 case Dali::Actor::Property::POSITION_Z:
2503 SetZ( property.Get< float >() );
2507 case Dali::Actor::Property::ORIENTATION:
2509 SetOrientation( property.Get< Quaternion >() );
2513 case Dali::Actor::Property::SCALE:
2515 Property::Type type = property.GetType();
2516 if( type == Property::FLOAT )
2518 float scale = property.Get< float >();
2519 SetScale( scale, scale, scale );
2521 else if ( type == Property::VECTOR3 )
2523 SetScale( property.Get< Vector3 >() );
2528 case Dali::Actor::Property::SCALE_X:
2530 SetScaleX( property.Get< float >() );
2534 case Dali::Actor::Property::SCALE_Y:
2536 SetScaleY( property.Get< float >() );
2540 case Dali::Actor::Property::SCALE_Z:
2542 SetScaleZ( property.Get< float >() );
2546 case Dali::Actor::Property::VISIBLE:
2548 SetVisible( property.Get< bool >() );
2552 case Dali::Actor::Property::COLOR:
2554 Property::Type type = property.GetType();
2555 if( type == Property::VECTOR3 )
2557 Vector3 color = property.Get< Vector3 >();
2558 SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2560 else if( type == Property::VECTOR4 )
2562 SetColor( property.Get< Vector4 >() );
2567 case Dali::Actor::Property::COLOR_RED:
2569 SetColorRed( property.Get< float >() );
2573 case Dali::Actor::Property::COLOR_GREEN:
2575 SetColorGreen( property.Get< float >() );
2579 case Dali::Actor::Property::COLOR_BLUE:
2581 SetColorBlue( property.Get< float >() );
2585 case Dali::Actor::Property::COLOR_ALPHA:
2586 case Dali::DevelActor::Property::OPACITY:
2589 if( property.Get( value ) )
2591 SetOpacity( value );
2596 case Dali::Actor::Property::NAME:
2598 SetName( property.Get< std::string >() );
2602 case Dali::Actor::Property::SENSITIVE:
2604 SetSensitive( property.Get< bool >() );
2608 case Dali::Actor::Property::LEAVE_REQUIRED:
2610 SetLeaveRequired( property.Get< bool >() );
2614 case Dali::Actor::Property::INHERIT_POSITION:
2616 SetInheritPosition( property.Get< bool >() );
2620 case Dali::Actor::Property::INHERIT_ORIENTATION:
2622 SetInheritOrientation( property.Get< bool >() );
2626 case Dali::Actor::Property::INHERIT_SCALE:
2628 SetInheritScale( property.Get< bool >() );
2632 case Dali::Actor::Property::COLOR_MODE:
2634 ColorMode mode = mColorMode;
2635 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2637 SetColorMode( mode );
2642 case Dali::Actor::Property::DRAW_MODE:
2644 DrawMode::Type mode = mDrawMode;
2645 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2647 SetDrawMode( mode );
2652 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2654 SetSizeModeFactor( property.Get< Vector3 >() );
2658 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2660 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2661 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2663 SetResizePolicy( type, Dimension::WIDTH );
2668 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2670 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2671 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2673 SetResizePolicy( type, Dimension::HEIGHT );
2678 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2680 SizeScalePolicy::Type type = GetSizeScalePolicy();
2681 if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2683 SetSizeScalePolicy( type );
2688 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2690 if( property.Get< bool >() )
2692 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2697 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2699 if( property.Get< bool >() )
2701 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2706 case Dali::Actor::Property::PADDING:
2708 Vector4 padding = property.Get< Vector4 >();
2709 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2710 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2714 case Dali::Actor::Property::MINIMUM_SIZE:
2716 Vector2 size = property.Get< Vector2 >();
2717 SetMinimumSize( size.x, Dimension::WIDTH );
2718 SetMinimumSize( size.y, Dimension::HEIGHT );
2722 case Dali::Actor::Property::MAXIMUM_SIZE:
2724 Vector2 size = property.Get< Vector2 >();
2725 SetMaximumSize( size.x, Dimension::WIDTH );
2726 SetMaximumSize( size.y, Dimension::HEIGHT );
2730 case Dali::DevelActor::Property::SIBLING_ORDER:
2734 if( property.Get( value ) )
2736 SetSiblingOrder( value );
2741 case Dali::Actor::Property::CLIPPING_MODE:
2743 ClippingMode::Type convertedValue = mClippingMode;
2744 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2746 mClippingMode = convertedValue;
2747 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2752 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2755 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2757 mPositionUsesAnchorPoint = value;
2758 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2763 case Dali::Actor::Property::LAYOUT_DIRECTION:
2765 Dali::LayoutDirection::Type direction = mLayoutDirection;
2766 mInheritLayoutDirection = false;
2768 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2770 InheritLayoutDirectionRecursively( this, direction, true );
2775 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2778 if( property.Get( value ) )
2780 SetInheritLayoutDirection( value );
2787 // this can happen in the case of a non-animatable default property so just do nothing
2793 // TODO: This method needs to be removed
2794 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2796 switch( entry.GetType() )
2798 case Property::BOOLEAN:
2800 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2801 DALI_ASSERT_DEBUG( NULL != property );
2803 // property is being used in a separate thread; queue a message to set the property
2804 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2809 case Property::INTEGER:
2811 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2812 DALI_ASSERT_DEBUG( NULL != property );
2814 // property is being used in a separate thread; queue a message to set the property
2815 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2820 case Property::FLOAT:
2822 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2823 DALI_ASSERT_DEBUG( NULL != property );
2825 // property is being used in a separate thread; queue a message to set the property
2826 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2831 case Property::VECTOR2:
2833 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2834 DALI_ASSERT_DEBUG( NULL != property );
2836 // property is being used in a separate thread; queue a message to set the property
2837 if(entry.componentIndex == 0)
2839 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2841 else if(entry.componentIndex == 1)
2843 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2847 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2853 case Property::VECTOR3:
2855 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2856 DALI_ASSERT_DEBUG( NULL != property );
2858 // property is being used in a separate thread; queue a message to set the property
2859 if(entry.componentIndex == 0)
2861 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2863 else if(entry.componentIndex == 1)
2865 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2867 else if(entry.componentIndex == 2)
2869 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2873 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2879 case Property::VECTOR4:
2881 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2882 DALI_ASSERT_DEBUG( NULL != property );
2884 // property is being used in a separate thread; queue a message to set the property
2885 if(entry.componentIndex == 0)
2887 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2889 else if(entry.componentIndex == 1)
2891 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2893 else if(entry.componentIndex == 2)
2895 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2897 else if(entry.componentIndex == 3)
2899 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2903 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2909 case Property::ROTATION:
2911 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2912 DALI_ASSERT_DEBUG( NULL != property );
2914 // property is being used in a separate thread; queue a message to set the property
2915 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2920 case Property::MATRIX:
2922 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2923 DALI_ASSERT_DEBUG( NULL != property );
2925 // property is being used in a separate thread; queue a message to set the property
2926 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2931 case Property::MATRIX3:
2933 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2934 DALI_ASSERT_DEBUG( NULL != property );
2936 // property is being used in a separate thread; queue a message to set the property
2937 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2944 // nothing to do for other types
2949 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2951 Property::Value value;
2953 if( ! GetCachedPropertyValue( index, value ) )
2955 // If property value is not stored in the event-side, then it must be a scene-graph only property
2956 GetCurrentPropertyValue( index, value );
2962 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2964 Property::Value value;
2966 if( ! GetCurrentPropertyValue( index, value ) )
2968 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2969 GetCachedPropertyValue( index, value );
2975 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2977 switch( animationType )
2980 case Animation::BETWEEN:
2984 case Dali::Actor::Property::SIZE:
2986 if( value.Get( mTargetSize ) )
2988 mAnimatedSize = mTargetSize;
2989 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
2991 // Notify deriving classes
2992 OnSizeAnimation( animation, mTargetSize );
2997 case Dali::Actor::Property::SIZE_WIDTH:
2999 if( value.Get( mTargetSize.width ) )
3001 mAnimatedSize.width = mTargetSize.width;
3002 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3004 // Notify deriving classes
3005 OnSizeAnimation( animation, mTargetSize );
3010 case Dali::Actor::Property::SIZE_HEIGHT:
3012 if( value.Get( mTargetSize.height ) )
3014 mAnimatedSize.height = mTargetSize.height;
3015 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3017 // Notify deriving classes
3018 OnSizeAnimation( animation, mTargetSize );
3023 case Dali::Actor::Property::SIZE_DEPTH:
3025 if( value.Get( mTargetSize.depth ) )
3027 mAnimatedSize.depth = mTargetSize.depth;
3028 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3030 // Notify deriving classes
3031 OnSizeAnimation( animation, mTargetSize );
3036 case Dali::Actor::Property::POSITION:
3038 value.Get( mTargetPosition );
3042 case Dali::Actor::Property::POSITION_X:
3044 value.Get( mTargetPosition.x );
3048 case Dali::Actor::Property::POSITION_Y:
3050 value.Get( mTargetPosition.y );
3054 case Dali::Actor::Property::POSITION_Z:
3056 value.Get( mTargetPosition.z );
3060 case Dali::Actor::Property::ORIENTATION:
3062 value.Get( mTargetOrientation );
3066 case Dali::Actor::Property::SCALE:
3068 value.Get( mTargetScale );
3072 case Dali::Actor::Property::SCALE_X:
3074 value.Get( mTargetScale.x );
3078 case Dali::Actor::Property::SCALE_Y:
3080 value.Get( mTargetScale.y );
3084 case Dali::Actor::Property::SCALE_Z:
3086 value.Get( mTargetScale.z );
3090 case Dali::Actor::Property::VISIBLE:
3092 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3096 case Dali::Actor::Property::COLOR:
3098 value.Get( mTargetColor );
3102 case Dali::Actor::Property::COLOR_RED:
3104 value.Get( mTargetColor.r );
3108 case Dali::Actor::Property::COLOR_GREEN:
3110 value.Get( mTargetColor.g );
3114 case Dali::Actor::Property::COLOR_BLUE:
3116 value.Get( mTargetColor.b );
3120 case Dali::Actor::Property::COLOR_ALPHA:
3121 case Dali::DevelActor::Property::OPACITY:
3123 value.Get( mTargetColor.a );
3129 // Not an animatable property. Do nothing.
3140 case Dali::Actor::Property::SIZE:
3142 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3144 mAnimatedSize = mTargetSize;
3145 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3147 // Notify deriving classes
3148 OnSizeAnimation( animation, mTargetSize );
3153 case Dali::Actor::Property::SIZE_WIDTH:
3155 if( AdjustValue< float >( mTargetSize.width, value ) )
3157 mAnimatedSize.width = mTargetSize.width;
3158 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3160 // Notify deriving classes
3161 OnSizeAnimation( animation, mTargetSize );
3166 case Dali::Actor::Property::SIZE_HEIGHT:
3168 if( AdjustValue< float >( mTargetSize.height, value ) )
3170 mAnimatedSize.height = mTargetSize.height;
3171 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3173 // Notify deriving classes
3174 OnSizeAnimation( animation, mTargetSize );
3179 case Dali::Actor::Property::SIZE_DEPTH:
3181 if( AdjustValue< float >( mTargetSize.depth, value ) )
3183 mAnimatedSize.depth = mTargetSize.depth;
3184 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3186 // Notify deriving classes
3187 OnSizeAnimation( animation, mTargetSize );
3192 case Dali::Actor::Property::POSITION:
3194 AdjustValue< Vector3 >( mTargetPosition, value );
3198 case Dali::Actor::Property::POSITION_X:
3200 AdjustValue< float >( mTargetPosition.x, value );
3204 case Dali::Actor::Property::POSITION_Y:
3206 AdjustValue< float >( mTargetPosition.y, value );
3210 case Dali::Actor::Property::POSITION_Z:
3212 AdjustValue< float >( mTargetPosition.z, value );
3216 case Dali::Actor::Property::ORIENTATION:
3218 Quaternion relativeValue;
3219 if( value.Get( relativeValue ) )
3221 mTargetOrientation *= relativeValue;
3226 case Dali::Actor::Property::SCALE:
3228 AdjustValue< Vector3 >( mTargetScale, value );
3232 case Dali::Actor::Property::SCALE_X:
3234 AdjustValue< float >( mTargetScale.x, value );
3238 case Dali::Actor::Property::SCALE_Y:
3240 AdjustValue< float >( mTargetScale.y, value );
3244 case Dali::Actor::Property::SCALE_Z:
3246 AdjustValue< float >( mTargetScale.z, value );
3250 case Dali::Actor::Property::VISIBLE:
3252 bool relativeValue = false;
3253 if( value.Get( relativeValue ) )
3255 bool visible = mVisible || relativeValue;
3256 SetVisibleInternal( visible, SendMessage::FALSE );
3261 case Dali::Actor::Property::COLOR:
3263 AdjustValue< Vector4 >( mTargetColor, value );
3267 case Dali::Actor::Property::COLOR_RED:
3269 AdjustValue< float >( mTargetColor.r, value );
3273 case Dali::Actor::Property::COLOR_GREEN:
3275 AdjustValue< float >( mTargetColor.g, value );
3279 case Dali::Actor::Property::COLOR_BLUE:
3281 AdjustValue< float >( mTargetColor.b, value );
3285 case Dali::Actor::Property::COLOR_ALPHA:
3286 case Dali::DevelActor::Property::OPACITY:
3288 AdjustValue< float >( mTargetColor.a, value );
3294 // Not an animatable property. Do nothing.
3303 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3305 const PropertyBase* property( NULL );
3309 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3310 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3311 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3312 case Dali::Actor::Property::SIZE_DEPTH:
3314 property = &GetNode().mSize;
3317 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3318 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3319 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3320 case Dali::Actor::Property::POSITION_Z:
3322 property = &GetNode().mPosition;
3325 case Dali::Actor::Property::ORIENTATION:
3327 property = &GetNode().mOrientation;
3330 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3331 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3332 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3333 case Dali::Actor::Property::SCALE_Z:
3335 property = &GetNode().mScale;
3338 case Dali::Actor::Property::VISIBLE:
3340 property = &GetNode().mVisible;
3343 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3344 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3345 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3346 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3347 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3348 case Dali::DevelActor::Property::OPACITY:
3350 property = &GetNode().mColor;
3360 // not our property, ask base
3361 property = Object::GetSceneObjectAnimatableProperty( index );
3367 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3369 const PropertyInputImpl* property( NULL );
3373 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3374 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3375 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3376 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3378 property = &GetNode().mParentOrigin;
3381 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3382 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3383 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3384 case Dali::Actor::Property::ANCHOR_POINT_Z:
3386 property = &GetNode().mAnchorPoint;
3389 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3390 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3391 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3392 case Dali::Actor::Property::WORLD_POSITION_Z:
3394 property = &GetNode().mWorldPosition;
3397 case Dali::Actor::Property::WORLD_ORIENTATION:
3399 property = &GetNode().mWorldOrientation;
3402 case Dali::Actor::Property::WORLD_SCALE:
3404 property = &GetNode().mWorldScale;
3407 case Dali::Actor::Property::WORLD_COLOR:
3409 property = &GetNode().mWorldColor;
3412 case Dali::Actor::Property::WORLD_MATRIX:
3414 property = &GetNode().mWorldMatrix;
3417 case Dali::DevelActor::Property::CULLED:
3419 property = &GetNode().mCulled;
3429 // reuse animatable property getter as animatable properties are inputs as well
3430 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3431 property = GetSceneObjectAnimatableProperty( index );
3437 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3439 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3443 case Dali::Actor::Property::PARENT_ORIGIN_X:
3444 case Dali::Actor::Property::ANCHOR_POINT_X:
3445 case Dali::Actor::Property::SIZE_WIDTH:
3446 case Dali::Actor::Property::POSITION_X:
3447 case Dali::Actor::Property::WORLD_POSITION_X:
3448 case Dali::Actor::Property::SCALE_X:
3449 case Dali::Actor::Property::COLOR_RED:
3455 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3456 case Dali::Actor::Property::ANCHOR_POINT_Y:
3457 case Dali::Actor::Property::SIZE_HEIGHT:
3458 case Dali::Actor::Property::POSITION_Y:
3459 case Dali::Actor::Property::WORLD_POSITION_Y:
3460 case Dali::Actor::Property::SCALE_Y:
3461 case Dali::Actor::Property::COLOR_GREEN:
3467 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3468 case Dali::Actor::Property::ANCHOR_POINT_Z:
3469 case Dali::Actor::Property::SIZE_DEPTH:
3470 case Dali::Actor::Property::POSITION_Z:
3471 case Dali::Actor::Property::WORLD_POSITION_Z:
3472 case Dali::Actor::Property::SCALE_Z:
3473 case Dali::Actor::Property::COLOR_BLUE:
3479 case Dali::Actor::Property::COLOR_ALPHA:
3480 case Dali::DevelActor::Property::OPACITY:
3492 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3495 componentIndex = Object::GetPropertyComponentIndex( index );
3498 return componentIndex;
3501 void Actor::SetParent( Actor* parent )
3505 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3509 mScene = parent->mScene;
3511 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3514 // Instruct each actor to create a corresponding node in the scene graph
3515 ConnectToStage( parent->GetHierarchyDepth() );
3518 // Resolve the name and index for the child properties if any
3519 ResolveChildProperties();
3521 else // parent being set to NULL
3523 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3527 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3530 // Disconnect the Node & its children from the scene-graph.
3531 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3533 // Instruct each actor to discard pointers to the scene-graph
3534 DisconnectFromStage();
3541 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3544 Actor* actor = dynamic_cast< Actor* >( object );
3548 if( 0 == actionName.compare( ACTION_SHOW ) )
3550 actor->SetVisible( true );
3553 else if( 0 == actionName.compare( ACTION_HIDE ) )
3555 actor->SetVisible( false );
3563 Rect<> Actor::CalculateScreenExtents( ) const
3565 auto screenPosition = GetCurrentScreenPosition();
3566 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3567 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3568 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3569 return { position.x, position.y, size.x, size.y };
3572 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3574 bool valueSet = true;
3578 case Dali::Actor::Property::PARENT_ORIGIN:
3580 value = GetCurrentParentOrigin();
3584 case Dali::Actor::Property::PARENT_ORIGIN_X:
3586 value = GetCurrentParentOrigin().x;
3590 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3592 value = GetCurrentParentOrigin().y;
3596 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3598 value = GetCurrentParentOrigin().z;
3602 case Dali::Actor::Property::ANCHOR_POINT:
3604 value = GetCurrentAnchorPoint();
3608 case Dali::Actor::Property::ANCHOR_POINT_X:
3610 value = GetCurrentAnchorPoint().x;
3614 case Dali::Actor::Property::ANCHOR_POINT_Y:
3616 value = GetCurrentAnchorPoint().y;
3620 case Dali::Actor::Property::ANCHOR_POINT_Z:
3622 value = GetCurrentAnchorPoint().z;
3626 case Dali::Actor::Property::SIZE:
3628 value = GetTargetSize();
3632 case Dali::Actor::Property::SIZE_WIDTH:
3634 value = GetTargetSize().width;
3638 case Dali::Actor::Property::SIZE_HEIGHT:
3640 value = GetTargetSize().height;
3644 case Dali::Actor::Property::SIZE_DEPTH:
3646 value = GetTargetSize().depth;
3650 case Dali::Actor::Property::POSITION:
3652 value = GetTargetPosition();
3656 case Dali::Actor::Property::POSITION_X:
3658 value = GetTargetPosition().x;
3662 case Dali::Actor::Property::POSITION_Y:
3664 value = GetTargetPosition().y;
3668 case Dali::Actor::Property::POSITION_Z:
3670 value = GetTargetPosition().z;
3674 case Dali::Actor::Property::ORIENTATION:
3676 value = mTargetOrientation;
3680 case Dali::Actor::Property::SCALE:
3682 value = mTargetScale;
3686 case Dali::Actor::Property::SCALE_X:
3688 value = mTargetScale.x;
3692 case Dali::Actor::Property::SCALE_Y:
3694 value = mTargetScale.y;
3698 case Dali::Actor::Property::SCALE_Z:
3700 value = mTargetScale.z;
3704 case Dali::Actor::Property::VISIBLE:
3710 case Dali::Actor::Property::COLOR:
3712 value = mTargetColor;
3716 case Dali::Actor::Property::COLOR_RED:
3718 value = mTargetColor.r;
3722 case Dali::Actor::Property::COLOR_GREEN:
3724 value = mTargetColor.g;
3728 case Dali::Actor::Property::COLOR_BLUE:
3730 value = mTargetColor.b;
3734 case Dali::Actor::Property::COLOR_ALPHA:
3735 case Dali::DevelActor::Property::OPACITY:
3737 value = mTargetColor.a;
3741 case Dali::Actor::Property::NAME:
3747 case Dali::Actor::Property::SENSITIVE:
3749 value = IsSensitive();
3753 case Dali::Actor::Property::LEAVE_REQUIRED:
3755 value = GetLeaveRequired();
3759 case Dali::Actor::Property::INHERIT_POSITION:
3761 value = IsPositionInherited();
3765 case Dali::Actor::Property::INHERIT_ORIENTATION:
3767 value = IsOrientationInherited();
3771 case Dali::Actor::Property::INHERIT_SCALE:
3773 value = IsScaleInherited();
3777 case Dali::Actor::Property::COLOR_MODE:
3779 value = GetColorMode();
3783 case Dali::Actor::Property::DRAW_MODE:
3785 value = GetDrawMode();
3789 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3791 value = GetSizeModeFactor();
3795 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3797 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3801 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3803 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3807 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3809 value = GetSizeScalePolicy();
3813 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3815 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3819 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3821 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3825 case Dali::Actor::Property::PADDING:
3827 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3828 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3829 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3833 case Dali::Actor::Property::MINIMUM_SIZE:
3835 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3839 case Dali::Actor::Property::MAXIMUM_SIZE:
3841 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3845 case Dali::Actor::Property::CLIPPING_MODE:
3847 value = mClippingMode;
3851 case Dali::DevelActor::Property::SIBLING_ORDER:
3853 value = static_cast<int>( GetSiblingOrder() );
3857 case Dali::DevelActor::Property::SCREEN_POSITION:
3859 value = GetCurrentScreenPosition();
3863 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3865 value = mPositionUsesAnchorPoint;
3869 case Dali::Actor::Property::LAYOUT_DIRECTION:
3871 value = mLayoutDirection;
3875 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3877 value = IsLayoutDirectionInherited();
3883 // Must be a scene-graph only property
3892 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3894 bool valueSet = true;
3898 case Dali::Actor::Property::SIZE:
3900 value = GetCurrentSize();
3904 case Dali::Actor::Property::SIZE_WIDTH:
3906 value = GetCurrentSize().width;
3910 case Dali::Actor::Property::SIZE_HEIGHT:
3912 value = GetCurrentSize().height;
3916 case Dali::Actor::Property::SIZE_DEPTH:
3918 value = GetCurrentSize().depth;
3922 case Dali::Actor::Property::POSITION:
3924 value = GetCurrentPosition();
3928 case Dali::Actor::Property::POSITION_X:
3930 value = GetCurrentPosition().x;
3934 case Dali::Actor::Property::POSITION_Y:
3936 value = GetCurrentPosition().y;
3940 case Dali::Actor::Property::POSITION_Z:
3942 value = GetCurrentPosition().z;
3946 case Dali::Actor::Property::WORLD_POSITION:
3948 value = GetCurrentWorldPosition();
3952 case Dali::Actor::Property::WORLD_POSITION_X:
3954 value = GetCurrentWorldPosition().x;
3958 case Dali::Actor::Property::WORLD_POSITION_Y:
3960 value = GetCurrentWorldPosition().y;
3964 case Dali::Actor::Property::WORLD_POSITION_Z:
3966 value = GetCurrentWorldPosition().z;
3970 case Dali::Actor::Property::ORIENTATION:
3972 value = GetCurrentOrientation();
3976 case Dali::Actor::Property::WORLD_ORIENTATION:
3978 value = GetCurrentWorldOrientation();
3982 case Dali::Actor::Property::SCALE:
3984 value = GetCurrentScale();
3988 case Dali::Actor::Property::SCALE_X:
3990 value = GetCurrentScale().x;
3994 case Dali::Actor::Property::SCALE_Y:
3996 value = GetCurrentScale().y;
4000 case Dali::Actor::Property::SCALE_Z:
4002 value = GetCurrentScale().z;
4006 case Dali::Actor::Property::WORLD_SCALE:
4008 value = GetCurrentWorldScale();
4012 case Dali::Actor::Property::COLOR:
4014 value = GetCurrentColor();
4018 case Dali::Actor::Property::COLOR_RED:
4020 value = GetCurrentColor().r;
4024 case Dali::Actor::Property::COLOR_GREEN:
4026 value = GetCurrentColor().g;
4030 case Dali::Actor::Property::COLOR_BLUE:
4032 value = GetCurrentColor().b;
4036 case Dali::Actor::Property::COLOR_ALPHA:
4037 case Dali::DevelActor::Property::OPACITY:
4039 value = GetCurrentColor().a;
4043 case Dali::Actor::Property::WORLD_COLOR:
4045 value = GetCurrentWorldColor();
4049 case Dali::Actor::Property::WORLD_MATRIX:
4051 value = GetCurrentWorldMatrix();
4055 case Dali::Actor::Property::VISIBLE:
4057 value = IsVisible();
4061 case DevelActor::Property::CULLED:
4063 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4069 // Must be an event-side only property
4078 void Actor::EnsureRelayoutData()
4080 // Assign relayout data.
4081 if( !mRelayoutData )
4083 mRelayoutData = new RelayoutData();
4087 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4089 // Check if actor is dependent on parent
4090 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4092 if( ( dimension & ( 1 << i ) ) )
4094 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4095 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4105 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4107 // Check if actor is dependent on children
4108 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4110 if( ( dimension & ( 1 << i ) ) )
4112 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4113 switch( resizePolicy )
4115 case ResizePolicy::FIT_TO_CHILDREN:
4116 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4132 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4134 return Actor::RelayoutDependentOnChildren( dimension );
4137 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4139 // Check each possible dimension and see if it is dependent on the input one
4140 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4142 if( dimension & ( 1 << i ) )
4144 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4151 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4153 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4155 if( dimension & ( 1 << i ) )
4157 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4162 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4164 // If more than one dimension is requested, just return the first one found
4165 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4167 if( ( dimension & ( 1 << i ) ) )
4169 return mRelayoutData->negotiatedDimensions[ i ];
4173 return 0.0f; // Default
4176 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4178 EnsureRelayoutData();
4180 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4182 if( dimension & ( 1 << i ) )
4184 mRelayoutData->dimensionPadding[ i ] = padding;
4189 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4191 if ( mRelayoutData )
4193 // If more than one dimension is requested, just return the first one found
4194 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4196 if( ( dimension & ( 1 << i ) ) )
4198 return mRelayoutData->dimensionPadding[ i ];
4203 return GetDefaultDimensionPadding();
4206 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4208 EnsureRelayoutData();
4210 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4212 if( dimension & ( 1 << i ) )
4214 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4219 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4221 if ( mRelayoutData )
4223 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4225 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4235 float Actor::GetHeightForWidthBase( float width )
4237 float height = 0.0f;
4239 const Vector3 naturalSize = GetNaturalSize();
4240 if( naturalSize.width > 0.0f )
4242 height = naturalSize.height * width / naturalSize.width;
4244 else // we treat 0 as 1:1 aspect ratio
4252 float Actor::GetWidthForHeightBase( float height )
4256 const Vector3 naturalSize = GetNaturalSize();
4257 if( naturalSize.height > 0.0f )
4259 width = naturalSize.width * height / naturalSize.height;
4261 else // we treat 0 as 1:1 aspect ratio
4269 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4271 // Fill to parent, taking size mode factor into account
4272 switch( child.GetResizePolicy( dimension ) )
4274 case ResizePolicy::FILL_TO_PARENT:
4276 return GetLatestSize( dimension );
4279 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4281 return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4284 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4286 return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4291 return GetLatestSize( dimension );
4296 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4298 // Can be overridden in derived class
4299 return CalculateChildSizeBase( child, dimension );
4302 float Actor::GetHeightForWidth( float width )
4304 // Can be overridden in derived class
4305 return GetHeightForWidthBase( width );
4308 float Actor::GetWidthForHeight( float height )
4310 // Can be overridden in derived class
4311 return GetWidthForHeightBase( height );
4314 float Actor::GetLatestSize( Dimension::Type dimension ) const
4316 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4319 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4321 Vector2 padding = GetPadding( dimension );
4323 return GetLatestSize( dimension ) + padding.x + padding.y;
4326 float Actor::NegotiateFromParent( Dimension::Type dimension )
4328 Actor* parent = GetParent();
4331 Vector2 padding( GetPadding( dimension ) );
4332 Vector2 parentPadding( parent->GetPadding( dimension ) );
4333 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4339 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4341 float maxDimensionPoint = 0.0f;
4343 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4345 ActorPtr child = GetChildAt( i );
4347 if( !child->RelayoutDependentOnParent( dimension ) )
4349 // Calculate the min and max points that the children range across
4350 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4351 float dimensionSize = child->GetRelayoutSize( dimension );
4352 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4356 return maxDimensionPoint;
4359 float Actor::GetSize( Dimension::Type dimension ) const
4361 return GetDimensionValue( mTargetSize, dimension );
4364 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4366 return GetDimensionValue( GetNaturalSize(), dimension );
4369 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4371 switch( GetResizePolicy( dimension ) )
4373 case ResizePolicy::USE_NATURAL_SIZE:
4375 return GetNaturalSize( dimension );
4378 case ResizePolicy::FIXED:
4380 return GetDimensionValue( GetPreferredSize(), dimension );
4383 case ResizePolicy::USE_ASSIGNED_SIZE:
4385 return GetDimensionValue( maximumSize, dimension );
4388 case ResizePolicy::FILL_TO_PARENT:
4389 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4390 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4392 return NegotiateFromParent( dimension );
4395 case ResizePolicy::FIT_TO_CHILDREN:
4397 return NegotiateFromChildren( dimension );
4400 case ResizePolicy::DIMENSION_DEPENDENCY:
4402 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4405 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4407 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4410 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4412 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4424 return 0.0f; // Default
4427 float Actor::ClampDimension( float size, Dimension::Type dimension )
4429 const float minSize = GetMinimumSize( dimension );
4430 const float maxSize = GetMaximumSize( dimension );
4432 return std::max( minSize, std::min( size, maxSize ) );
4435 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4437 // Check if it needs to be negotiated
4438 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4440 // Check that we havn't gotten into an infinite loop
4441 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4442 bool recursionFound = false;
4443 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4445 if( *it == searchActor )
4447 recursionFound = true;
4452 if( !recursionFound )
4454 // Record the path that we have taken
4455 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4457 // Dimension dependency check
4458 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4460 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4462 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4464 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4468 // Parent dependency check
4469 Actor* parent = GetParent();
4470 if( parent && RelayoutDependentOnParent( dimension ) )
4472 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4475 // Children dependency check
4476 if( RelayoutDependentOnChildren( dimension ) )
4478 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4480 ActorPtr child = GetChildAt( i );
4482 // Only relayout child first if it is not dependent on this actor
4483 if( !child->RelayoutDependentOnParent( dimension ) )
4485 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4490 // For deriving classes
4491 OnCalculateRelayoutSize( dimension );
4493 // All dependencies checked, calculate the size and set negotiated flag
4494 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4496 SetNegotiatedDimension( newSize, dimension );
4497 SetLayoutNegotiated( true, dimension );
4499 // For deriving classes
4500 OnLayoutNegotiated( newSize, dimension );
4502 // This actor has been successfully processed, pop it off the recursion stack
4503 recursionStack.pop_back();
4507 // TODO: Break infinite loop
4508 SetLayoutNegotiated( true, dimension );
4513 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4515 // Negotiate all dimensions that require it
4516 ActorDimensionStack recursionStack;
4518 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4520 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4523 NegotiateDimension( dimension, allocatedSize, recursionStack );
4527 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4529 switch( mRelayoutData->sizeSetPolicy )
4531 case SizeScalePolicy::USE_SIZE_SET:
4536 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4538 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4539 const Vector3 naturalSize = GetNaturalSize();
4540 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4542 const float sizeRatio = size.width / size.height;
4543 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4545 if( naturalSizeRatio < sizeRatio )
4547 return Vector2( naturalSizeRatio * size.height, size.height );
4549 else if( naturalSizeRatio > sizeRatio )
4551 return Vector2( size.width, size.width / naturalSizeRatio );
4562 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4564 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4565 const Vector3 naturalSize = GetNaturalSize();
4566 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4568 const float sizeRatio = size.width / size.height;
4569 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4571 if( naturalSizeRatio < sizeRatio )
4573 return Vector2( size.width, size.width / naturalSizeRatio );
4575 else if( naturalSizeRatio > sizeRatio )
4577 return Vector2( naturalSizeRatio * size.height, size.height );
4596 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4598 // Do the set actor size
4599 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4601 // Adjust for size set policy
4602 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4604 // Lock the flag to stop recursive relayouts on set size
4605 mRelayoutData->insideRelayout = true;
4606 SetSize( negotiatedSize );
4607 mRelayoutData->insideRelayout = false;
4609 // Clear flags for all dimensions
4610 SetLayoutDirty( false );
4612 // Give deriving classes a chance to respond
4613 OnRelayout( negotiatedSize, container );
4615 if( !mOnRelayoutSignal.Empty() )
4617 Dali::Actor handle( this );
4618 mOnRelayoutSignal.Emit( handle );
4622 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4624 // Force a size negotiation for actors that has assigned size during relayout
4625 // This is required as otherwise the flags that force a relayout will not
4626 // necessarilly be set. This will occur if the actor has already been laid out.
4627 // The dirty flags are then cleared. Then if the actor is added back into the
4628 // relayout container afterwards, the dirty flags would still be clear...
4629 // causing a relayout to be skipped. Here we force any actors added to the
4630 // container to be relayed out.
4631 DALI_LOG_TIMER_START( NegSizeTimer1 );
4633 if( GetUseAssignedSize(Dimension::WIDTH ) )
4635 SetLayoutNegotiated( false, Dimension::WIDTH );
4637 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4639 SetLayoutNegotiated( false, Dimension::HEIGHT );
4642 // Do the negotiation
4643 NegotiateDimensions( allocatedSize );
4645 // Set the actor size
4646 SetNegotiatedSize( container );
4648 // Negotiate down to children
4649 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4651 ActorPtr child = GetChildAt( i );
4653 // Forces children that have already been laid out to be relayed out
4654 // if they have assigned size during relayout.
4655 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4657 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4658 child->SetLayoutDirty(true, Dimension::WIDTH);
4661 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4663 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4664 child->SetLayoutDirty(true, Dimension::HEIGHT);
4667 // Only relayout if required
4668 if( child->RelayoutRequired() )
4670 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4673 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4676 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4680 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4682 if( dimension & ( 1 << i ) )
4684 mRelayoutData->useAssignedSize[ i ] = use;
4690 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4692 if ( mRelayoutData )
4694 // If more than one dimension is requested, just return the first one found
4695 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4697 if( dimension & ( 1 << i ) )
4699 return mRelayoutData->useAssignedSize[ i ];
4707 void Actor::RelayoutRequest( Dimension::Type dimension )
4709 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4710 if( relayoutController )
4712 Dali::Actor self( this );
4713 relayoutController->RequestRelayout( self, dimension );
4717 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4721 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4725 void Actor::SetPreferredSize( const Vector2& size )
4727 EnsureRelayoutData();
4729 // If valid width or height, then set the resize policy to FIXED
4730 // 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,
4731 // then change to FIXED as well
4733 if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4735 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4738 if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4740 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4743 mRelayoutData->preferredSize = size;
4745 mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4750 Vector2 Actor::GetPreferredSize() const
4752 if ( mRelayoutData )
4754 return Vector2( mRelayoutData->preferredSize );
4757 return GetDefaultPreferredSize();
4760 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4762 EnsureRelayoutData();
4764 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4766 if( dimension & ( 1 << i ) )
4768 mRelayoutData->minimumSize[ i ] = size;
4775 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4777 if ( mRelayoutData )
4779 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4781 if( dimension & ( 1 << i ) )
4783 return mRelayoutData->minimumSize[ i ];
4788 return 0.0f; // Default
4791 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4793 EnsureRelayoutData();
4795 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4797 if( dimension & ( 1 << i ) )
4799 mRelayoutData->maximumSize[ i ] = size;
4806 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4808 if ( mRelayoutData )
4810 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4812 if( dimension & ( 1 << i ) )
4814 return mRelayoutData->maximumSize[ i ];
4819 return FLT_MAX; // Default
4822 Object* Actor::GetParentObject() const
4827 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4829 if( mVisible != visible )
4831 if( sendMessage == SendMessage::TRUE )
4833 // node is being used in a separate thread; queue a message to set the value & base value
4834 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4839 // Emit the signal on this actor and all its children
4840 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4844 void Actor::SetSiblingOrder( uint32_t order )
4848 ActorContainer& siblings = *(mParent->mChildren);
4849 uint32_t currentOrder = GetSiblingOrder();
4851 if( order != currentOrder )
4857 else if( order < siblings.size() -1 )
4859 if( order > currentOrder )
4861 RaiseAbove( *siblings[order] );
4865 LowerBelow( *siblings[order] );
4876 uint32_t Actor::GetSiblingOrder() const
4882 ActorContainer& siblings = *(mParent->mChildren);
4883 for( std::size_t i = 0; i < siblings.size(); ++i )
4885 if( siblings[i] == this )
4887 order = static_cast<uint32_t>( i );
4896 void Actor::RequestRebuildDepthTree()
4902 mScene->RequestRebuildDepthTree();
4911 ActorContainer& siblings = *(mParent->mChildren);
4912 if( siblings.back() != this ) // If not already at end
4914 for( std::size_t i=0; i<siblings.size(); ++i )
4916 if( siblings[i] == this )
4919 ActorPtr next = siblings[i+1];
4920 siblings[i+1] = this;
4927 Dali::Actor handle( this );
4928 mParent->mChildOrderChangedSignal.Emit( handle );
4930 RequestRebuildDepthTree();
4934 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4942 ActorContainer& siblings = *(mParent->mChildren);
4943 if( siblings.front() != this ) // If not already at beginning
4945 for( std::size_t i=1; i<siblings.size(); ++i )
4947 if( siblings[i] == this )
4949 // Swap with previous
4950 ActorPtr previous = siblings[i-1];
4951 siblings[i-1] = this;
4952 siblings[i] = previous;
4958 Dali::Actor handle( this );
4959 mParent->mChildOrderChangedSignal.Emit( handle );
4961 RequestRebuildDepthTree();
4965 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4969 void Actor::RaiseToTop()
4973 ActorContainer& siblings = *(mParent->mChildren);
4974 if( siblings.back() != this ) // If not already at end
4976 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4977 if( iter != siblings.end() )
4979 siblings.erase(iter);
4980 siblings.push_back(ActorPtr(this));
4984 Dali::Actor handle( this );
4985 mParent->mChildOrderChangedSignal.Emit( handle );
4987 RequestRebuildDepthTree();
4991 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4995 void Actor::LowerToBottom()
4999 ActorContainer& siblings = *(mParent->mChildren);
5000 if( siblings.front() != this ) // If not already at bottom,
5002 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5004 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5005 if( iter != siblings.end() )
5007 siblings.erase(iter);
5008 siblings.insert(siblings.begin(), thisPtr);
5012 Dali::Actor handle( this );
5013 mParent->mChildOrderChangedSignal.Emit( handle );
5015 RequestRebuildDepthTree();
5019 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5023 void Actor::RaiseAbove( Internal::Actor& target )
5027 ActorContainer& siblings = *(mParent->mChildren);
5028 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5030 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5032 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5033 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5034 if( thisIter < targetIter )
5036 siblings.erase(thisIter);
5037 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5038 // invalidate thisIter)
5039 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5041 siblings.insert(targetIter, thisPtr);
5044 Dali::Actor handle( this );
5045 mParent->mChildOrderChangedSignal.Emit( handle );
5047 RequestRebuildDepthTree();
5052 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5056 void Actor::LowerBelow( Internal::Actor& target )
5060 ActorContainer& siblings = *(mParent->mChildren);
5061 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5063 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5065 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5066 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5068 if( thisIter > targetIter )
5070 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5071 siblings.insert(targetIter, thisPtr);
5074 Dali::Actor handle( this );
5075 mParent->mChildOrderChangedSignal.Emit( handle );
5077 RequestRebuildDepthTree();
5082 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5086 void Actor::SetScene( Scene& scene )
5091 Scene& Actor::GetScene() const
5096 void Actor::SetInheritLayoutDirection( bool inherit )
5098 if( mInheritLayoutDirection != inherit )
5100 mInheritLayoutDirection = inherit;
5102 if( inherit && mParent )
5104 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5109 bool Actor::IsLayoutDirectionInherited() const
5111 return mInheritLayoutDirection;
5114 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5116 if( actor && ( actor->mInheritLayoutDirection || set ) )
5118 if( actor->mLayoutDirection != direction )
5120 actor->mLayoutDirection = direction;
5121 actor->EmitLayoutDirectionChangedSignal( direction );
5122 actor->RelayoutRequest();
5125 if( actor->GetChildCount() > 0 )
5127 ActorContainer& children = actor->GetChildrenInternal();
5128 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5130 InheritLayoutDirectionRecursively( *iter, direction );
5136 } // namespace Internal