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-event.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( "drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE )
198 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
199 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
200 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
201 DALI_PROPERTY( "sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
202 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
203 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
204 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
205 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
206 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
207 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
208 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
209 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
210 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
211 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY )
212 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION )
213 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT )
214 DALI_PROPERTY( "culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED )
215 DALI_PROPERTY( "id", INTEGER, false, false, false, Dali::Actor::Property::ID )
216 DALI_PROPERTY( "hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH )
217 DALI_PROPERTY( "isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT )
218 DALI_PROPERTY( "isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER )
219 DALI_PROPERTY( "connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE )
220 DALI_PROPERTY( "keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE )
221 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
222 DALI_PROPERTY( "updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT )
223 DALI_PROPERTY( "captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START )
224 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
228 const char* const SIGNAL_HOVERED = "hovered";
229 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
230 const char* const SIGNAL_ON_SCENE = "onScene";
231 const char* const SIGNAL_OFF_SCENE = "offScene";
232 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
233 const char* const SIGNAL_TOUCHED = "touched";
234 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
235 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
236 const char* const SIGNAL_CHILD_ADDED = "childAdded";
237 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
241 const char* const ACTION_SHOW = "show";
242 const char* const ACTION_HIDE = "hide";
244 BaseHandle CreateActor()
246 return Dali::Actor::New();
249 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
251 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector4( mType, SIGNAL_ON_SCENE, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_SCENE, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
256 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
257 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
258 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
259 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
260 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
262 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
263 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
268 const Vector3& value;
271 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
276 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
281 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
283 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
284 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
285 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
286 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
287 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
288 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
290 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
293 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
295 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
299 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
300 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
304 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
306 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
307 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
310 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
312 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
315 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
317 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
318 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
319 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
320 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
322 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
324 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
326 uint32_t sizeIgnored = 0;
327 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
329 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
336 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
338 // Values are the same so just use the same table as anchor-point
339 return GetAnchorPointConstant( value, parentOrigin );
343 * @brief Extract a given dimension from a Vector2
345 * @param[in] values The values to extract from
346 * @param[in] dimension The dimension to extract
347 * @return Return the value for the dimension
349 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
353 case Dimension::WIDTH:
357 case Dimension::HEIGHT:
359 return values.height;
370 * @brief Extract a given dimension from a Vector3
372 * @param[in] values The values to extract from
373 * @param[in] dimension The dimension to extract
374 * @return Return the value for the dimension
376 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
378 return GetDimensionValue( values.GetVectorXY(), dimension );
382 * @brief Recursively emits the visibility-changed-signal on the actor tree.
383 * @param[in] actor The actor to emit the signal on
384 * @param[in] visible The new visibility of the actor
385 * @param[in] type Whether the actor's visible property has changed or a parent's
387 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
391 actor->EmitVisibilityChangedSignal( visible, type );
393 if( actor->GetChildCount() > 0 )
395 ActorContainer& children = actor->GetChildrenInternal();
396 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
398 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
404 } // unnamed namespace
406 ActorPtr Actor::New()
408 // pass a reference to actor, actor does not own its node
409 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
411 // Second-phase construction
417 const SceneGraph::Node* Actor::CreateNode()
419 // create node. Nodes are owned by the update manager
420 SceneGraph::Node* node = SceneGraph::Node::New();
421 OwnerPointer< SceneGraph::Node > transferOwnership( node );
422 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
424 DALI_ASSERT_ALWAYS( tls && "ThreadLocalStorage is null" );
426 AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
431 const std::string& Actor::GetName() const
436 void Actor::SetName( const std::string& name )
440 // ATTENTION: string for debug purposes is not thread safe.
441 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
444 uint32_t Actor::GetId() const
446 return GetNode().GetId();
449 bool Actor::OnScene() const
454 Dali::Layer Actor::GetLayer()
458 // Short-circuit for Layer derived actors
461 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
464 // Find the immediate Layer parent
465 for( Actor* parent = mParent; !layer && parent != nullptr; parent = parent->GetParent() )
467 if( parent->IsLayer() )
469 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
476 void Actor::Add( Actor& child )
478 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
479 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
483 mChildren = new ActorContainer;
486 Actor* const oldParent( child.mParent );
488 // child might already be ours
489 if( this != oldParent )
491 // if we already have parent, unparent us first
494 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
496 // Old parent may need to readjust to missing child
497 if( oldParent->RelayoutDependentOnChildren() )
499 oldParent->RelayoutRequest();
503 // Guard against Add() during previous OnChildRemove callback
506 // Do this first, since user callbacks from within SetParent() may need to remove child
507 mChildren->push_back( ActorPtr( &child ) );
509 // SetParent asserts that child can be added
510 child.SetParent( this );
512 // Notification for derived classes
514 EmitChildAddedSignal( child );
516 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
518 // Only put in a relayout request if there is a suitable dependency
519 if( RelayoutDependentOnChildren() )
527 void Actor::Remove( Actor& child )
529 if( (this == &child) || (!mChildren) )
531 // no children or removing itself
537 // Find the child in mChildren, and unparent it
538 ActorIter end = mChildren->end();
539 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
541 ActorPtr actor = (*iter);
543 if( actor.Get() == &child )
545 // Keep handle for OnChildRemove notification
548 // Do this first, since user callbacks from within SetParent() may need to add the child
549 mChildren->erase( iter );
551 DALI_ASSERT_DEBUG( actor->GetParent() == this );
552 actor->SetParent( nullptr );
560 // Only put in a relayout request if there is a suitable dependency
561 if( RelayoutDependentOnChildren() )
567 // Notification for derived classes
568 OnChildRemove( child );
569 EmitChildRemovedSignal( child );
572 void Actor::Unparent()
576 // Remove this actor from the parent. The remove will put a relayout request in for
577 // the parent if required
578 mParent->Remove( *this );
579 // mParent is now NULL!
583 uint32_t Actor::GetChildCount() const
585 return ( nullptr != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
588 ActorPtr Actor::GetChildAt( uint32_t index ) const
590 DALI_ASSERT_ALWAYS( index < GetChildCount() );
592 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
595 ActorPtr Actor::FindChildByName( const std::string& actorName )
597 ActorPtr child = nullptr;
598 if( actorName == mName )
604 ActorIter end = mChildren->end();
605 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
607 child = (*iter)->FindChildByName( actorName );
618 ActorPtr Actor::FindChildById( const uint32_t id )
620 ActorPtr child = nullptr;
627 ActorIter end = mChildren->end();
628 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
630 child = (*iter)->FindChildById( id );
641 void Actor::SetParentOrigin( const Vector3& origin )
643 // node is being used in a separate thread; queue a message to set the value & base value
644 SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
646 // Cache for event-thread access
649 // not allocated, check if different from default
650 if( ParentOrigin::DEFAULT != origin )
652 mParentOrigin = new Vector3( origin );
657 // check if different from current costs more than just set
658 *mParentOrigin = origin;
662 void Actor::SetParentOriginX( float x )
664 const Vector3& current = GetCurrentParentOrigin();
666 SetParentOrigin( Vector3( x, current.y, current.z ) );
669 void Actor::SetParentOriginY( float y )
671 const Vector3& current = GetCurrentParentOrigin();
673 SetParentOrigin( Vector3( current.x, y, current.z ) );
676 void Actor::SetParentOriginZ( float z )
678 const Vector3& current = GetCurrentParentOrigin();
680 SetParentOrigin( Vector3( current.x, current.y, z ) );
683 const Vector3& Actor::GetCurrentParentOrigin() const
685 // Cached for event-thread access
686 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
689 void Actor::SetAnchorPoint( const Vector3& anchor )
691 // node is being used in a separate thread; queue a message to set the value & base value
692 SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
694 // Cache for event-thread access
697 // not allocated, check if different from default
698 if( AnchorPoint::DEFAULT != anchor )
700 mAnchorPoint = new Vector3( anchor );
705 // check if different from current costs more than just set
706 *mAnchorPoint = anchor;
710 void Actor::SetAnchorPointX( float x )
712 const Vector3& current = GetCurrentAnchorPoint();
714 SetAnchorPoint( Vector3( x, current.y, current.z ) );
717 void Actor::SetAnchorPointY( float y )
719 const Vector3& current = GetCurrentAnchorPoint();
721 SetAnchorPoint( Vector3( current.x, y, current.z ) );
724 void Actor::SetAnchorPointZ( float z )
726 const Vector3& current = GetCurrentAnchorPoint();
728 SetAnchorPoint( Vector3( current.x, current.y, z ) );
731 const Vector3& Actor::GetCurrentAnchorPoint() const
733 // Cached for event-thread access
734 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
737 void Actor::SetPosition( float x, float y )
739 SetPosition( Vector3( x, y, 0.0f ) );
742 void Actor::SetPosition( float x, float y, float z )
744 SetPosition( Vector3( x, y, z ) );
747 void Actor::SetPosition( const Vector3& position )
749 mTargetPosition = position;
751 // node is being used in a separate thread; queue a message to set the value & base value
752 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
755 void Actor::SetX( float x )
757 mTargetPosition.x = x;
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>::BakeX, x );
763 void Actor::SetY( float y )
765 mTargetPosition.y = y;
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>::BakeY, y );
771 void Actor::SetZ( float z )
773 mTargetPosition.z = z;
775 // node is being used in a separate thread; queue a message to set the value & base value
776 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
779 void Actor::TranslateBy( const Vector3& distance )
781 mTargetPosition += distance;
783 // node is being used in a separate thread; queue a message to set the value & base value
784 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
787 const Vector3& Actor::GetCurrentPosition() const
789 // node is being used in a separate thread; copy the value from the previous update
790 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
793 const Vector3& Actor::GetTargetPosition() const
795 return mTargetPosition;
798 const Vector3& Actor::GetCurrentWorldPosition() const
800 // node is being used in a separate thread; copy the value from the previous update
801 return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
804 const Vector2 Actor::GetCurrentScreenPosition() const
806 if( mScene && OnScene() )
808 Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
809 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
810 worldPosition -= cameraPosition;
812 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
813 Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
814 Vector3 halfActorSize( actorSize * 0.5f );
815 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
817 return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
818 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
821 return Vector2::ZERO;
824 void Actor::SetInheritPosition( bool inherit )
826 if( mInheritPosition != inherit )
828 // non animatable so keep local copy
829 mInheritPosition = inherit;
830 SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
834 bool Actor::IsPositionInherited() const
836 return mInheritPosition;
839 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
841 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
842 normalizedAxis.Normalize();
844 Quaternion orientation( angle, normalizedAxis );
846 SetOrientation( orientation );
849 void Actor::SetOrientation( const Quaternion& orientation )
851 mTargetOrientation = orientation;
853 // node is being used in a separate thread; queue a message to set the value & base value
854 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
857 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
859 RotateBy( Quaternion(angle, axis) );
862 void Actor::RotateBy( const Quaternion& relativeRotation )
864 mTargetOrientation *= Quaternion( relativeRotation );
866 // node is being used in a separate thread; queue a message to set the value & base value
867 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
870 const Quaternion& Actor::GetCurrentOrientation() const
872 // node is being used in a separate thread; copy the value from the previous update
873 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
876 const Quaternion& Actor::GetCurrentWorldOrientation() const
878 // node is being used in a separate thread; copy the value from the previous update
879 return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
882 void Actor::SetScale( float scale )
884 SetScale( Vector3( scale, scale, scale ) );
887 void Actor::SetScale( float x, float y, float z )
889 SetScale( Vector3( x, y, z ) );
892 void Actor::SetScale( const Vector3& scale )
894 mTargetScale = scale;
896 // node is being used in a separate thread; queue a message to set the value & base value
897 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
900 void Actor::SetScaleX( float x )
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>::BakeX, x );
908 void Actor::SetScaleY( float y )
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>::BakeY, y );
916 void Actor::SetScaleZ( float z )
920 // node is being used in a separate thread; queue a message to set the value & base value
921 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
924 void Actor::ScaleBy(const Vector3& relativeScale)
926 mTargetScale *= relativeScale;
928 // node is being used in a separate thread; queue a message to set the value & base value
929 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
932 const Vector3& Actor::GetCurrentScale() const
934 // node is being used in a separate thread; copy the value from the previous update
935 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
938 const Vector3& Actor::GetCurrentWorldScale() const
940 // node is being used in a separate thread; copy the value from the previous update
941 return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
944 void Actor::SetInheritScale( bool inherit )
946 if( mInheritScale != inherit )
948 // non animatable so keep local copy
949 mInheritScale = inherit;
950 // node is being used in a separate thread; queue a message to set the value
951 SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
955 bool Actor::IsScaleInherited() const
957 return mInheritScale;
960 Matrix Actor::GetCurrentWorldMatrix() const
962 return GetNode().GetWorldMatrix(0);
965 void Actor::SetVisible( bool visible )
967 SetVisibleInternal( visible, SendMessage::TRUE );
970 bool Actor::IsVisible() const
972 // node is being used in a separate thread; copy the value from the previous update
973 return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
976 void Actor::SetOpacity( float opacity )
978 mTargetColor.a = opacity;
980 // node is being used in a separate thread; queue a message to set the value & base value
981 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
984 float Actor::GetCurrentOpacity() const
986 // node is being used in a separate thread; copy the value from the previous update
987 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
990 ClippingMode::Type Actor::GetClippingMode() const
992 return mClippingMode;
995 uint32_t Actor::GetSortingDepth()
1000 const Vector4& Actor::GetCurrentWorldColor() const
1002 return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1005 void Actor::SetColor( const Vector4& color )
1007 mTargetColor = color;
1009 // node is being used in a separate thread; queue a message to set the value & base value
1010 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
1013 void Actor::SetColorRed( float red )
1015 mTargetColor.r = red;
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>::BakeX, red );
1021 void Actor::SetColorGreen( float green )
1023 mTargetColor.g = green;
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>::BakeY, green );
1029 void Actor::SetColorBlue( float blue )
1031 mTargetColor.b = blue;
1033 // node is being used in a separate thread; queue a message to set the value & base value
1034 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1037 const Vector4& Actor::GetCurrentColor() const
1039 // node is being used in a separate thread; copy the value from the previous update
1040 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
1043 void Actor::SetInheritOrientation( bool inherit )
1045 if( mInheritOrientation != inherit )
1047 // non animatable so keep local copy
1048 mInheritOrientation = inherit;
1049 // node is being used in a separate thread; queue a message to set the value
1050 SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
1054 bool Actor::IsOrientationInherited() const
1056 return mInheritOrientation;
1059 void Actor::SetSizeModeFactor( const Vector3& factor )
1061 EnsureRelayoutData();
1063 mRelayoutData->sizeModeFactor = factor;
1066 const Vector3& Actor::GetSizeModeFactor() const
1068 if ( mRelayoutData )
1070 return mRelayoutData->sizeModeFactor;
1073 return GetDefaultSizeModeFactor();
1076 void Actor::SetColorMode( ColorMode colorMode )
1078 // non animatable so keep local copy
1079 mColorMode = colorMode;
1080 // node is being used in a separate thread; queue a message to set the value
1081 SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
1084 ColorMode Actor::GetColorMode() const
1086 // we have cached copy
1090 void Actor::SetSize( float width, float height )
1092 SetSize( Vector2( width, height ) );
1095 void Actor::SetSize( float width, float height, float depth )
1097 SetSize( Vector3( width, height, depth ) );
1100 void Actor::SetSize( const Vector2& size )
1102 SetSize( Vector3( size.width, size.height, 0.f ) );
1105 void Actor::SetSizeInternal( const Vector2& size )
1107 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1110 void Actor::SetSize( const Vector3& size )
1112 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1114 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1115 SetPreferredSize( size.GetVectorXY() );
1119 SetSizeInternal( size );
1123 void Actor::SetSizeInternal( const Vector3& size )
1125 // dont allow recursive loop
1126 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1127 // 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
1128 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1129 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1130 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1134 // node is being used in a separate thread; queue a message to set the value & base value
1135 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1137 // Notification for derived classes
1138 mInsideOnSizeSet = true;
1139 OnSizeSet( mTargetSize );
1140 mInsideOnSizeSet = false;
1142 // Raise a relayout request if the flag is not locked
1143 if( mRelayoutData && !mRelayoutData->insideRelayout )
1150 void Actor::SetWidth( float width )
1152 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1154 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1155 mRelayoutData->preferredSize.width = width;
1159 mTargetSize.width = width;
1161 // node is being used in a separate thread; queue a message to set the value & base value
1162 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1165 mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
1170 void Actor::SetHeight( float height )
1172 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1174 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1175 mRelayoutData->preferredSize.height = height;
1179 mTargetSize.height = height;
1181 // node is being used in a separate thread; queue a message to set the value & base value
1182 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1185 mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
1190 void Actor::SetDepth( float depth )
1192 mTargetSize.depth = depth;
1194 mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
1196 // node is being used in a separate thread; queue a message to set the value & base value
1197 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1200 Vector3 Actor::GetTargetSize() const
1202 Vector3 size = mTargetSize;
1204 if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH )
1206 // Should return animated size if size is animated
1207 size.width = mAnimatedSize.width;
1211 // Should return preferred size if size is fixed as set by SetSize
1212 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1214 size.width = GetPreferredSize().width;
1218 if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT )
1220 size.height = mAnimatedSize.height;
1224 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1226 size.height = GetPreferredSize().height;
1230 if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH )
1232 size.depth = mAnimatedSize.depth;
1238 const Vector3& Actor::GetCurrentSize() const
1240 // node is being used in a separate thread; copy the value from the previous update
1241 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1244 Vector3 Actor::GetNaturalSize() const
1246 // It is up to deriving classes to return the appropriate natural size
1247 return Vector3( 0.0f, 0.0f, 0.0f );
1250 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1252 EnsureRelayoutData();
1254 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1255 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1257 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1259 if( dimension & ( 1 << i ) )
1261 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1263 mRelayoutData->useAssignedSize[ i ] = true;
1267 mRelayoutData->resizePolicies[ i ] = policy;
1268 mRelayoutData->useAssignedSize[ i ] = false;
1273 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1275 if( dimension & Dimension::WIDTH )
1277 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1280 if( dimension & Dimension::HEIGHT )
1282 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1286 // If calling SetResizePolicy, assume we want relayout enabled
1287 SetRelayoutEnabled( true );
1289 // If the resize policy is set to be FIXED, the preferred size
1290 // should be overrided by the target size. Otherwise the target
1291 // size should be overrided by the preferred size.
1293 if( dimension & Dimension::WIDTH )
1295 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1297 mRelayoutData->preferredSize.width = mTargetSize.width;
1299 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1301 mTargetSize.width = mRelayoutData->preferredSize.width;
1305 if( dimension & Dimension::HEIGHT )
1307 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1309 mRelayoutData->preferredSize.height = mTargetSize.height;
1311 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1313 mTargetSize.height = mRelayoutData->preferredSize.height;
1317 OnSetResizePolicy( policy, dimension );
1319 // Trigger relayout on this control
1323 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1325 if ( mRelayoutData )
1327 // If more than one dimension is requested, just return the first one found
1328 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1330 if( ( dimension & ( 1 << i ) ) )
1332 if( mRelayoutData->useAssignedSize[ i ] )
1334 return ResizePolicy::USE_ASSIGNED_SIZE;
1338 return mRelayoutData->resizePolicies[ i ];
1344 return ResizePolicy::DEFAULT;
1347 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1349 EnsureRelayoutData();
1351 mRelayoutData->sizeSetPolicy = policy;
1353 // Trigger relayout on this control
1357 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1359 if ( mRelayoutData )
1361 return mRelayoutData->sizeSetPolicy;
1364 return DEFAULT_SIZE_SCALE_POLICY;
1367 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1369 EnsureRelayoutData();
1371 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1373 if( dimension & ( 1 << i ) )
1375 mRelayoutData->dimensionDependencies[ i ] = dependency;
1380 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1382 if ( mRelayoutData )
1384 // If more than one dimension is requested, just return the first one found
1385 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1387 if( ( dimension & ( 1 << i ) ) )
1389 return mRelayoutData->dimensionDependencies[ i ];
1394 return Dimension::ALL_DIMENSIONS; // Default
1397 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1399 // If relayout data has not been allocated yet and the client is requesting
1400 // to disable it, do nothing
1401 if( mRelayoutData || relayoutEnabled )
1403 EnsureRelayoutData();
1405 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1407 mRelayoutData->relayoutEnabled = relayoutEnabled;
1411 bool Actor::IsRelayoutEnabled() const
1413 // Assume that if relayout data has not been allocated yet then
1414 // relayout is disabled
1415 return mRelayoutData && mRelayoutData->relayoutEnabled;
1418 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1420 EnsureRelayoutData();
1422 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1424 if( dimension & ( 1 << i ) )
1426 mRelayoutData->dimensionDirty[ i ] = dirty;
1431 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1433 if ( mRelayoutData )
1435 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1437 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1447 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1449 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1452 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1454 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1457 uint32_t Actor::AddRenderer( Renderer& renderer )
1461 mRenderers = new RendererContainer;
1464 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1465 RendererPtr rendererPtr = RendererPtr( &renderer );
1466 mRenderers->push_back( rendererPtr );
1467 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1471 uint32_t Actor::GetRendererCount() const
1473 uint32_t rendererCount(0);
1476 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1479 return rendererCount;
1482 RendererPtr Actor::GetRendererAt( uint32_t index )
1484 RendererPtr renderer;
1485 if( index < GetRendererCount() )
1487 renderer = ( *mRenderers )[ index ];
1493 void Actor::RemoveRenderer( Renderer& renderer )
1497 RendererIter end = mRenderers->end();
1498 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1500 if( (*iter).Get() == &renderer )
1502 mRenderers->erase( iter );
1503 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1510 void Actor::RemoveRenderer( uint32_t index )
1512 if( index < GetRendererCount() )
1514 RendererPtr renderer = ( *mRenderers )[ index ];
1515 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1516 mRenderers->erase( mRenderers->begin()+index );
1520 bool Actor::IsOverlay() const
1522 return ( DrawMode::OVERLAY_2D == mDrawMode );
1525 void Actor::SetDrawMode( DrawMode::Type drawMode )
1527 // this flag is not animatable so keep the value
1528 mDrawMode = drawMode;
1530 // node is being used in a separate thread; queue a message to set the value
1531 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1534 DrawMode::Type Actor::GetDrawMode() const
1539 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1541 // only valid when on-stage
1542 if( mScene && OnScene() )
1544 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1546 Vector2 converted( screenX, screenY );
1548 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1549 uint32_t taskCount = taskList.GetTaskCount();
1550 for( uint32_t i = taskCount; i > 0; --i )
1552 RenderTaskPtr task = taskList.GetTask( i - 1 );
1553 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1555 // found a task where this conversion was ok so return
1563 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1565 bool retval = false;
1566 // only valid when on-stage
1569 CameraActor* camera = renderTask.GetCameraActor();
1573 renderTask.GetViewport( viewport );
1575 // need to translate coordinates to render tasks coordinate space
1576 Vector2 converted( screenX, screenY );
1577 if( renderTask.TranslateCoordinates( converted ) )
1579 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1586 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1588 // Early-out if not on stage
1594 // Get the ModelView matrix
1596 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1598 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1599 Matrix invertedMvp( false/*don't init*/);
1600 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1601 bool success = invertedMvp.Invert();
1603 // Convert to GL coordinates
1604 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1609 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1616 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1622 if( XyPlaneIntersect( nearPos, farPos, local ) )
1624 Vector3 size = GetCurrentSize();
1625 localX = local.x + size.x * 0.5f;
1626 localY = local.y + size.y * 0.5f;
1637 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1640 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1642 Mathematical Formulation
1644 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1646 ( p - c ) dot ( p - c ) = r^2
1648 Given a ray with a point of origin 'o', and a direction vector 'd':
1650 ray(t) = o + td, t >= 0
1652 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1654 (o + td - c ) dot ( o + td - c ) = r^2
1656 To solve for t we first expand the above into a more recognisable quadratic equation form
1658 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1667 B = 2( o - c ) dot d
1668 C = ( o - c ) dot ( o - c ) - r^2
1670 which can be solved using a standard quadratic formula.
1672 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1674 Practical Simplification
1676 In a renderer, we often differentiate between world space and object space. In the object space
1677 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1678 into object space, the mathematical solution presented above can be simplified significantly.
1680 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1684 and we can find the t at which the (transformed) ray intersects the sphere by
1686 ( o + td ) dot ( o + td ) = r^2
1688 According to the reasoning above, we expand the above quadratic equation into the general form
1692 which now has coefficients:
1699 // Early-out if not on stage
1705 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1707 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1708 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1709 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1711 // Compute the radius is not needed, square radius it's enough.
1712 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1714 // Scale the sphere.
1715 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1717 const float width = size.width * scale.width;
1718 const float height = size.height * scale.height;
1720 float squareSphereRadius = 0.5f * ( width * width + height * height );
1722 float a = rayDir.Dot( rayDir ); // a
1723 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1724 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1726 return ( b2 * b2 - a * c ) >= 0.f;
1729 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1735 // Transforms the ray to the local reference system.
1736 // Calculate the inverse of Model matrix
1737 Matrix invModelMatrix( false/*don't init*/);
1739 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1740 invModelMatrix = GetNode().GetWorldMatrix(0);
1741 invModelMatrix.Invert();
1743 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1744 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1746 // Test with the actor's XY plane (Normal = 0 0 1 1).
1748 float a = -rayOriginLocal.z;
1749 float b = rayDirLocal.z;
1751 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1753 // Ray travels distance * rayDirLocal to intersect with plane.
1756 const Vector3& size = GetNode().GetSize( bufferIndex );
1758 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1759 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1761 // Test with the actor's geometry.
1762 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1769 void Actor::SetLeaveRequired( bool required )
1771 mLeaveRequired = required;
1774 bool Actor::GetLeaveRequired() const
1776 return mLeaveRequired;
1779 void Actor::SetKeyboardFocusable( bool focusable )
1781 mKeyboardFocusable = focusable;
1784 bool Actor::IsKeyboardFocusable() const
1786 return mKeyboardFocusable;
1789 bool Actor::GetTouchRequired() const
1791 return !mTouchedSignal.Empty();
1794 bool Actor::GetHoverRequired() const
1796 return !mHoveredSignal.Empty();
1799 bool Actor::GetWheelEventRequired() const
1801 return !mWheelEventSignal.Empty();
1804 bool Actor::IsHittable() const
1806 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1809 ActorGestureData& Actor::GetGestureData()
1811 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1812 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1813 if( nullptr == mGestureData )
1815 mGestureData = new ActorGestureData;
1817 return *mGestureData;
1820 bool Actor::IsGestureRequired( GestureType::Value type ) const
1822 return mGestureData && mGestureData->IsGestureRequired( type );
1825 bool Actor::EmitTouchEventSignal( const Dali::TouchEvent& touch )
1827 bool consumed = false;
1829 if( !mTouchedSignal.Empty() )
1831 Dali::Actor handle( this );
1832 consumed = mTouchedSignal.Emit( handle, touch );
1838 bool Actor::EmitHoverEventSignal( const Dali::HoverEvent& event )
1840 bool consumed = false;
1842 if( !mHoveredSignal.Empty() )
1844 Dali::Actor handle( this );
1845 consumed = mHoveredSignal.Emit( handle, event );
1851 bool Actor::EmitWheelEventSignal( const Dali::WheelEvent& event )
1853 bool consumed = false;
1855 if( !mWheelEventSignal.Empty() )
1857 Dali::Actor handle( this );
1858 consumed = mWheelEventSignal.Emit( handle, event );
1864 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1866 if( ! mVisibilityChangedSignal.Empty() )
1868 Dali::Actor handle( this );
1869 mVisibilityChangedSignal.Emit( handle, visible, type );
1873 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1875 if( ! mLayoutDirectionChangedSignal.Empty() )
1877 Dali::Actor handle( this );
1878 mLayoutDirectionChangedSignal.Emit( handle, type );
1882 void Actor::EmitChildAddedSignal( Actor& child )
1884 if( ! mChildAddedSignal.Empty() )
1886 Dali::Actor handle( &child );
1887 mChildAddedSignal.Emit( handle );
1891 void Actor::EmitChildRemovedSignal( Actor& child )
1893 if( ! mChildRemovedSignal.Empty() )
1895 Dali::Actor handle( &child );
1896 mChildRemovedSignal.Emit( handle );
1900 Dali::Actor::TouchEventSignalType& Actor::TouchedSignal()
1902 return mTouchedSignal;
1905 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1907 return mHoveredSignal;
1910 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1912 return mWheelEventSignal;
1915 Dali::Actor::OnSceneSignalType& Actor::OnSceneSignal()
1917 return mOnSceneSignal;
1920 Dali::Actor::OffSceneSignalType& Actor::OffSceneSignal()
1922 return mOffSceneSignal;
1925 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1927 return mOnRelayoutSignal;
1930 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1932 return mVisibilityChangedSignal;
1935 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1937 return mLayoutDirectionChangedSignal;
1940 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1942 return mChildAddedSignal;
1945 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1947 return mChildRemovedSignal;
1950 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1952 return mChildOrderChangedSignal;
1955 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1957 bool connected( true );
1958 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1960 if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1962 actor->HoveredSignal().Connect( tracker, functor );
1964 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1966 actor->WheelEventSignal().Connect( tracker, functor );
1968 else if( 0 == signalName.compare( SIGNAL_ON_SCENE ) )
1970 actor->OnSceneSignal().Connect( tracker, functor );
1972 else if( 0 == signalName.compare( SIGNAL_OFF_SCENE ) )
1974 actor->OffSceneSignal().Connect( tracker, functor );
1976 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1978 actor->OnRelayoutSignal().Connect( tracker, functor );
1980 else if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1982 actor->TouchedSignal().Connect( tracker, functor );
1984 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
1986 actor->VisibilityChangedSignal().Connect( tracker, functor );
1988 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
1990 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
1992 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
1994 actor->ChildAddedSignal().Connect( tracker, functor );
1996 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
1998 actor->ChildRemovedSignal().Connect( tracker, functor );
2002 // signalName does not match any signal
2009 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2013 mChildren( nullptr ),
2014 mRenderers( nullptr ),
2015 mParentOrigin( nullptr ),
2016 mAnchorPoint( nullptr ),
2017 mRelayoutData( nullptr ),
2018 mGestureData( nullptr ),
2021 mWheelEventSignal(),
2024 mOnRelayoutSignal(),
2025 mVisibilityChangedSignal(),
2026 mLayoutDirectionChangedSignal(),
2027 mChildAddedSignal(),
2028 mChildRemovedSignal(),
2029 mChildOrderChangedSignal(),
2030 mTargetOrientation( Quaternion::IDENTITY ),
2031 mTargetColor( Color::WHITE ),
2032 mTargetSize( Vector3::ZERO ),
2033 mTargetPosition( Vector3::ZERO ),
2034 mTargetScale( Vector3::ONE ),
2035 mAnimatedSize( Vector3::ZERO ),
2039 mUseAnimatedSize( AnimatedSizeFlag::CLEAR ),
2040 mIsRoot( ROOT_LAYER == derivedType ),
2041 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2042 mIsOnScene( false ),
2044 mLeaveRequired( false ),
2045 mKeyboardFocusable( false ),
2046 mOnSceneSignalled( false ),
2047 mInsideOnSizeSet( false ),
2048 mInheritPosition( true ),
2049 mInheritOrientation( true ),
2050 mInheritScale( true ),
2051 mPositionUsesAnchorPoint( true ),
2053 mInheritLayoutDirection( true ),
2054 mCaptureAllTouchAfterStart( false ),
2055 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2056 mDrawMode( DrawMode::NORMAL ),
2057 mColorMode( Node::DEFAULT_COLOR_MODE ),
2058 mClippingMode( ClippingMode::DISABLED )
2062 void Actor::Initialize()
2066 GetEventThreadServices().RegisterObject( this );
2071 // Remove mParent pointers from children even if we're destroying core,
2072 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2075 ActorConstIter endIter = mChildren->end();
2076 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2078 (*iter)->SetParent( nullptr );
2084 // Guard to allow handle destruction after Core has been destroyed
2085 if( EventThreadServices::IsCoreRunning() )
2087 // Root layer will destroy its node in its own destructor
2090 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2092 GetEventThreadServices().UnregisterObject( this );
2096 // Cleanup optional gesture data
2097 delete mGestureData;
2099 // Cleanup optional parent origin and anchor
2100 delete mParentOrigin;
2101 delete mAnchorPoint;
2103 // Delete optional relayout data
2104 delete mRelayoutData;
2107 void Actor::ConnectToScene( uint32_t parentDepth )
2109 // This container is used instead of walking the Actor hierarchy.
2110 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
2111 ActorContainer connectionList;
2115 mScene->RequestRebuildDepthTree();
2118 // This stage is atomic i.e. not interrupted by user callbacks.
2119 RecursiveConnectToScene( connectionList, parentDepth + 1 );
2121 // Notify applications about the newly connected actors.
2122 const ActorIter endIter = connectionList.end();
2123 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2125 (*iter)->NotifyStageConnection();
2131 void Actor::RecursiveConnectToScene( ActorContainer& connectionList, uint32_t depth )
2133 DALI_ASSERT_ALWAYS( !OnScene() );
2136 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2138 ConnectToSceneGraph();
2140 // Notification for internal derived classes
2141 OnSceneConnectionInternal();
2143 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2144 connectionList.push_back( ActorPtr( this ) );
2146 // Recursively connect children
2149 ActorConstIter endIter = mChildren->end();
2150 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2152 (*iter)->SetScene( *mScene );
2153 (*iter)->RecursiveConnectToScene( connectionList, depth + 1 );
2159 * This method is called when the Actor is connected to the Stage.
2160 * The parent must have added its Node to the scene-graph.
2161 * The child must connect its Node to the parent's Node.
2162 * This is recursive; the child calls ConnectToScene() for its children.
2164 void Actor::ConnectToSceneGraph()
2166 DALI_ASSERT_DEBUG( mParent != NULL);
2168 // Reparent Node in next Update
2169 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2171 // Request relayout on all actors that are added to the scenegraph
2174 // Notification for Object::Observers
2178 void Actor::NotifyStageConnection()
2180 // Actors can be removed (in a callback), before the on-stage stage is reported.
2181 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
2182 if( OnScene() && !mOnSceneSignalled )
2184 // Notification for external (CustomActor) derived classes
2185 OnSceneConnectionExternal( mDepth );
2187 if( !mOnSceneSignal.Empty() )
2189 Dali::Actor handle( this );
2190 mOnSceneSignal.Emit( handle );
2193 // Guard against Remove during callbacks
2196 mOnSceneSignalled = true; // signal required next time Actor is removed
2201 void Actor::DisconnectFromStage()
2203 // This container is used instead of walking the Actor hierachy.
2204 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
2205 ActorContainer disconnectionList;
2209 mScene->RequestRebuildDepthTree();
2212 // This stage is atomic i.e. not interrupted by user callbacks
2213 RecursiveDisconnectFromStage( disconnectionList );
2215 // Notify applications about the newly disconnected actors.
2216 const ActorIter endIter = disconnectionList.end();
2217 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2219 (*iter)->NotifyStageDisconnection();
2223 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2225 // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
2228 // Recursively disconnect children
2231 ActorConstIter endIter = mChildren->end();
2232 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2234 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2238 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2239 disconnectionList.push_back( ActorPtr( this ) );
2241 // Notification for internal derived classes
2242 OnSceneDisconnectionInternal();
2244 DisconnectFromSceneGraph();
2248 * This method is called by an actor or its parent, before a node removal message is sent.
2249 * This is recursive; the child calls DisconnectFromStage() for its children.
2251 void Actor::DisconnectFromSceneGraph()
2253 // Notification for Object::Observers
2254 OnSceneObjectRemove();
2257 void Actor::NotifyStageDisconnection()
2259 // Actors can be added (in a callback), before the off-stage state is reported.
2260 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
2261 // only do this step if there is a stage, i.e. Core is not being shut down
2262 if ( EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled )
2264 // Notification for external (CustomeActor) derived classes
2265 OnSceneDisconnectionExternal();
2267 if( !mOffSceneSignal.Empty() )
2269 Dali::Actor handle( this );
2270 mOffSceneSignal.Emit( handle );
2273 // Guard against Add during callbacks
2276 mOnSceneSignalled = false; // signal required next time Actor is added
2281 bool Actor::IsNodeConnected() const
2283 bool connected( false );
2287 if( IsRoot() || GetNode().GetParent() )
2296 // This method initiates traversal of the actor tree using depth-first
2297 // traversal to set a depth index based on traversal order. It sends a
2298 // single message to update manager to update all the actor's nodes in
2299 // this tree with the depth index. The sceneGraphNodeDepths vector's
2300 // elements are ordered by depth, and could be used to reduce sorting
2301 // in the update thread.
2302 void Actor::RebuildDepthTree()
2304 DALI_LOG_TIMER_START(depthTimer);
2306 // Vector of scene-graph nodes and their depths to send to UpdateManager
2307 // in a single message
2308 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2310 int32_t depthIndex = 1;
2311 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2313 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2314 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2317 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2319 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2320 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2322 // Create/add to children of this node
2325 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2327 Actor* childActor = (*it).Get();
2329 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2334 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2338 case Dali::Actor::Property::PARENT_ORIGIN:
2340 Property::Type type = property.GetType();
2341 if( type == Property::VECTOR3 )
2343 SetParentOrigin( property.Get< Vector3 >() );
2345 else if ( type == Property::STRING )
2347 std::string parentOriginString;
2348 property.Get( parentOriginString );
2349 Vector3 parentOrigin;
2350 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2352 SetParentOrigin( parentOrigin );
2358 case Dali::Actor::Property::PARENT_ORIGIN_X:
2360 SetParentOriginX( property.Get< float >() );
2364 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2366 SetParentOriginY( property.Get< float >() );
2370 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2372 SetParentOriginZ( property.Get< float >() );
2376 case Dali::Actor::Property::ANCHOR_POINT:
2378 Property::Type type = property.GetType();
2379 if( type == Property::VECTOR3 )
2381 SetAnchorPoint( property.Get< Vector3 >() );
2383 else if ( type == Property::STRING )
2385 std::string anchorPointString;
2386 property.Get( anchorPointString );
2388 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2390 SetAnchorPoint( anchor );
2396 case Dali::Actor::Property::ANCHOR_POINT_X:
2398 SetAnchorPointX( property.Get< float >() );
2402 case Dali::Actor::Property::ANCHOR_POINT_Y:
2404 SetAnchorPointY( property.Get< float >() );
2408 case Dali::Actor::Property::ANCHOR_POINT_Z:
2410 SetAnchorPointZ( property.Get< float >() );
2414 case Dali::Actor::Property::SIZE:
2416 Property::Type type = property.GetType();
2417 if( type == Property::VECTOR2 )
2419 SetSize( property.Get< Vector2 >() );
2421 else if ( type == Property::VECTOR3 )
2423 SetSize( property.Get< Vector3 >() );
2428 case Dali::Actor::Property::SIZE_WIDTH:
2430 SetWidth( property.Get< float >() );
2434 case Dali::Actor::Property::SIZE_HEIGHT:
2436 SetHeight( property.Get< float >() );
2440 case Dali::Actor::Property::SIZE_DEPTH:
2442 SetDepth( property.Get< float >() );
2446 case Dali::Actor::Property::POSITION:
2448 Property::Type type = property.GetType();
2449 if( type == Property::VECTOR2 )
2451 Vector2 position = property.Get< Vector2 >();
2452 SetPosition( Vector3( position.x, position.y, 0.0f ) );
2454 else if ( type == Property::VECTOR3 )
2456 SetPosition( property.Get< Vector3 >() );
2461 case Dali::Actor::Property::POSITION_X:
2463 SetX( property.Get< float >() );
2467 case Dali::Actor::Property::POSITION_Y:
2469 SetY( property.Get< float >() );
2473 case Dali::Actor::Property::POSITION_Z:
2475 SetZ( property.Get< float >() );
2479 case Dali::Actor::Property::ORIENTATION:
2481 SetOrientation( property.Get< Quaternion >() );
2485 case Dali::Actor::Property::SCALE:
2487 Property::Type type = property.GetType();
2488 if( type == Property::FLOAT )
2490 float scale = property.Get< float >();
2491 SetScale( scale, scale, scale );
2493 else if ( type == Property::VECTOR3 )
2495 SetScale( property.Get< Vector3 >() );
2500 case Dali::Actor::Property::SCALE_X:
2502 SetScaleX( property.Get< float >() );
2506 case Dali::Actor::Property::SCALE_Y:
2508 SetScaleY( property.Get< float >() );
2512 case Dali::Actor::Property::SCALE_Z:
2514 SetScaleZ( property.Get< float >() );
2518 case Dali::Actor::Property::VISIBLE:
2520 SetVisible( property.Get< bool >() );
2524 case Dali::Actor::Property::COLOR:
2526 Property::Type type = property.GetType();
2527 if( type == Property::VECTOR3 )
2529 Vector3 color = property.Get< Vector3 >();
2530 SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2532 else if( type == Property::VECTOR4 )
2534 SetColor( property.Get< Vector4 >() );
2539 case Dali::Actor::Property::COLOR_RED:
2541 SetColorRed( property.Get< float >() );
2545 case Dali::Actor::Property::COLOR_GREEN:
2547 SetColorGreen( property.Get< float >() );
2551 case Dali::Actor::Property::COLOR_BLUE:
2553 SetColorBlue( property.Get< float >() );
2557 case Dali::Actor::Property::COLOR_ALPHA:
2558 case Dali::Actor::Property::OPACITY:
2561 if( property.Get( value ) )
2563 SetOpacity( value );
2568 case Dali::Actor::Property::NAME:
2570 SetName( property.Get< std::string >() );
2574 case Dali::Actor::Property::SENSITIVE:
2576 SetSensitive( property.Get< bool >() );
2580 case Dali::Actor::Property::LEAVE_REQUIRED:
2582 SetLeaveRequired( property.Get< bool >() );
2586 case Dali::Actor::Property::INHERIT_POSITION:
2588 SetInheritPosition( property.Get< bool >() );
2592 case Dali::Actor::Property::INHERIT_ORIENTATION:
2594 SetInheritOrientation( property.Get< bool >() );
2598 case Dali::Actor::Property::INHERIT_SCALE:
2600 SetInheritScale( property.Get< bool >() );
2604 case Dali::Actor::Property::COLOR_MODE:
2606 ColorMode mode = mColorMode;
2607 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2609 SetColorMode( mode );
2614 case Dali::Actor::Property::DRAW_MODE:
2616 DrawMode::Type mode = mDrawMode;
2617 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2619 SetDrawMode( mode );
2624 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2626 SetSizeModeFactor( property.Get< Vector3 >() );
2630 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2632 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2633 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2635 SetResizePolicy( type, Dimension::WIDTH );
2640 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2642 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2643 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2645 SetResizePolicy( type, Dimension::HEIGHT );
2650 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2652 SizeScalePolicy::Type type = GetSizeScalePolicy();
2653 if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2655 SetSizeScalePolicy( type );
2660 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2662 if( property.Get< bool >() )
2664 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2669 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2671 if( property.Get< bool >() )
2673 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2678 case Dali::Actor::Property::PADDING:
2680 Vector4 padding = property.Get< Vector4 >();
2681 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2682 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2686 case Dali::Actor::Property::MINIMUM_SIZE:
2688 Vector2 size = property.Get< Vector2 >();
2689 SetMinimumSize( size.x, Dimension::WIDTH );
2690 SetMinimumSize( size.y, Dimension::HEIGHT );
2694 case Dali::Actor::Property::MAXIMUM_SIZE:
2696 Vector2 size = property.Get< Vector2 >();
2697 SetMaximumSize( size.x, Dimension::WIDTH );
2698 SetMaximumSize( size.y, Dimension::HEIGHT );
2702 case Dali::DevelActor::Property::SIBLING_ORDER:
2706 if( property.Get( value ) )
2708 SetSiblingOrder( value );
2713 case Dali::Actor::Property::CLIPPING_MODE:
2715 ClippingMode::Type convertedValue = mClippingMode;
2716 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2718 mClippingMode = convertedValue;
2719 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2724 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
2727 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2729 mPositionUsesAnchorPoint = value;
2730 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2735 case Dali::Actor::Property::LAYOUT_DIRECTION:
2737 Dali::LayoutDirection::Type direction = mLayoutDirection;
2738 mInheritLayoutDirection = false;
2740 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2742 InheritLayoutDirectionRecursively( this, direction, true );
2747 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2750 if( property.Get( value ) )
2752 SetInheritLayoutDirection( value );
2757 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
2760 if( property.Get( value ) )
2762 SetKeyboardFocusable( value );
2767 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
2769 SetUpdateSizeHint( property.Get< Vector2 >() );
2773 case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START:
2775 bool boolValue = false;
2776 if ( property.Get( boolValue ) )
2778 mCaptureAllTouchAfterStart = boolValue;
2785 // this can happen in the case of a non-animatable default property so just do nothing
2791 // TODO: This method needs to be removed
2792 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2794 switch( entry.GetType() )
2796 case Property::BOOLEAN:
2798 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2799 DALI_ASSERT_DEBUG( NULL != property );
2801 // property is being used in a separate thread; queue a message to set the property
2802 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2807 case Property::INTEGER:
2809 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2810 DALI_ASSERT_DEBUG( NULL != property );
2812 // property is being used in a separate thread; queue a message to set the property
2813 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2818 case Property::FLOAT:
2820 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2821 DALI_ASSERT_DEBUG( NULL != property );
2823 // property is being used in a separate thread; queue a message to set the property
2824 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2829 case Property::VECTOR2:
2831 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2832 DALI_ASSERT_DEBUG( NULL != property );
2834 // property is being used in a separate thread; queue a message to set the property
2835 if(entry.componentIndex == 0)
2837 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2839 else if(entry.componentIndex == 1)
2841 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2845 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2851 case Property::VECTOR3:
2853 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2854 DALI_ASSERT_DEBUG( NULL != property );
2856 // property is being used in a separate thread; queue a message to set the property
2857 if(entry.componentIndex == 0)
2859 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2861 else if(entry.componentIndex == 1)
2863 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2865 else if(entry.componentIndex == 2)
2867 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2871 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2877 case Property::VECTOR4:
2879 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2880 DALI_ASSERT_DEBUG( NULL != property );
2882 // property is being used in a separate thread; queue a message to set the property
2883 if(entry.componentIndex == 0)
2885 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2887 else if(entry.componentIndex == 1)
2889 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2891 else if(entry.componentIndex == 2)
2893 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2895 else if(entry.componentIndex == 3)
2897 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2901 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2907 case Property::ROTATION:
2909 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2910 DALI_ASSERT_DEBUG( NULL != property );
2912 // property is being used in a separate thread; queue a message to set the property
2913 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2918 case Property::MATRIX:
2920 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2921 DALI_ASSERT_DEBUG( NULL != property );
2923 // property is being used in a separate thread; queue a message to set the property
2924 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2929 case Property::MATRIX3:
2931 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2932 DALI_ASSERT_DEBUG( NULL != property );
2934 // property is being used in a separate thread; queue a message to set the property
2935 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2942 // nothing to do for other types
2947 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2949 Property::Value value;
2951 if( ! GetCachedPropertyValue( index, value ) )
2953 // If property value is not stored in the event-side, then it must be a scene-graph only property
2954 GetCurrentPropertyValue( index, value );
2960 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2962 Property::Value value;
2964 if( ! GetCurrentPropertyValue( index, value ) )
2966 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2967 GetCachedPropertyValue( index, value );
2973 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2975 switch( animationType )
2978 case Animation::BETWEEN:
2982 case Dali::Actor::Property::SIZE:
2984 if( value.Get( mTargetSize ) )
2986 mAnimatedSize = mTargetSize;
2987 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
2989 // Notify deriving classes
2990 OnSizeAnimation( animation, mTargetSize );
2995 case Dali::Actor::Property::SIZE_WIDTH:
2997 if( value.Get( mTargetSize.width ) )
2999 mAnimatedSize.width = mTargetSize.width;
3000 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3002 // Notify deriving classes
3003 OnSizeAnimation( animation, mTargetSize );
3008 case Dali::Actor::Property::SIZE_HEIGHT:
3010 if( value.Get( mTargetSize.height ) )
3012 mAnimatedSize.height = mTargetSize.height;
3013 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3015 // Notify deriving classes
3016 OnSizeAnimation( animation, mTargetSize );
3021 case Dali::Actor::Property::SIZE_DEPTH:
3023 if( value.Get( mTargetSize.depth ) )
3025 mAnimatedSize.depth = mTargetSize.depth;
3026 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3028 // Notify deriving classes
3029 OnSizeAnimation( animation, mTargetSize );
3034 case Dali::Actor::Property::POSITION:
3036 value.Get( mTargetPosition );
3040 case Dali::Actor::Property::POSITION_X:
3042 value.Get( mTargetPosition.x );
3046 case Dali::Actor::Property::POSITION_Y:
3048 value.Get( mTargetPosition.y );
3052 case Dali::Actor::Property::POSITION_Z:
3054 value.Get( mTargetPosition.z );
3058 case Dali::Actor::Property::ORIENTATION:
3060 value.Get( mTargetOrientation );
3064 case Dali::Actor::Property::SCALE:
3066 value.Get( mTargetScale );
3070 case Dali::Actor::Property::SCALE_X:
3072 value.Get( mTargetScale.x );
3076 case Dali::Actor::Property::SCALE_Y:
3078 value.Get( mTargetScale.y );
3082 case Dali::Actor::Property::SCALE_Z:
3084 value.Get( mTargetScale.z );
3088 case Dali::Actor::Property::VISIBLE:
3090 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3094 case Dali::Actor::Property::COLOR:
3096 value.Get( mTargetColor );
3100 case Dali::Actor::Property::COLOR_RED:
3102 value.Get( mTargetColor.r );
3106 case Dali::Actor::Property::COLOR_GREEN:
3108 value.Get( mTargetColor.g );
3112 case Dali::Actor::Property::COLOR_BLUE:
3114 value.Get( mTargetColor.b );
3118 case Dali::Actor::Property::COLOR_ALPHA:
3119 case Dali::Actor::Property::OPACITY:
3121 value.Get( mTargetColor.a );
3127 // Not an animatable property. Do nothing.
3138 case Dali::Actor::Property::SIZE:
3140 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3142 mAnimatedSize = mTargetSize;
3143 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3145 // Notify deriving classes
3146 OnSizeAnimation( animation, mTargetSize );
3151 case Dali::Actor::Property::SIZE_WIDTH:
3153 if( AdjustValue< float >( mTargetSize.width, value ) )
3155 mAnimatedSize.width = mTargetSize.width;
3156 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3158 // Notify deriving classes
3159 OnSizeAnimation( animation, mTargetSize );
3164 case Dali::Actor::Property::SIZE_HEIGHT:
3166 if( AdjustValue< float >( mTargetSize.height, value ) )
3168 mAnimatedSize.height = mTargetSize.height;
3169 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3171 // Notify deriving classes
3172 OnSizeAnimation( animation, mTargetSize );
3177 case Dali::Actor::Property::SIZE_DEPTH:
3179 if( AdjustValue< float >( mTargetSize.depth, value ) )
3181 mAnimatedSize.depth = mTargetSize.depth;
3182 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3184 // Notify deriving classes
3185 OnSizeAnimation( animation, mTargetSize );
3190 case Dali::Actor::Property::POSITION:
3192 AdjustValue< Vector3 >( mTargetPosition, value );
3196 case Dali::Actor::Property::POSITION_X:
3198 AdjustValue< float >( mTargetPosition.x, value );
3202 case Dali::Actor::Property::POSITION_Y:
3204 AdjustValue< float >( mTargetPosition.y, value );
3208 case Dali::Actor::Property::POSITION_Z:
3210 AdjustValue< float >( mTargetPosition.z, value );
3214 case Dali::Actor::Property::ORIENTATION:
3216 Quaternion relativeValue;
3217 if( value.Get( relativeValue ) )
3219 mTargetOrientation *= relativeValue;
3224 case Dali::Actor::Property::SCALE:
3226 AdjustValue< Vector3 >( mTargetScale, value );
3230 case Dali::Actor::Property::SCALE_X:
3232 AdjustValue< float >( mTargetScale.x, value );
3236 case Dali::Actor::Property::SCALE_Y:
3238 AdjustValue< float >( mTargetScale.y, value );
3242 case Dali::Actor::Property::SCALE_Z:
3244 AdjustValue< float >( mTargetScale.z, value );
3248 case Dali::Actor::Property::VISIBLE:
3250 bool relativeValue = false;
3251 if( value.Get( relativeValue ) )
3253 bool visible = mVisible || relativeValue;
3254 SetVisibleInternal( visible, SendMessage::FALSE );
3259 case Dali::Actor::Property::COLOR:
3261 AdjustValue< Vector4 >( mTargetColor, value );
3265 case Dali::Actor::Property::COLOR_RED:
3267 AdjustValue< float >( mTargetColor.r, value );
3271 case Dali::Actor::Property::COLOR_GREEN:
3273 AdjustValue< float >( mTargetColor.g, value );
3277 case Dali::Actor::Property::COLOR_BLUE:
3279 AdjustValue< float >( mTargetColor.b, value );
3283 case Dali::Actor::Property::COLOR_ALPHA:
3284 case Dali::Actor::Property::OPACITY:
3286 AdjustValue< float >( mTargetColor.a, value );
3292 // Not an animatable property. Do nothing.
3301 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3303 const PropertyBase* property( nullptr );
3307 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3308 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3309 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3310 case Dali::Actor::Property::SIZE_DEPTH:
3312 property = &GetNode().mSize;
3315 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3316 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3317 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3318 case Dali::Actor::Property::POSITION_Z:
3320 property = &GetNode().mPosition;
3323 case Dali::Actor::Property::ORIENTATION:
3325 property = &GetNode().mOrientation;
3328 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3329 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3330 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3331 case Dali::Actor::Property::SCALE_Z:
3333 property = &GetNode().mScale;
3336 case Dali::Actor::Property::VISIBLE:
3338 property = &GetNode().mVisible;
3341 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3342 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3343 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3344 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3345 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3346 case Dali::Actor::Property::OPACITY:
3348 property = &GetNode().mColor;
3358 // not our property, ask base
3359 property = Object::GetSceneObjectAnimatableProperty( index );
3365 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3367 const PropertyInputImpl* property( nullptr );
3371 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3372 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3373 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3374 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3376 property = &GetNode().mParentOrigin;
3379 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3380 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3381 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3382 case Dali::Actor::Property::ANCHOR_POINT_Z:
3384 property = &GetNode().mAnchorPoint;
3387 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3388 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3389 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3390 case Dali::Actor::Property::WORLD_POSITION_Z:
3392 property = &GetNode().mWorldPosition;
3395 case Dali::Actor::Property::WORLD_ORIENTATION:
3397 property = &GetNode().mWorldOrientation;
3400 case Dali::Actor::Property::WORLD_SCALE:
3402 property = &GetNode().mWorldScale;
3405 case Dali::Actor::Property::WORLD_COLOR:
3407 property = &GetNode().mWorldColor;
3410 case Dali::Actor::Property::WORLD_MATRIX:
3412 property = &GetNode().mWorldMatrix;
3415 case Dali::Actor::Property::CULLED:
3417 property = &GetNode().mCulled;
3427 // reuse animatable property getter as animatable properties are inputs as well
3428 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3429 property = GetSceneObjectAnimatableProperty( index );
3435 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3437 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3441 case Dali::Actor::Property::PARENT_ORIGIN_X:
3442 case Dali::Actor::Property::ANCHOR_POINT_X:
3443 case Dali::Actor::Property::SIZE_WIDTH:
3444 case Dali::Actor::Property::POSITION_X:
3445 case Dali::Actor::Property::WORLD_POSITION_X:
3446 case Dali::Actor::Property::SCALE_X:
3447 case Dali::Actor::Property::COLOR_RED:
3453 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3454 case Dali::Actor::Property::ANCHOR_POINT_Y:
3455 case Dali::Actor::Property::SIZE_HEIGHT:
3456 case Dali::Actor::Property::POSITION_Y:
3457 case Dali::Actor::Property::WORLD_POSITION_Y:
3458 case Dali::Actor::Property::SCALE_Y:
3459 case Dali::Actor::Property::COLOR_GREEN:
3465 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3466 case Dali::Actor::Property::ANCHOR_POINT_Z:
3467 case Dali::Actor::Property::SIZE_DEPTH:
3468 case Dali::Actor::Property::POSITION_Z:
3469 case Dali::Actor::Property::WORLD_POSITION_Z:
3470 case Dali::Actor::Property::SCALE_Z:
3471 case Dali::Actor::Property::COLOR_BLUE:
3477 case Dali::Actor::Property::COLOR_ALPHA:
3478 case Dali::Actor::Property::OPACITY:
3490 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3493 componentIndex = Object::GetPropertyComponentIndex( index );
3496 return componentIndex;
3499 bool Actor::IsAnimationPossible() const
3504 void Actor::SetParent( Actor* parent )
3508 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3512 mScene = parent->mScene;
3514 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3517 // Instruct each actor to create a corresponding node in the scene graph
3518 ConnectToScene( parent->GetHierarchyDepth() );
3521 // Resolve the name and index for the child properties if any
3522 ResolveChildProperties();
3524 else // parent being set to NULL
3526 DALI_ASSERT_ALWAYS( mParent != nullptr && "Actor should have a parent" );
3530 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3533 // Disconnect the Node & its children from the scene-graph.
3534 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3536 // Instruct each actor to discard pointers to the scene-graph
3537 DisconnectFromStage();
3544 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3547 Actor* actor = dynamic_cast< Actor* >( object );
3551 if( 0 == actionName.compare( ACTION_SHOW ) )
3553 actor->SetVisible( true );
3556 else if( 0 == actionName.compare( ACTION_HIDE ) )
3558 actor->SetVisible( false );
3566 Rect<> Actor::CalculateScreenExtents( ) const
3568 auto screenPosition = GetCurrentScreenPosition();
3569 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3570 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3571 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3572 return { position.x, position.y, size.x, size.y };
3575 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3577 bool valueSet = true;
3581 case Dali::Actor::Property::PARENT_ORIGIN:
3583 value = GetCurrentParentOrigin();
3587 case Dali::Actor::Property::PARENT_ORIGIN_X:
3589 value = GetCurrentParentOrigin().x;
3593 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3595 value = GetCurrentParentOrigin().y;
3599 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3601 value = GetCurrentParentOrigin().z;
3605 case Dali::Actor::Property::ANCHOR_POINT:
3607 value = GetCurrentAnchorPoint();
3611 case Dali::Actor::Property::ANCHOR_POINT_X:
3613 value = GetCurrentAnchorPoint().x;
3617 case Dali::Actor::Property::ANCHOR_POINT_Y:
3619 value = GetCurrentAnchorPoint().y;
3623 case Dali::Actor::Property::ANCHOR_POINT_Z:
3625 value = GetCurrentAnchorPoint().z;
3629 case Dali::Actor::Property::SIZE:
3631 value = GetTargetSize();
3635 case Dali::Actor::Property::SIZE_WIDTH:
3637 value = GetTargetSize().width;
3641 case Dali::Actor::Property::SIZE_HEIGHT:
3643 value = GetTargetSize().height;
3647 case Dali::Actor::Property::SIZE_DEPTH:
3649 value = GetTargetSize().depth;
3653 case Dali::Actor::Property::POSITION:
3655 value = GetTargetPosition();
3659 case Dali::Actor::Property::POSITION_X:
3661 value = GetTargetPosition().x;
3665 case Dali::Actor::Property::POSITION_Y:
3667 value = GetTargetPosition().y;
3671 case Dali::Actor::Property::POSITION_Z:
3673 value = GetTargetPosition().z;
3677 case Dali::Actor::Property::ORIENTATION:
3679 value = mTargetOrientation;
3683 case Dali::Actor::Property::SCALE:
3685 value = mTargetScale;
3689 case Dali::Actor::Property::SCALE_X:
3691 value = mTargetScale.x;
3695 case Dali::Actor::Property::SCALE_Y:
3697 value = mTargetScale.y;
3701 case Dali::Actor::Property::SCALE_Z:
3703 value = mTargetScale.z;
3707 case Dali::Actor::Property::VISIBLE:
3713 case Dali::Actor::Property::COLOR:
3715 value = mTargetColor;
3719 case Dali::Actor::Property::COLOR_RED:
3721 value = mTargetColor.r;
3725 case Dali::Actor::Property::COLOR_GREEN:
3727 value = mTargetColor.g;
3731 case Dali::Actor::Property::COLOR_BLUE:
3733 value = mTargetColor.b;
3737 case Dali::Actor::Property::COLOR_ALPHA:
3738 case Dali::Actor::Property::OPACITY:
3740 value = mTargetColor.a;
3744 case Dali::Actor::Property::NAME:
3750 case Dali::Actor::Property::SENSITIVE:
3752 value = IsSensitive();
3756 case Dali::Actor::Property::LEAVE_REQUIRED:
3758 value = GetLeaveRequired();
3762 case Dali::Actor::Property::INHERIT_POSITION:
3764 value = IsPositionInherited();
3768 case Dali::Actor::Property::INHERIT_ORIENTATION:
3770 value = IsOrientationInherited();
3774 case Dali::Actor::Property::INHERIT_SCALE:
3776 value = IsScaleInherited();
3780 case Dali::Actor::Property::COLOR_MODE:
3782 value = GetColorMode();
3786 case Dali::Actor::Property::DRAW_MODE:
3788 value = GetDrawMode();
3792 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3794 value = GetSizeModeFactor();
3798 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3800 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3804 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3806 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3810 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3812 value = GetSizeScalePolicy();
3816 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3818 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3822 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3824 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3828 case Dali::Actor::Property::PADDING:
3830 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3831 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3832 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3836 case Dali::Actor::Property::MINIMUM_SIZE:
3838 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3842 case Dali::Actor::Property::MAXIMUM_SIZE:
3844 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3848 case Dali::Actor::Property::CLIPPING_MODE:
3850 value = mClippingMode;
3854 case Dali::DevelActor::Property::SIBLING_ORDER:
3856 value = static_cast<int>( GetSiblingOrder() );
3860 case Dali::Actor::Property::SCREEN_POSITION:
3862 value = GetCurrentScreenPosition();
3866 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
3868 value = mPositionUsesAnchorPoint;
3872 case Dali::Actor::Property::LAYOUT_DIRECTION:
3874 value = mLayoutDirection;
3878 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3880 value = IsLayoutDirectionInherited();
3884 case Dali::Actor::Property::ID:
3886 value = static_cast<int>( GetId() );
3890 case Dali::Actor::Property::HIERARCHY_DEPTH:
3892 value = GetHierarchyDepth();
3896 case Dali::Actor::Property::IS_ROOT:
3902 case Dali::Actor::Property::IS_LAYER:
3908 case Dali::Actor::Property::CONNECTED_TO_SCENE:
3914 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
3916 value = IsKeyboardFocusable();
3920 case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START:
3922 value = mCaptureAllTouchAfterStart;
3928 // Must be a scene-graph only property
3937 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3939 bool valueSet = true;
3943 case Dali::Actor::Property::SIZE:
3945 value = GetCurrentSize();
3949 case Dali::Actor::Property::SIZE_WIDTH:
3951 value = GetCurrentSize().width;
3955 case Dali::Actor::Property::SIZE_HEIGHT:
3957 value = GetCurrentSize().height;
3961 case Dali::Actor::Property::SIZE_DEPTH:
3963 value = GetCurrentSize().depth;
3967 case Dali::Actor::Property::POSITION:
3969 value = GetCurrentPosition();
3973 case Dali::Actor::Property::POSITION_X:
3975 value = GetCurrentPosition().x;
3979 case Dali::Actor::Property::POSITION_Y:
3981 value = GetCurrentPosition().y;
3985 case Dali::Actor::Property::POSITION_Z:
3987 value = GetCurrentPosition().z;
3991 case Dali::Actor::Property::WORLD_POSITION:
3993 value = GetCurrentWorldPosition();
3997 case Dali::Actor::Property::WORLD_POSITION_X:
3999 value = GetCurrentWorldPosition().x;
4003 case Dali::Actor::Property::WORLD_POSITION_Y:
4005 value = GetCurrentWorldPosition().y;
4009 case Dali::Actor::Property::WORLD_POSITION_Z:
4011 value = GetCurrentWorldPosition().z;
4015 case Dali::Actor::Property::ORIENTATION:
4017 value = GetCurrentOrientation();
4021 case Dali::Actor::Property::WORLD_ORIENTATION:
4023 value = GetCurrentWorldOrientation();
4027 case Dali::Actor::Property::SCALE:
4029 value = GetCurrentScale();
4033 case Dali::Actor::Property::SCALE_X:
4035 value = GetCurrentScale().x;
4039 case Dali::Actor::Property::SCALE_Y:
4041 value = GetCurrentScale().y;
4045 case Dali::Actor::Property::SCALE_Z:
4047 value = GetCurrentScale().z;
4051 case Dali::Actor::Property::WORLD_SCALE:
4053 value = GetCurrentWorldScale();
4057 case Dali::Actor::Property::COLOR:
4059 value = GetCurrentColor();
4063 case Dali::Actor::Property::COLOR_RED:
4065 value = GetCurrentColor().r;
4069 case Dali::Actor::Property::COLOR_GREEN:
4071 value = GetCurrentColor().g;
4075 case Dali::Actor::Property::COLOR_BLUE:
4077 value = GetCurrentColor().b;
4081 case Dali::Actor::Property::COLOR_ALPHA:
4082 case Dali::Actor::Property::OPACITY:
4084 value = GetCurrentColor().a;
4088 case Dali::Actor::Property::WORLD_COLOR:
4090 value = GetCurrentWorldColor();
4094 case Dali::Actor::Property::WORLD_MATRIX:
4096 value = GetCurrentWorldMatrix();
4100 case Dali::Actor::Property::VISIBLE:
4102 value = IsVisible();
4106 case Dali::Actor::Property::CULLED:
4108 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4112 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
4114 value = GetUpdateSizeHint();
4120 // Must be an event-side only property
4129 void Actor::EnsureRelayoutData()
4131 // Assign relayout data.
4132 if( !mRelayoutData )
4134 mRelayoutData = new RelayoutData();
4138 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4140 // Check if actor is dependent on parent
4141 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4143 if( ( dimension & ( 1 << i ) ) )
4145 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4146 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4156 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4158 // Check if actor is dependent on children
4159 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4161 if( ( dimension & ( 1 << i ) ) )
4163 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4164 switch( resizePolicy )
4166 case ResizePolicy::FIT_TO_CHILDREN:
4167 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4183 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4185 return Actor::RelayoutDependentOnChildren( dimension );
4188 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4190 // Check each possible dimension and see if it is dependent on the input one
4191 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4193 if( dimension & ( 1 << i ) )
4195 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4202 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4204 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4206 if( dimension & ( 1 << i ) )
4208 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4213 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4215 // If more than one dimension is requested, just return the first one found
4216 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4218 if( ( dimension & ( 1 << i ) ) )
4220 return mRelayoutData->negotiatedDimensions[ i ];
4224 return 0.0f; // Default
4227 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4229 EnsureRelayoutData();
4231 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4233 if( dimension & ( 1 << i ) )
4235 mRelayoutData->dimensionPadding[ i ] = padding;
4240 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4242 if ( mRelayoutData )
4244 // If more than one dimension is requested, just return the first one found
4245 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4247 if( ( dimension & ( 1 << i ) ) )
4249 return mRelayoutData->dimensionPadding[ i ];
4254 return GetDefaultDimensionPadding();
4257 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4259 EnsureRelayoutData();
4261 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4263 if( dimension & ( 1 << i ) )
4265 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4270 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4272 if ( mRelayoutData )
4274 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4276 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4286 float Actor::GetHeightForWidthBase( float width )
4288 float height = 0.0f;
4290 const Vector3 naturalSize = GetNaturalSize();
4291 if( naturalSize.width > 0.0f )
4293 height = naturalSize.height * width / naturalSize.width;
4295 else // we treat 0 as 1:1 aspect ratio
4303 float Actor::GetWidthForHeightBase( float height )
4307 const Vector3 naturalSize = GetNaturalSize();
4308 if( naturalSize.height > 0.0f )
4310 width = naturalSize.width * height / naturalSize.height;
4312 else // we treat 0 as 1:1 aspect ratio
4320 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4322 // Fill to parent, taking size mode factor into account
4323 switch( child.GetResizePolicy( dimension ) )
4325 case ResizePolicy::FILL_TO_PARENT:
4327 return GetLatestSize( dimension );
4330 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4332 return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4335 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4337 return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4342 return GetLatestSize( dimension );
4347 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4349 // Can be overridden in derived class
4350 return CalculateChildSizeBase( child, dimension );
4353 float Actor::GetHeightForWidth( float width )
4355 // Can be overridden in derived class
4356 return GetHeightForWidthBase( width );
4359 float Actor::GetWidthForHeight( float height )
4361 // Can be overridden in derived class
4362 return GetWidthForHeightBase( height );
4365 float Actor::GetLatestSize( Dimension::Type dimension ) const
4367 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4370 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4372 Vector2 padding = GetPadding( dimension );
4374 return GetLatestSize( dimension ) + padding.x + padding.y;
4377 float Actor::NegotiateFromParent( Dimension::Type dimension )
4379 Actor* parent = GetParent();
4382 Vector2 padding( GetPadding( dimension ) );
4383 Vector2 parentPadding( parent->GetPadding( dimension ) );
4384 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4390 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4392 float maxDimensionPoint = 0.0f;
4394 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4396 ActorPtr child = GetChildAt( i );
4398 if( !child->RelayoutDependentOnParent( dimension ) )
4400 // Calculate the min and max points that the children range across
4401 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4402 float dimensionSize = child->GetRelayoutSize( dimension );
4403 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4407 return maxDimensionPoint;
4410 float Actor::GetSize( Dimension::Type dimension ) const
4412 return GetDimensionValue( mTargetSize, dimension );
4415 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4417 return GetDimensionValue( GetNaturalSize(), dimension );
4420 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4422 switch( GetResizePolicy( dimension ) )
4424 case ResizePolicy::USE_NATURAL_SIZE:
4426 return GetNaturalSize( dimension );
4429 case ResizePolicy::FIXED:
4431 return GetDimensionValue( GetPreferredSize(), dimension );
4434 case ResizePolicy::USE_ASSIGNED_SIZE:
4436 return GetDimensionValue( maximumSize, dimension );
4439 case ResizePolicy::FILL_TO_PARENT:
4440 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4441 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4443 return NegotiateFromParent( dimension );
4446 case ResizePolicy::FIT_TO_CHILDREN:
4448 return NegotiateFromChildren( dimension );
4451 case ResizePolicy::DIMENSION_DEPENDENCY:
4453 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4456 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4458 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4461 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4463 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4475 return 0.0f; // Default
4478 float Actor::ClampDimension( float size, Dimension::Type dimension )
4480 const float minSize = GetMinimumSize( dimension );
4481 const float maxSize = GetMaximumSize( dimension );
4483 return std::max( minSize, std::min( size, maxSize ) );
4486 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4488 // Check if it needs to be negotiated
4489 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4491 // Check that we havn't gotten into an infinite loop
4492 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4493 bool recursionFound = false;
4494 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4496 if( *it == searchActor )
4498 recursionFound = true;
4503 if( !recursionFound )
4505 // Record the path that we have taken
4506 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4508 // Dimension dependency check
4509 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4511 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4513 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4515 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4519 // Parent dependency check
4520 Actor* parent = GetParent();
4521 if( parent && RelayoutDependentOnParent( dimension ) )
4523 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4526 // Children dependency check
4527 if( RelayoutDependentOnChildren( dimension ) )
4529 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4531 ActorPtr child = GetChildAt( i );
4533 // Only relayout child first if it is not dependent on this actor
4534 if( !child->RelayoutDependentOnParent( dimension ) )
4536 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4541 // For deriving classes
4542 OnCalculateRelayoutSize( dimension );
4544 // All dependencies checked, calculate the size and set negotiated flag
4545 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4547 SetNegotiatedDimension( newSize, dimension );
4548 SetLayoutNegotiated( true, dimension );
4550 // For deriving classes
4551 OnLayoutNegotiated( newSize, dimension );
4553 // This actor has been successfully processed, pop it off the recursion stack
4554 recursionStack.pop_back();
4558 // TODO: Break infinite loop
4559 SetLayoutNegotiated( true, dimension );
4564 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4566 // Negotiate all dimensions that require it
4567 ActorDimensionStack recursionStack;
4569 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4571 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4574 NegotiateDimension( dimension, allocatedSize, recursionStack );
4578 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4580 switch( mRelayoutData->sizeSetPolicy )
4582 case SizeScalePolicy::USE_SIZE_SET:
4587 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4589 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4590 const Vector3 naturalSize = GetNaturalSize();
4591 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4593 const float sizeRatio = size.width / size.height;
4594 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4596 if( naturalSizeRatio < sizeRatio )
4598 return Vector2( naturalSizeRatio * size.height, size.height );
4600 else if( naturalSizeRatio > sizeRatio )
4602 return Vector2( size.width, size.width / naturalSizeRatio );
4613 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4615 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4616 const Vector3 naturalSize = GetNaturalSize();
4617 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4619 const float sizeRatio = size.width / size.height;
4620 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4622 if( naturalSizeRatio < sizeRatio )
4624 return Vector2( size.width, size.width / naturalSizeRatio );
4626 else if( naturalSizeRatio > sizeRatio )
4628 return Vector2( naturalSizeRatio * size.height, size.height );
4647 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4649 // Do the set actor size
4650 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4652 // Adjust for size set policy
4653 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4655 // Lock the flag to stop recursive relayouts on set size
4656 mRelayoutData->insideRelayout = true;
4657 SetSize( negotiatedSize );
4658 mRelayoutData->insideRelayout = false;
4660 // Clear flags for all dimensions
4661 SetLayoutDirty( false );
4663 // Give deriving classes a chance to respond
4664 OnRelayout( negotiatedSize, container );
4666 if( !mOnRelayoutSignal.Empty() )
4668 Dali::Actor handle( this );
4669 mOnRelayoutSignal.Emit( handle );
4673 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4675 // Force a size negotiation for actors that has assigned size during relayout
4676 // This is required as otherwise the flags that force a relayout will not
4677 // necessarilly be set. This will occur if the actor has already been laid out.
4678 // The dirty flags are then cleared. Then if the actor is added back into the
4679 // relayout container afterwards, the dirty flags would still be clear...
4680 // causing a relayout to be skipped. Here we force any actors added to the
4681 // container to be relayed out.
4682 DALI_LOG_TIMER_START( NegSizeTimer1 );
4684 if( GetUseAssignedSize(Dimension::WIDTH ) )
4686 SetLayoutNegotiated( false, Dimension::WIDTH );
4688 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4690 SetLayoutNegotiated( false, Dimension::HEIGHT );
4693 // Do the negotiation
4694 NegotiateDimensions( allocatedSize );
4696 // Set the actor size
4697 SetNegotiatedSize( container );
4699 // Negotiate down to children
4700 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4702 ActorPtr child = GetChildAt( i );
4704 // Forces children that have already been laid out to be relayed out
4705 // if they have assigned size during relayout.
4706 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4708 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4709 child->SetLayoutDirty(true, Dimension::WIDTH);
4712 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4714 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4715 child->SetLayoutDirty(true, Dimension::HEIGHT);
4718 // Only relayout if required
4719 if( child->RelayoutRequired() )
4721 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4724 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4727 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4731 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4733 if( dimension & ( 1 << i ) )
4735 mRelayoutData->useAssignedSize[ i ] = use;
4741 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4743 if ( mRelayoutData )
4745 // If more than one dimension is requested, just return the first one found
4746 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4748 if( dimension & ( 1 << i ) )
4750 return mRelayoutData->useAssignedSize[ i ];
4758 void Actor::RelayoutRequest( Dimension::Type dimension )
4760 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4761 if( relayoutController )
4763 Dali::Actor self( this );
4764 relayoutController->RequestRelayout( self, dimension );
4768 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4772 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4776 void Actor::SetPreferredSize( const Vector2& size )
4778 EnsureRelayoutData();
4780 // If valid width or height, then set the resize policy to FIXED
4781 // 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,
4782 // then change to FIXED as well
4784 if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4786 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4789 if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4791 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4794 mRelayoutData->preferredSize = size;
4796 mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4801 Vector2 Actor::GetPreferredSize() const
4803 if ( mRelayoutData )
4805 return Vector2( mRelayoutData->preferredSize );
4808 return GetDefaultPreferredSize();
4811 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4813 EnsureRelayoutData();
4815 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4817 if( dimension & ( 1 << i ) )
4819 mRelayoutData->minimumSize[ i ] = size;
4826 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4828 if ( mRelayoutData )
4830 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4832 if( dimension & ( 1 << i ) )
4834 return mRelayoutData->minimumSize[ i ];
4839 return 0.0f; // Default
4842 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4844 EnsureRelayoutData();
4846 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4848 if( dimension & ( 1 << i ) )
4850 mRelayoutData->maximumSize[ i ] = size;
4857 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4859 if ( mRelayoutData )
4861 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4863 if( dimension & ( 1 << i ) )
4865 return mRelayoutData->maximumSize[ i ];
4870 return FLT_MAX; // Default
4873 Object* Actor::GetParentObject() const
4878 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4880 if( mVisible != visible )
4882 if( sendMessage == SendMessage::TRUE )
4884 // node is being used in a separate thread; queue a message to set the value & base value
4885 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4890 // Emit the signal on this actor and all its children
4891 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4895 void Actor::SetSiblingOrder( uint32_t order )
4899 ActorContainer& siblings = *(mParent->mChildren);
4900 uint32_t currentOrder = GetSiblingOrder();
4902 if( order != currentOrder )
4908 else if( order < siblings.size() -1 )
4910 if( order > currentOrder )
4912 RaiseAbove( *siblings[order] );
4916 LowerBelow( *siblings[order] );
4927 uint32_t Actor::GetSiblingOrder() const
4933 ActorContainer& siblings = *(mParent->mChildren);
4934 for( std::size_t i = 0; i < siblings.size(); ++i )
4936 if( siblings[i] == this )
4938 order = static_cast<uint32_t>( i );
4947 void Actor::RequestRebuildDepthTree()
4953 mScene->RequestRebuildDepthTree();
4962 ActorContainer& siblings = *(mParent->mChildren);
4963 if( siblings.back() != this ) // If not already at end
4965 for( std::size_t i=0; i<siblings.size(); ++i )
4967 if( siblings[i] == this )
4970 ActorPtr next = siblings[i+1];
4971 siblings[i+1] = this;
4978 Dali::Actor handle( this );
4979 mParent->mChildOrderChangedSignal.Emit( handle );
4981 RequestRebuildDepthTree();
4985 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4993 ActorContainer& siblings = *(mParent->mChildren);
4994 if( siblings.front() != this ) // If not already at beginning
4996 for( std::size_t i=1; i<siblings.size(); ++i )
4998 if( siblings[i] == this )
5000 // Swap with previous
5001 ActorPtr previous = siblings[i-1];
5002 siblings[i-1] = this;
5003 siblings[i] = previous;
5009 Dali::Actor handle( this );
5010 mParent->mChildOrderChangedSignal.Emit( handle );
5012 RequestRebuildDepthTree();
5016 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5020 void Actor::RaiseToTop()
5024 ActorContainer& siblings = *(mParent->mChildren);
5025 if( siblings.back() != this ) // If not already at end
5027 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5028 if( iter != siblings.end() )
5030 siblings.erase(iter);
5031 siblings.push_back(ActorPtr(this));
5035 Dali::Actor handle( this );
5036 mParent->mChildOrderChangedSignal.Emit( handle );
5038 RequestRebuildDepthTree();
5042 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5046 void Actor::LowerToBottom()
5050 ActorContainer& siblings = *(mParent->mChildren);
5051 if( siblings.front() != this ) // If not already at bottom,
5053 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5055 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5056 if( iter != siblings.end() )
5058 siblings.erase(iter);
5059 siblings.insert(siblings.begin(), thisPtr);
5063 Dali::Actor handle( this );
5064 mParent->mChildOrderChangedSignal.Emit( handle );
5066 RequestRebuildDepthTree();
5070 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5074 void Actor::RaiseAbove( Internal::Actor& target )
5078 ActorContainer& siblings = *(mParent->mChildren);
5079 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5081 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5083 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5084 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5085 if( thisIter < targetIter )
5087 siblings.erase(thisIter);
5088 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5089 // invalidate thisIter)
5090 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5092 siblings.insert(targetIter, thisPtr);
5095 Dali::Actor handle( this );
5096 mParent->mChildOrderChangedSignal.Emit( handle );
5098 RequestRebuildDepthTree();
5103 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5107 void Actor::LowerBelow( Internal::Actor& target )
5111 ActorContainer& siblings = *(mParent->mChildren);
5112 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5114 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5116 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5117 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5119 if( thisIter > targetIter )
5121 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5122 siblings.insert(targetIter, thisPtr);
5125 Dali::Actor handle( this );
5126 mParent->mChildOrderChangedSignal.Emit( handle );
5128 RequestRebuildDepthTree();
5133 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5137 void Actor::SetScene( Scene& scene )
5142 Scene& Actor::GetScene() const
5147 void Actor::SetInheritLayoutDirection( bool inherit )
5149 if( mInheritLayoutDirection != inherit )
5151 mInheritLayoutDirection = inherit;
5153 if( inherit && mParent )
5155 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5160 bool Actor::IsLayoutDirectionInherited() const
5162 return mInheritLayoutDirection;
5165 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5167 if( actor && ( actor->mInheritLayoutDirection || set ) )
5169 if( actor->mLayoutDirection != direction )
5171 actor->mLayoutDirection = direction;
5172 actor->EmitLayoutDirectionChangedSignal( direction );
5173 actor->RelayoutRequest();
5176 if( actor->GetChildCount() > 0 )
5178 ActorContainer& children = actor->GetChildrenInternal();
5179 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5181 InheritLayoutDirectionRecursively( *iter, direction );
5187 void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint )
5189 // node is being used in a separate thread; queue a message to set the value & base value
5190 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) );
5193 Vector2 Actor::GetUpdateSizeHint() const
5195 // node is being used in a separate thread, the value from the previous update is the same, set by user
5196 Vector3 updateSizeHint = GetNode().GetUpdateSizeHint();
5197 return Vector2( updateSizeHint.width, updateSizeHint.height );
5200 } // namespace Internal