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 void Actor::SetParent( Actor* parent )
3503 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3507 mScene = parent->mScene;
3509 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3512 // Instruct each actor to create a corresponding node in the scene graph
3513 ConnectToScene( parent->GetHierarchyDepth() );
3516 // Resolve the name and index for the child properties if any
3517 ResolveChildProperties();
3519 else // parent being set to NULL
3521 DALI_ASSERT_ALWAYS( mParent != nullptr && "Actor should have a parent" );
3525 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3528 // Disconnect the Node & its children from the scene-graph.
3529 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3531 // Instruct each actor to discard pointers to the scene-graph
3532 DisconnectFromStage();
3539 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3542 Actor* actor = dynamic_cast< Actor* >( object );
3546 if( 0 == actionName.compare( ACTION_SHOW ) )
3548 actor->SetVisible( true );
3551 else if( 0 == actionName.compare( ACTION_HIDE ) )
3553 actor->SetVisible( false );
3561 Rect<> Actor::CalculateScreenExtents( ) const
3563 auto screenPosition = GetCurrentScreenPosition();
3564 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3565 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3566 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3567 return { position.x, position.y, size.x, size.y };
3570 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3572 bool valueSet = true;
3576 case Dali::Actor::Property::PARENT_ORIGIN:
3578 value = GetCurrentParentOrigin();
3582 case Dali::Actor::Property::PARENT_ORIGIN_X:
3584 value = GetCurrentParentOrigin().x;
3588 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3590 value = GetCurrentParentOrigin().y;
3594 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3596 value = GetCurrentParentOrigin().z;
3600 case Dali::Actor::Property::ANCHOR_POINT:
3602 value = GetCurrentAnchorPoint();
3606 case Dali::Actor::Property::ANCHOR_POINT_X:
3608 value = GetCurrentAnchorPoint().x;
3612 case Dali::Actor::Property::ANCHOR_POINT_Y:
3614 value = GetCurrentAnchorPoint().y;
3618 case Dali::Actor::Property::ANCHOR_POINT_Z:
3620 value = GetCurrentAnchorPoint().z;
3624 case Dali::Actor::Property::SIZE:
3626 value = GetTargetSize();
3630 case Dali::Actor::Property::SIZE_WIDTH:
3632 value = GetTargetSize().width;
3636 case Dali::Actor::Property::SIZE_HEIGHT:
3638 value = GetTargetSize().height;
3642 case Dali::Actor::Property::SIZE_DEPTH:
3644 value = GetTargetSize().depth;
3648 case Dali::Actor::Property::POSITION:
3650 value = GetTargetPosition();
3654 case Dali::Actor::Property::POSITION_X:
3656 value = GetTargetPosition().x;
3660 case Dali::Actor::Property::POSITION_Y:
3662 value = GetTargetPosition().y;
3666 case Dali::Actor::Property::POSITION_Z:
3668 value = GetTargetPosition().z;
3672 case Dali::Actor::Property::ORIENTATION:
3674 value = mTargetOrientation;
3678 case Dali::Actor::Property::SCALE:
3680 value = mTargetScale;
3684 case Dali::Actor::Property::SCALE_X:
3686 value = mTargetScale.x;
3690 case Dali::Actor::Property::SCALE_Y:
3692 value = mTargetScale.y;
3696 case Dali::Actor::Property::SCALE_Z:
3698 value = mTargetScale.z;
3702 case Dali::Actor::Property::VISIBLE:
3708 case Dali::Actor::Property::COLOR:
3710 value = mTargetColor;
3714 case Dali::Actor::Property::COLOR_RED:
3716 value = mTargetColor.r;
3720 case Dali::Actor::Property::COLOR_GREEN:
3722 value = mTargetColor.g;
3726 case Dali::Actor::Property::COLOR_BLUE:
3728 value = mTargetColor.b;
3732 case Dali::Actor::Property::COLOR_ALPHA:
3733 case Dali::Actor::Property::OPACITY:
3735 value = mTargetColor.a;
3739 case Dali::Actor::Property::NAME:
3745 case Dali::Actor::Property::SENSITIVE:
3747 value = IsSensitive();
3751 case Dali::Actor::Property::LEAVE_REQUIRED:
3753 value = GetLeaveRequired();
3757 case Dali::Actor::Property::INHERIT_POSITION:
3759 value = IsPositionInherited();
3763 case Dali::Actor::Property::INHERIT_ORIENTATION:
3765 value = IsOrientationInherited();
3769 case Dali::Actor::Property::INHERIT_SCALE:
3771 value = IsScaleInherited();
3775 case Dali::Actor::Property::COLOR_MODE:
3777 value = GetColorMode();
3781 case Dali::Actor::Property::DRAW_MODE:
3783 value = GetDrawMode();
3787 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3789 value = GetSizeModeFactor();
3793 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3795 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3799 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3801 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3805 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3807 value = GetSizeScalePolicy();
3811 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3813 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3817 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3819 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3823 case Dali::Actor::Property::PADDING:
3825 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3826 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3827 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3831 case Dali::Actor::Property::MINIMUM_SIZE:
3833 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3837 case Dali::Actor::Property::MAXIMUM_SIZE:
3839 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3843 case Dali::Actor::Property::CLIPPING_MODE:
3845 value = mClippingMode;
3849 case Dali::DevelActor::Property::SIBLING_ORDER:
3851 value = static_cast<int>( GetSiblingOrder() );
3855 case Dali::Actor::Property::SCREEN_POSITION:
3857 value = GetCurrentScreenPosition();
3861 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
3863 value = mPositionUsesAnchorPoint;
3867 case Dali::Actor::Property::LAYOUT_DIRECTION:
3869 value = mLayoutDirection;
3873 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3875 value = IsLayoutDirectionInherited();
3879 case Dali::Actor::Property::ID:
3881 value = static_cast<int>( GetId() );
3885 case Dali::Actor::Property::HIERARCHY_DEPTH:
3887 value = GetHierarchyDepth();
3891 case Dali::Actor::Property::IS_ROOT:
3897 case Dali::Actor::Property::IS_LAYER:
3903 case Dali::Actor::Property::CONNECTED_TO_SCENE:
3909 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
3911 value = IsKeyboardFocusable();
3915 case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START:
3917 value = mCaptureAllTouchAfterStart;
3923 // Must be a scene-graph only property
3932 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3934 bool valueSet = true;
3938 case Dali::Actor::Property::SIZE:
3940 value = GetCurrentSize();
3944 case Dali::Actor::Property::SIZE_WIDTH:
3946 value = GetCurrentSize().width;
3950 case Dali::Actor::Property::SIZE_HEIGHT:
3952 value = GetCurrentSize().height;
3956 case Dali::Actor::Property::SIZE_DEPTH:
3958 value = GetCurrentSize().depth;
3962 case Dali::Actor::Property::POSITION:
3964 value = GetCurrentPosition();
3968 case Dali::Actor::Property::POSITION_X:
3970 value = GetCurrentPosition().x;
3974 case Dali::Actor::Property::POSITION_Y:
3976 value = GetCurrentPosition().y;
3980 case Dali::Actor::Property::POSITION_Z:
3982 value = GetCurrentPosition().z;
3986 case Dali::Actor::Property::WORLD_POSITION:
3988 value = GetCurrentWorldPosition();
3992 case Dali::Actor::Property::WORLD_POSITION_X:
3994 value = GetCurrentWorldPosition().x;
3998 case Dali::Actor::Property::WORLD_POSITION_Y:
4000 value = GetCurrentWorldPosition().y;
4004 case Dali::Actor::Property::WORLD_POSITION_Z:
4006 value = GetCurrentWorldPosition().z;
4010 case Dali::Actor::Property::ORIENTATION:
4012 value = GetCurrentOrientation();
4016 case Dali::Actor::Property::WORLD_ORIENTATION:
4018 value = GetCurrentWorldOrientation();
4022 case Dali::Actor::Property::SCALE:
4024 value = GetCurrentScale();
4028 case Dali::Actor::Property::SCALE_X:
4030 value = GetCurrentScale().x;
4034 case Dali::Actor::Property::SCALE_Y:
4036 value = GetCurrentScale().y;
4040 case Dali::Actor::Property::SCALE_Z:
4042 value = GetCurrentScale().z;
4046 case Dali::Actor::Property::WORLD_SCALE:
4048 value = GetCurrentWorldScale();
4052 case Dali::Actor::Property::COLOR:
4054 value = GetCurrentColor();
4058 case Dali::Actor::Property::COLOR_RED:
4060 value = GetCurrentColor().r;
4064 case Dali::Actor::Property::COLOR_GREEN:
4066 value = GetCurrentColor().g;
4070 case Dali::Actor::Property::COLOR_BLUE:
4072 value = GetCurrentColor().b;
4076 case Dali::Actor::Property::COLOR_ALPHA:
4077 case Dali::Actor::Property::OPACITY:
4079 value = GetCurrentColor().a;
4083 case Dali::Actor::Property::WORLD_COLOR:
4085 value = GetCurrentWorldColor();
4089 case Dali::Actor::Property::WORLD_MATRIX:
4091 value = GetCurrentWorldMatrix();
4095 case Dali::Actor::Property::VISIBLE:
4097 value = IsVisible();
4101 case Dali::Actor::Property::CULLED:
4103 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4107 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
4109 value = GetUpdateSizeHint();
4115 // Must be an event-side only property
4124 void Actor::EnsureRelayoutData()
4126 // Assign relayout data.
4127 if( !mRelayoutData )
4129 mRelayoutData = new RelayoutData();
4133 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4135 // Check if actor is dependent on parent
4136 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4138 if( ( dimension & ( 1 << i ) ) )
4140 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4141 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4151 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4153 // Check if actor is dependent on children
4154 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4156 if( ( dimension & ( 1 << i ) ) )
4158 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4159 switch( resizePolicy )
4161 case ResizePolicy::FIT_TO_CHILDREN:
4162 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4178 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4180 return Actor::RelayoutDependentOnChildren( dimension );
4183 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4185 // Check each possible dimension and see if it is dependent on the input one
4186 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4188 if( dimension & ( 1 << i ) )
4190 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4197 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4199 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4201 if( dimension & ( 1 << i ) )
4203 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4208 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4210 // If more than one dimension is requested, just return the first one found
4211 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4213 if( ( dimension & ( 1 << i ) ) )
4215 return mRelayoutData->negotiatedDimensions[ i ];
4219 return 0.0f; // Default
4222 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4224 EnsureRelayoutData();
4226 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4228 if( dimension & ( 1 << i ) )
4230 mRelayoutData->dimensionPadding[ i ] = padding;
4235 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4237 if ( mRelayoutData )
4239 // If more than one dimension is requested, just return the first one found
4240 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4242 if( ( dimension & ( 1 << i ) ) )
4244 return mRelayoutData->dimensionPadding[ i ];
4249 return GetDefaultDimensionPadding();
4252 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4254 EnsureRelayoutData();
4256 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4258 if( dimension & ( 1 << i ) )
4260 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4265 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4267 if ( mRelayoutData )
4269 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4271 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4281 float Actor::GetHeightForWidthBase( float width )
4283 float height = 0.0f;
4285 const Vector3 naturalSize = GetNaturalSize();
4286 if( naturalSize.width > 0.0f )
4288 height = naturalSize.height * width / naturalSize.width;
4290 else // we treat 0 as 1:1 aspect ratio
4298 float Actor::GetWidthForHeightBase( float height )
4302 const Vector3 naturalSize = GetNaturalSize();
4303 if( naturalSize.height > 0.0f )
4305 width = naturalSize.width * height / naturalSize.height;
4307 else // we treat 0 as 1:1 aspect ratio
4315 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4317 // Fill to parent, taking size mode factor into account
4318 switch( child.GetResizePolicy( dimension ) )
4320 case ResizePolicy::FILL_TO_PARENT:
4322 return GetLatestSize( dimension );
4325 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4327 return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4330 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4332 return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4337 return GetLatestSize( dimension );
4342 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4344 // Can be overridden in derived class
4345 return CalculateChildSizeBase( child, dimension );
4348 float Actor::GetHeightForWidth( float width )
4350 // Can be overridden in derived class
4351 return GetHeightForWidthBase( width );
4354 float Actor::GetWidthForHeight( float height )
4356 // Can be overridden in derived class
4357 return GetWidthForHeightBase( height );
4360 float Actor::GetLatestSize( Dimension::Type dimension ) const
4362 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4365 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4367 Vector2 padding = GetPadding( dimension );
4369 return GetLatestSize( dimension ) + padding.x + padding.y;
4372 float Actor::NegotiateFromParent( Dimension::Type dimension )
4374 Actor* parent = GetParent();
4377 Vector2 padding( GetPadding( dimension ) );
4378 Vector2 parentPadding( parent->GetPadding( dimension ) );
4379 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4385 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4387 float maxDimensionPoint = 0.0f;
4389 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4391 ActorPtr child = GetChildAt( i );
4393 if( !child->RelayoutDependentOnParent( dimension ) )
4395 // Calculate the min and max points that the children range across
4396 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4397 float dimensionSize = child->GetRelayoutSize( dimension );
4398 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4402 return maxDimensionPoint;
4405 float Actor::GetSize( Dimension::Type dimension ) const
4407 return GetDimensionValue( mTargetSize, dimension );
4410 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4412 return GetDimensionValue( GetNaturalSize(), dimension );
4415 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4417 switch( GetResizePolicy( dimension ) )
4419 case ResizePolicy::USE_NATURAL_SIZE:
4421 return GetNaturalSize( dimension );
4424 case ResizePolicy::FIXED:
4426 return GetDimensionValue( GetPreferredSize(), dimension );
4429 case ResizePolicy::USE_ASSIGNED_SIZE:
4431 return GetDimensionValue( maximumSize, dimension );
4434 case ResizePolicy::FILL_TO_PARENT:
4435 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4436 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4438 return NegotiateFromParent( dimension );
4441 case ResizePolicy::FIT_TO_CHILDREN:
4443 return NegotiateFromChildren( dimension );
4446 case ResizePolicy::DIMENSION_DEPENDENCY:
4448 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4451 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4453 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4456 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4458 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4470 return 0.0f; // Default
4473 float Actor::ClampDimension( float size, Dimension::Type dimension )
4475 const float minSize = GetMinimumSize( dimension );
4476 const float maxSize = GetMaximumSize( dimension );
4478 return std::max( minSize, std::min( size, maxSize ) );
4481 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4483 // Check if it needs to be negotiated
4484 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4486 // Check that we havn't gotten into an infinite loop
4487 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4488 bool recursionFound = false;
4489 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4491 if( *it == searchActor )
4493 recursionFound = true;
4498 if( !recursionFound )
4500 // Record the path that we have taken
4501 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4503 // Dimension dependency check
4504 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4506 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4508 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4510 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4514 // Parent dependency check
4515 Actor* parent = GetParent();
4516 if( parent && RelayoutDependentOnParent( dimension ) )
4518 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4521 // Children dependency check
4522 if( RelayoutDependentOnChildren( dimension ) )
4524 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4526 ActorPtr child = GetChildAt( i );
4528 // Only relayout child first if it is not dependent on this actor
4529 if( !child->RelayoutDependentOnParent( dimension ) )
4531 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4536 // For deriving classes
4537 OnCalculateRelayoutSize( dimension );
4539 // All dependencies checked, calculate the size and set negotiated flag
4540 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4542 SetNegotiatedDimension( newSize, dimension );
4543 SetLayoutNegotiated( true, dimension );
4545 // For deriving classes
4546 OnLayoutNegotiated( newSize, dimension );
4548 // This actor has been successfully processed, pop it off the recursion stack
4549 recursionStack.pop_back();
4553 // TODO: Break infinite loop
4554 SetLayoutNegotiated( true, dimension );
4559 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4561 // Negotiate all dimensions that require it
4562 ActorDimensionStack recursionStack;
4564 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4566 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4569 NegotiateDimension( dimension, allocatedSize, recursionStack );
4573 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4575 switch( mRelayoutData->sizeSetPolicy )
4577 case SizeScalePolicy::USE_SIZE_SET:
4582 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4584 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4585 const Vector3 naturalSize = GetNaturalSize();
4586 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4588 const float sizeRatio = size.width / size.height;
4589 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4591 if( naturalSizeRatio < sizeRatio )
4593 return Vector2( naturalSizeRatio * size.height, size.height );
4595 else if( naturalSizeRatio > sizeRatio )
4597 return Vector2( size.width, size.width / naturalSizeRatio );
4608 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4610 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4611 const Vector3 naturalSize = GetNaturalSize();
4612 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4614 const float sizeRatio = size.width / size.height;
4615 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4617 if( naturalSizeRatio < sizeRatio )
4619 return Vector2( size.width, size.width / naturalSizeRatio );
4621 else if( naturalSizeRatio > sizeRatio )
4623 return Vector2( naturalSizeRatio * size.height, size.height );
4642 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4644 // Do the set actor size
4645 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4647 // Adjust for size set policy
4648 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4650 // Lock the flag to stop recursive relayouts on set size
4651 mRelayoutData->insideRelayout = true;
4652 SetSize( negotiatedSize );
4653 mRelayoutData->insideRelayout = false;
4655 // Clear flags for all dimensions
4656 SetLayoutDirty( false );
4658 // Give deriving classes a chance to respond
4659 OnRelayout( negotiatedSize, container );
4661 if( !mOnRelayoutSignal.Empty() )
4663 Dali::Actor handle( this );
4664 mOnRelayoutSignal.Emit( handle );
4668 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4670 // Force a size negotiation for actors that has assigned size during relayout
4671 // This is required as otherwise the flags that force a relayout will not
4672 // necessarilly be set. This will occur if the actor has already been laid out.
4673 // The dirty flags are then cleared. Then if the actor is added back into the
4674 // relayout container afterwards, the dirty flags would still be clear...
4675 // causing a relayout to be skipped. Here we force any actors added to the
4676 // container to be relayed out.
4677 DALI_LOG_TIMER_START( NegSizeTimer1 );
4679 if( GetUseAssignedSize(Dimension::WIDTH ) )
4681 SetLayoutNegotiated( false, Dimension::WIDTH );
4683 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4685 SetLayoutNegotiated( false, Dimension::HEIGHT );
4688 // Do the negotiation
4689 NegotiateDimensions( allocatedSize );
4691 // Set the actor size
4692 SetNegotiatedSize( container );
4694 // Negotiate down to children
4695 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4697 ActorPtr child = GetChildAt( i );
4699 // Forces children that have already been laid out to be relayed out
4700 // if they have assigned size during relayout.
4701 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4703 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4704 child->SetLayoutDirty(true, Dimension::WIDTH);
4707 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4709 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4710 child->SetLayoutDirty(true, Dimension::HEIGHT);
4713 // Only relayout if required
4714 if( child->RelayoutRequired() )
4716 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4719 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4722 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4726 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4728 if( dimension & ( 1 << i ) )
4730 mRelayoutData->useAssignedSize[ i ] = use;
4736 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4738 if ( mRelayoutData )
4740 // If more than one dimension is requested, just return the first one found
4741 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4743 if( dimension & ( 1 << i ) )
4745 return mRelayoutData->useAssignedSize[ i ];
4753 void Actor::RelayoutRequest( Dimension::Type dimension )
4755 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4756 if( relayoutController )
4758 Dali::Actor self( this );
4759 relayoutController->RequestRelayout( self, dimension );
4763 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4767 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4771 void Actor::SetPreferredSize( const Vector2& size )
4773 EnsureRelayoutData();
4775 // If valid width or height, then set the resize policy to FIXED
4776 // 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,
4777 // then change to FIXED as well
4779 if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4781 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4784 if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4786 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4789 mRelayoutData->preferredSize = size;
4791 mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4796 Vector2 Actor::GetPreferredSize() const
4798 if ( mRelayoutData )
4800 return Vector2( mRelayoutData->preferredSize );
4803 return GetDefaultPreferredSize();
4806 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4808 EnsureRelayoutData();
4810 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4812 if( dimension & ( 1 << i ) )
4814 mRelayoutData->minimumSize[ i ] = size;
4821 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4823 if ( mRelayoutData )
4825 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4827 if( dimension & ( 1 << i ) )
4829 return mRelayoutData->minimumSize[ i ];
4834 return 0.0f; // Default
4837 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4839 EnsureRelayoutData();
4841 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4843 if( dimension & ( 1 << i ) )
4845 mRelayoutData->maximumSize[ i ] = size;
4852 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4854 if ( mRelayoutData )
4856 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4858 if( dimension & ( 1 << i ) )
4860 return mRelayoutData->maximumSize[ i ];
4865 return FLT_MAX; // Default
4868 Object* Actor::GetParentObject() const
4873 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4875 if( mVisible != visible )
4877 if( sendMessage == SendMessage::TRUE )
4879 // node is being used in a separate thread; queue a message to set the value & base value
4880 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4885 // Emit the signal on this actor and all its children
4886 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4890 void Actor::SetSiblingOrder( uint32_t order )
4894 ActorContainer& siblings = *(mParent->mChildren);
4895 uint32_t currentOrder = GetSiblingOrder();
4897 if( order != currentOrder )
4903 else if( order < siblings.size() -1 )
4905 if( order > currentOrder )
4907 RaiseAbove( *siblings[order] );
4911 LowerBelow( *siblings[order] );
4922 uint32_t Actor::GetSiblingOrder() const
4928 ActorContainer& siblings = *(mParent->mChildren);
4929 for( std::size_t i = 0; i < siblings.size(); ++i )
4931 if( siblings[i] == this )
4933 order = static_cast<uint32_t>( i );
4942 void Actor::RequestRebuildDepthTree()
4948 mScene->RequestRebuildDepthTree();
4957 ActorContainer& siblings = *(mParent->mChildren);
4958 if( siblings.back() != this ) // If not already at end
4960 for( std::size_t i=0; i<siblings.size(); ++i )
4962 if( siblings[i] == this )
4965 ActorPtr next = siblings[i+1];
4966 siblings[i+1] = this;
4973 Dali::Actor handle( this );
4974 mParent->mChildOrderChangedSignal.Emit( handle );
4976 RequestRebuildDepthTree();
4980 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4988 ActorContainer& siblings = *(mParent->mChildren);
4989 if( siblings.front() != this ) // If not already at beginning
4991 for( std::size_t i=1; i<siblings.size(); ++i )
4993 if( siblings[i] == this )
4995 // Swap with previous
4996 ActorPtr previous = siblings[i-1];
4997 siblings[i-1] = this;
4998 siblings[i] = previous;
5004 Dali::Actor handle( this );
5005 mParent->mChildOrderChangedSignal.Emit( handle );
5007 RequestRebuildDepthTree();
5011 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5015 void Actor::RaiseToTop()
5019 ActorContainer& siblings = *(mParent->mChildren);
5020 if( siblings.back() != this ) // If not already at end
5022 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5023 if( iter != siblings.end() )
5025 siblings.erase(iter);
5026 siblings.push_back(ActorPtr(this));
5030 Dali::Actor handle( this );
5031 mParent->mChildOrderChangedSignal.Emit( handle );
5033 RequestRebuildDepthTree();
5037 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5041 void Actor::LowerToBottom()
5045 ActorContainer& siblings = *(mParent->mChildren);
5046 if( siblings.front() != this ) // If not already at bottom,
5048 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5050 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5051 if( iter != siblings.end() )
5053 siblings.erase(iter);
5054 siblings.insert(siblings.begin(), thisPtr);
5058 Dali::Actor handle( this );
5059 mParent->mChildOrderChangedSignal.Emit( handle );
5061 RequestRebuildDepthTree();
5065 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5069 void Actor::RaiseAbove( Internal::Actor& target )
5073 ActorContainer& siblings = *(mParent->mChildren);
5074 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5076 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5078 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5079 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5080 if( thisIter < targetIter )
5082 siblings.erase(thisIter);
5083 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5084 // invalidate thisIter)
5085 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5087 siblings.insert(targetIter, thisPtr);
5090 Dali::Actor handle( this );
5091 mParent->mChildOrderChangedSignal.Emit( handle );
5093 RequestRebuildDepthTree();
5098 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5102 void Actor::LowerBelow( Internal::Actor& target )
5106 ActorContainer& siblings = *(mParent->mChildren);
5107 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5109 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5111 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5112 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5114 if( thisIter > targetIter )
5116 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5117 siblings.insert(targetIter, thisPtr);
5120 Dali::Actor handle( this );
5121 mParent->mChildOrderChangedSignal.Emit( handle );
5123 RequestRebuildDepthTree();
5128 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5132 void Actor::SetScene( Scene& scene )
5137 Scene& Actor::GetScene() const
5142 void Actor::SetInheritLayoutDirection( bool inherit )
5144 if( mInheritLayoutDirection != inherit )
5146 mInheritLayoutDirection = inherit;
5148 if( inherit && mParent )
5150 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5155 bool Actor::IsLayoutDirectionInherited() const
5157 return mInheritLayoutDirection;
5160 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5162 if( actor && ( actor->mInheritLayoutDirection || set ) )
5164 if( actor->mLayoutDirection != direction )
5166 actor->mLayoutDirection = direction;
5167 actor->EmitLayoutDirectionChangedSignal( direction );
5168 actor->RelayoutRequest();
5171 if( actor->GetChildCount() > 0 )
5173 ActorContainer& children = actor->GetChildrenInternal();
5174 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5176 InheritLayoutDirectionRecursively( *iter, direction );
5182 void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint )
5184 // node is being used in a separate thread; queue a message to set the value & base value
5185 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) );
5188 Vector2 Actor::GetUpdateSizeHint() const
5190 // node is being used in a separate thread, the value from the previous update is the same, set by user
5191 Vector3 updateSizeHint = GetNode().GetUpdateSizeHint();
5192 return Vector2( updateSizeHint.width, updateSizeHint.height );
5195 } // namespace Internal