2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/common/scene-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/animation/constraint-impl.h>
48 #include <dali/internal/event/common/projection.h>
49 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
50 #include <dali/internal/update/common/animatable-property.h>
51 #include <dali/internal/update/nodes/node-messages.h>
52 #include <dali/internal/update/nodes/node-declarations.h>
53 #include <dali/internal/update/animation/scene-graph-constraint.h>
54 #include <dali/internal/event/events/actor-gesture-data.h>
55 #include <dali/internal/common/message.h>
56 #include <dali/integration-api/debug.h>
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::PropertyBase;
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
64 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
75 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
76 inline const Vector3& GetDefaultSizeModeFactor()
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultPreferredSize()
87 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
88 inline const Vector2& GetDefaultDimensionPadding()
93 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
95 } // unnamed namespace
98 * Struct to collect relayout variables
100 struct Actor::RelayoutData
103 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
105 // Set size negotiation defaults
106 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
108 resizePolicies[ i ] = ResizePolicy::DEFAULT;
109 useAssignedSize[ i ] = false;
110 negotiatedDimensions[ i ] = 0.0f;
111 dimensionNegotiated[ i ] = false;
112 dimensionDirty[ i ] = false;
113 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
114 dimensionPadding[ i ] = GetDefaultDimensionPadding();
115 minimumSize[ i ] = 0.0f;
116 maximumSize[ i ] = FLT_MAX;
120 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
121 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
123 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
125 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
127 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
129 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
130 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
132 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
133 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
135 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
137 Vector2 preferredSize; ///< The preferred size of the actor
139 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
141 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
142 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
145 namespace // unnamed namespace
151 * We want to discourage the use of property strings (minimize string comparisons),
152 * particularly for the default properties.
153 * Name Type writable animatable constraint-input enum for index-checking
155 DALI_PROPERTY_TABLE_BEGIN
156 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
157 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
158 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
159 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
160 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
161 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
162 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
163 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
164 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
165 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
166 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
167 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
168 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
169 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
170 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
171 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
172 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
173 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
174 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
175 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
176 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
177 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
178 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
179 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
180 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
181 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
182 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
183 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
184 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
185 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
186 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
187 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
188 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
189 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
190 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
191 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
192 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
193 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
194 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
195 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
196 DALI_PROPERTY( "colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "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_TOUCHED = "touched";
229 const char* const SIGNAL_HOVERED = "hovered";
230 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
231 const char* const SIGNAL_ON_SCENE = "onScene";
232 const char* const SIGNAL_OFF_SCENE = "offScene";
233 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
234 const char* const SIGNAL_TOUCH = "touch";
235 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
236 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
237 const char* const SIGNAL_CHILD_ADDED = "childAdded";
238 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
242 const char* const ACTION_SHOW = "show";
243 const char* const ACTION_HIDE = "hide";
245 BaseHandle CreateActor()
247 return Dali::Actor::New();
250 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
252 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector4( mType, SIGNAL_ON_SCENE, &Actor::DoConnectSignal );
256 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_SCENE, &Actor::DoConnectSignal );
257 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
258 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
259 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
260 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
261 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
262 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
264 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
265 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
270 const Vector3& value;
273 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
276 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
282 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
283 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
285 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
286 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
287 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
288 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
289 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
290 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
292 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
295 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
297 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
299 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
300 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
305 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
306 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
308 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
310 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
311 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
312 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
314 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
315 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
316 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
317 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
319 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
320 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
321 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
322 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
324 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
326 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
328 uint32_t sizeIgnored = 0;
329 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
331 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
338 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
340 // Values are the same so just use the same table as anchor-point
341 return GetAnchorPointConstant( value, parentOrigin );
345 * @brief Extract a given dimension from a Vector2
347 * @param[in] values The values to extract from
348 * @param[in] dimension The dimension to extract
349 * @return Return the value for the dimension
351 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
355 case Dimension::WIDTH:
359 case Dimension::HEIGHT:
361 return values.height;
372 * @brief Extract a given dimension from a Vector3
374 * @param[in] values The values to extract from
375 * @param[in] dimension The dimension to extract
376 * @return Return the value for the dimension
378 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
380 return GetDimensionValue( values.GetVectorXY(), dimension );
384 * @brief Recursively emits the visibility-changed-signal on the actor tree.
385 * @param[in] actor The actor to emit the signal on
386 * @param[in] visible The new visibility of the actor
387 * @param[in] type Whether the actor's visible property has changed or a parent's
389 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
393 actor->EmitVisibilityChangedSignal( visible, type );
395 if( actor->GetChildCount() > 0 )
397 ActorContainer& children = actor->GetChildrenInternal();
398 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
400 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
406 } // unnamed namespace
408 ActorPtr Actor::New()
410 // pass a reference to actor, actor does not own its node
411 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
413 // Second-phase construction
419 const SceneGraph::Node* Actor::CreateNode()
421 // create node. Nodes are owned by the update manager
422 SceneGraph::Node* node = SceneGraph::Node::New();
423 OwnerPointer< SceneGraph::Node > transferOwnership( node );
424 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
426 DALI_ASSERT_ALWAYS( tls && "ThreadLocalStorage is null" );
428 AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
433 const std::string& Actor::GetName() const
438 void Actor::SetName( const std::string& name )
442 // ATTENTION: string for debug purposes is not thread safe.
443 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
446 uint32_t Actor::GetId() const
448 return GetNode().GetId();
451 bool Actor::OnScene() const
456 Dali::Layer Actor::GetLayer()
460 // Short-circuit for Layer derived actors
463 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
466 // Find the immediate Layer parent
467 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
469 if( parent->IsLayer() )
471 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
478 void Actor::Add( Actor& child )
480 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
481 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
485 mChildren = new ActorContainer;
488 Actor* const oldParent( child.mParent );
490 // child might already be ours
491 if( this != oldParent )
493 // if we already have parent, unparent us first
496 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
498 // Old parent may need to readjust to missing child
499 if( oldParent->RelayoutDependentOnChildren() )
501 oldParent->RelayoutRequest();
505 // Guard against Add() during previous OnChildRemove callback
508 // Do this first, since user callbacks from within SetParent() may need to remove child
509 mChildren->push_back( ActorPtr( &child ) );
511 // SetParent asserts that child can be added
512 child.SetParent( this );
514 // Notification for derived classes
516 EmitChildAddedSignal( child );
518 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
520 // Only put in a relayout request if there is a suitable dependency
521 if( RelayoutDependentOnChildren() )
529 void Actor::Remove( Actor& child )
531 if( (this == &child) || (!mChildren) )
533 // no children or removing itself
539 // Find the child in mChildren, and unparent it
540 ActorIter end = mChildren->end();
541 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
543 ActorPtr actor = (*iter);
545 if( actor.Get() == &child )
547 // Keep handle for OnChildRemove notification
550 // Do this first, since user callbacks from within SetParent() may need to add the child
551 mChildren->erase( iter );
553 DALI_ASSERT_DEBUG( actor->GetParent() == this );
554 actor->SetParent( NULL );
562 // Only put in a relayout request if there is a suitable dependency
563 if( RelayoutDependentOnChildren() )
569 // Notification for derived classes
570 OnChildRemove( child );
571 EmitChildRemovedSignal( child );
574 void Actor::Unparent()
578 // Remove this actor from the parent. The remove will put a relayout request in for
579 // the parent if required
580 mParent->Remove( *this );
581 // mParent is now NULL!
585 uint32_t Actor::GetChildCount() const
587 return ( NULL != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
590 ActorPtr Actor::GetChildAt( uint32_t index ) const
592 DALI_ASSERT_ALWAYS( index < GetChildCount() );
594 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
597 ActorPtr Actor::FindChildByName( const std::string& actorName )
600 if( actorName == mName )
606 ActorIter end = mChildren->end();
607 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
609 child = (*iter)->FindChildByName( actorName );
620 ActorPtr Actor::FindChildById( const uint32_t id )
629 ActorIter end = mChildren->end();
630 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
632 child = (*iter)->FindChildById( id );
643 void Actor::SetParentOrigin( const Vector3& origin )
645 // node is being used in a separate thread; queue a message to set the value & base value
646 SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
648 // Cache for event-thread access
651 // not allocated, check if different from default
652 if( ParentOrigin::DEFAULT != origin )
654 mParentOrigin = new Vector3( origin );
659 // check if different from current costs more than just set
660 *mParentOrigin = origin;
664 void Actor::SetParentOriginX( float x )
666 const Vector3& current = GetCurrentParentOrigin();
668 SetParentOrigin( Vector3( x, current.y, current.z ) );
671 void Actor::SetParentOriginY( float y )
673 const Vector3& current = GetCurrentParentOrigin();
675 SetParentOrigin( Vector3( current.x, y, current.z ) );
678 void Actor::SetParentOriginZ( float z )
680 const Vector3& current = GetCurrentParentOrigin();
682 SetParentOrigin( Vector3( current.x, current.y, z ) );
685 const Vector3& Actor::GetCurrentParentOrigin() const
687 // Cached for event-thread access
688 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
691 void Actor::SetAnchorPoint( const Vector3& anchor )
693 // node is being used in a separate thread; queue a message to set the value & base value
694 SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
696 // Cache for event-thread access
699 // not allocated, check if different from default
700 if( AnchorPoint::DEFAULT != anchor )
702 mAnchorPoint = new Vector3( anchor );
707 // check if different from current costs more than just set
708 *mAnchorPoint = anchor;
712 void Actor::SetAnchorPointX( float x )
714 const Vector3& current = GetCurrentAnchorPoint();
716 SetAnchorPoint( Vector3( x, current.y, current.z ) );
719 void Actor::SetAnchorPointY( float y )
721 const Vector3& current = GetCurrentAnchorPoint();
723 SetAnchorPoint( Vector3( current.x, y, current.z ) );
726 void Actor::SetAnchorPointZ( float z )
728 const Vector3& current = GetCurrentAnchorPoint();
730 SetAnchorPoint( Vector3( current.x, current.y, z ) );
733 const Vector3& Actor::GetCurrentAnchorPoint() const
735 // Cached for event-thread access
736 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
739 void Actor::SetPosition( float x, float y )
741 SetPosition( Vector3( x, y, 0.0f ) );
744 void Actor::SetPosition( float x, float y, float z )
746 SetPosition( Vector3( x, y, z ) );
749 void Actor::SetPosition( const Vector3& position )
751 mTargetPosition = position;
753 // node is being used in a separate thread; queue a message to set the value & base value
754 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
757 void Actor::SetX( float x )
759 mTargetPosition.x = x;
761 // node is being used in a separate thread; queue a message to set the value & base value
762 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
765 void Actor::SetY( float y )
767 mTargetPosition.y = y;
769 // node is being used in a separate thread; queue a message to set the value & base value
770 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
773 void Actor::SetZ( float z )
775 mTargetPosition.z = z;
777 // node is being used in a separate thread; queue a message to set the value & base value
778 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
781 void Actor::TranslateBy( const Vector3& distance )
783 mTargetPosition += distance;
785 // node is being used in a separate thread; queue a message to set the value & base value
786 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
789 const Vector3& Actor::GetCurrentPosition() const
791 // node is being used in a separate thread; copy the value from the previous update
792 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
795 const Vector3& Actor::GetTargetPosition() const
797 return mTargetPosition;
800 const Vector3& Actor::GetCurrentWorldPosition() const
802 // node is being used in a separate thread; copy the value from the previous update
803 return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
806 const Vector2 Actor::GetCurrentScreenPosition() const
808 if( mScene && OnScene() )
810 Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
811 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
812 worldPosition -= cameraPosition;
814 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
815 Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
816 Vector3 halfActorSize( actorSize * 0.5f );
817 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
819 return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
820 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
823 return Vector2::ZERO;
826 void Actor::SetInheritPosition( bool inherit )
828 if( mInheritPosition != inherit )
830 // non animatable so keep local copy
831 mInheritPosition = inherit;
832 SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
836 bool Actor::IsPositionInherited() const
838 return mInheritPosition;
841 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
843 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
844 normalizedAxis.Normalize();
846 Quaternion orientation( angle, normalizedAxis );
848 SetOrientation( orientation );
851 void Actor::SetOrientation( const Quaternion& orientation )
853 mTargetOrientation = orientation;
855 // node is being used in a separate thread; queue a message to set the value & base value
856 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
859 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
861 RotateBy( Quaternion(angle, axis) );
864 void Actor::RotateBy( const Quaternion& relativeRotation )
866 mTargetOrientation *= Quaternion( relativeRotation );
868 // node is being used in a separate thread; queue a message to set the value & base value
869 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
872 const Quaternion& Actor::GetCurrentOrientation() const
874 // node is being used in a separate thread; copy the value from the previous update
875 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
878 const Quaternion& Actor::GetCurrentWorldOrientation() const
880 // node is being used in a separate thread; copy the value from the previous update
881 return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
884 void Actor::SetScale( float scale )
886 SetScale( Vector3( scale, scale, scale ) );
889 void Actor::SetScale( float x, float y, float z )
891 SetScale( Vector3( x, y, z ) );
894 void Actor::SetScale( const Vector3& scale )
896 mTargetScale = scale;
898 // node is being used in a separate thread; queue a message to set the value & base value
899 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
902 void Actor::SetScaleX( float x )
906 // node is being used in a separate thread; queue a message to set the value & base value
907 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
910 void Actor::SetScaleY( float y )
914 // node is being used in a separate thread; queue a message to set the value & base value
915 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
918 void Actor::SetScaleZ( float z )
922 // node is being used in a separate thread; queue a message to set the value & base value
923 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
926 void Actor::ScaleBy(const Vector3& relativeScale)
928 mTargetScale *= relativeScale;
930 // node is being used in a separate thread; queue a message to set the value & base value
931 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
934 const Vector3& Actor::GetCurrentScale() const
936 // node is being used in a separate thread; copy the value from the previous update
937 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
940 const Vector3& Actor::GetCurrentWorldScale() const
942 // node is being used in a separate thread; copy the value from the previous update
943 return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
946 void Actor::SetInheritScale( bool inherit )
948 if( mInheritScale != inherit )
950 // non animatable so keep local copy
951 mInheritScale = inherit;
952 // node is being used in a separate thread; queue a message to set the value
953 SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
957 bool Actor::IsScaleInherited() const
959 return mInheritScale;
962 Matrix Actor::GetCurrentWorldMatrix() const
964 return GetNode().GetWorldMatrix(0);
967 void Actor::SetVisible( bool visible )
969 SetVisibleInternal( visible, SendMessage::TRUE );
972 bool Actor::IsVisible() const
974 // node is being used in a separate thread; copy the value from the previous update
975 return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
978 void Actor::SetOpacity( float opacity )
980 mTargetColor.a = opacity;
982 // node is being used in a separate thread; queue a message to set the value & base value
983 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
986 float Actor::GetCurrentOpacity() const
988 // node is being used in a separate thread; copy the value from the previous update
989 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
992 ClippingMode::Type Actor::GetClippingMode() const
994 return mClippingMode;
997 uint32_t Actor::GetSortingDepth()
1002 const Vector4& Actor::GetCurrentWorldColor() const
1004 return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1007 void Actor::SetColor( const Vector4& color )
1009 mTargetColor = color;
1011 // node is being used in a separate thread; queue a message to set the value & base value
1012 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
1015 void Actor::SetColorRed( float red )
1017 mTargetColor.r = red;
1019 // node is being used in a separate thread; queue a message to set the value & base value
1020 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
1023 void Actor::SetColorGreen( float green )
1025 mTargetColor.g = green;
1027 // node is being used in a separate thread; queue a message to set the value & base value
1028 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green );
1031 void Actor::SetColorBlue( float blue )
1033 mTargetColor.b = blue;
1035 // node is being used in a separate thread; queue a message to set the value & base value
1036 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1039 const Vector4& Actor::GetCurrentColor() const
1041 // node is being used in a separate thread; copy the value from the previous update
1042 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
1045 void Actor::SetInheritOrientation( bool inherit )
1047 if( mInheritOrientation != inherit )
1049 // non animatable so keep local copy
1050 mInheritOrientation = inherit;
1051 // node is being used in a separate thread; queue a message to set the value
1052 SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
1056 bool Actor::IsOrientationInherited() const
1058 return mInheritOrientation;
1061 void Actor::SetSizeModeFactor( const Vector3& factor )
1063 EnsureRelayoutData();
1065 mRelayoutData->sizeModeFactor = factor;
1068 const Vector3& Actor::GetSizeModeFactor() const
1070 if ( mRelayoutData )
1072 return mRelayoutData->sizeModeFactor;
1075 return GetDefaultSizeModeFactor();
1078 void Actor::SetColorMode( ColorMode colorMode )
1080 // non animatable so keep local copy
1081 mColorMode = colorMode;
1082 // node is being used in a separate thread; queue a message to set the value
1083 SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
1086 ColorMode Actor::GetColorMode() const
1088 // we have cached copy
1092 void Actor::SetSize( float width, float height )
1094 SetSize( Vector2( width, height ) );
1097 void Actor::SetSize( float width, float height, float depth )
1099 SetSize( Vector3( width, height, depth ) );
1102 void Actor::SetSize( const Vector2& size )
1104 SetSize( Vector3( size.width, size.height, 0.f ) );
1107 void Actor::SetSizeInternal( const Vector2& size )
1109 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1112 void Actor::SetSize( const Vector3& size )
1114 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1116 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1117 SetPreferredSize( size.GetVectorXY() );
1121 SetSizeInternal( size );
1125 void Actor::SetSizeInternal( const Vector3& size )
1127 // dont allow recursive loop
1128 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1129 // 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
1130 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1131 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1132 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1136 // node is being used in a separate thread; queue a message to set the value & base value
1137 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1139 // Notification for derived classes
1140 mInsideOnSizeSet = true;
1141 OnSizeSet( mTargetSize );
1142 mInsideOnSizeSet = false;
1144 // Raise a relayout request if the flag is not locked
1145 if( mRelayoutData && !mRelayoutData->insideRelayout )
1152 void Actor::SetWidth( float width )
1154 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1156 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1157 mRelayoutData->preferredSize.width = width;
1161 mTargetSize.width = width;
1163 // node is being used in a separate thread; queue a message to set the value & base value
1164 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1167 mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
1172 void Actor::SetHeight( float height )
1174 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1176 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1177 mRelayoutData->preferredSize.height = height;
1181 mTargetSize.height = height;
1183 // node is being used in a separate thread; queue a message to set the value & base value
1184 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1187 mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
1192 void Actor::SetDepth( float depth )
1194 mTargetSize.depth = depth;
1196 mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
1198 // node is being used in a separate thread; queue a message to set the value & base value
1199 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1202 Vector3 Actor::GetTargetSize() const
1204 Vector3 size = mTargetSize;
1206 if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH )
1208 // Should return animated size if size is animated
1209 size.width = mAnimatedSize.width;
1213 // Should return preferred size if size is fixed as set by SetSize
1214 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1216 size.width = GetPreferredSize().width;
1220 if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT )
1222 size.height = mAnimatedSize.height;
1226 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1228 size.height = GetPreferredSize().height;
1232 if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH )
1234 size.depth = mAnimatedSize.depth;
1240 const Vector3& Actor::GetCurrentSize() const
1242 // node is being used in a separate thread; copy the value from the previous update
1243 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1246 Vector3 Actor::GetNaturalSize() const
1248 // It is up to deriving classes to return the appropriate natural size
1249 return Vector3( 0.0f, 0.0f, 0.0f );
1252 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1254 EnsureRelayoutData();
1256 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1257 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1259 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1261 if( dimension & ( 1 << i ) )
1263 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1265 mRelayoutData->useAssignedSize[ i ] = true;
1269 mRelayoutData->resizePolicies[ i ] = policy;
1270 mRelayoutData->useAssignedSize[ i ] = false;
1275 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1277 if( dimension & Dimension::WIDTH )
1279 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1282 if( dimension & Dimension::HEIGHT )
1284 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1288 // If calling SetResizePolicy, assume we want relayout enabled
1289 SetRelayoutEnabled( true );
1291 // If the resize policy is set to be FIXED, the preferred size
1292 // should be overrided by the target size. Otherwise the target
1293 // size should be overrided by the preferred size.
1295 if( dimension & Dimension::WIDTH )
1297 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1299 mRelayoutData->preferredSize.width = mTargetSize.width;
1301 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1303 mTargetSize.width = mRelayoutData->preferredSize.width;
1307 if( dimension & Dimension::HEIGHT )
1309 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1311 mRelayoutData->preferredSize.height = mTargetSize.height;
1313 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1315 mTargetSize.height = mRelayoutData->preferredSize.height;
1319 OnSetResizePolicy( policy, dimension );
1321 // Trigger relayout on this control
1325 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1327 if ( mRelayoutData )
1329 // If more than one dimension is requested, just return the first one found
1330 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1332 if( ( dimension & ( 1 << i ) ) )
1334 if( mRelayoutData->useAssignedSize[ i ] )
1336 return ResizePolicy::USE_ASSIGNED_SIZE;
1340 return mRelayoutData->resizePolicies[ i ];
1346 return ResizePolicy::DEFAULT;
1349 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1351 EnsureRelayoutData();
1353 mRelayoutData->sizeSetPolicy = policy;
1355 // Trigger relayout on this control
1359 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1361 if ( mRelayoutData )
1363 return mRelayoutData->sizeSetPolicy;
1366 return DEFAULT_SIZE_SCALE_POLICY;
1369 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1371 EnsureRelayoutData();
1373 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1375 if( dimension & ( 1 << i ) )
1377 mRelayoutData->dimensionDependencies[ i ] = dependency;
1382 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1384 if ( mRelayoutData )
1386 // If more than one dimension is requested, just return the first one found
1387 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1389 if( ( dimension & ( 1 << i ) ) )
1391 return mRelayoutData->dimensionDependencies[ i ];
1396 return Dimension::ALL_DIMENSIONS; // Default
1399 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1401 // If relayout data has not been allocated yet and the client is requesting
1402 // to disable it, do nothing
1403 if( mRelayoutData || relayoutEnabled )
1405 EnsureRelayoutData();
1407 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1409 mRelayoutData->relayoutEnabled = relayoutEnabled;
1413 bool Actor::IsRelayoutEnabled() const
1415 // Assume that if relayout data has not been allocated yet then
1416 // relayout is disabled
1417 return mRelayoutData && mRelayoutData->relayoutEnabled;
1420 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1422 EnsureRelayoutData();
1424 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1426 if( dimension & ( 1 << i ) )
1428 mRelayoutData->dimensionDirty[ i ] = dirty;
1433 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1435 if ( mRelayoutData )
1437 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1439 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1449 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1451 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1454 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1456 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1459 uint32_t Actor::AddRenderer( Renderer& renderer )
1463 mRenderers = new RendererContainer;
1466 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1467 RendererPtr rendererPtr = RendererPtr( &renderer );
1468 mRenderers->push_back( rendererPtr );
1469 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1473 uint32_t Actor::GetRendererCount() const
1475 uint32_t rendererCount(0);
1478 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1481 return rendererCount;
1484 RendererPtr Actor::GetRendererAt( uint32_t index )
1486 RendererPtr renderer;
1487 if( index < GetRendererCount() )
1489 renderer = ( *mRenderers )[ index ];
1495 void Actor::RemoveRenderer( Renderer& renderer )
1499 RendererIter end = mRenderers->end();
1500 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1502 if( (*iter).Get() == &renderer )
1504 mRenderers->erase( iter );
1505 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1512 void Actor::RemoveRenderer( uint32_t index )
1514 if( index < GetRendererCount() )
1516 RendererPtr renderer = ( *mRenderers )[ index ];
1517 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1518 mRenderers->erase( mRenderers->begin()+index );
1522 bool Actor::IsOverlay() const
1524 return ( DrawMode::OVERLAY_2D == mDrawMode );
1527 void Actor::SetDrawMode( DrawMode::Type drawMode )
1529 // this flag is not animatable so keep the value
1530 mDrawMode = drawMode;
1532 // node is being used in a separate thread; queue a message to set the value
1533 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1536 DrawMode::Type Actor::GetDrawMode() const
1541 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1543 // only valid when on-stage
1544 if( mScene && OnScene() )
1546 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1548 Vector2 converted( screenX, screenY );
1550 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1551 uint32_t taskCount = taskList.GetTaskCount();
1552 for( uint32_t i = taskCount; i > 0; --i )
1554 RenderTaskPtr task = taskList.GetTask( i - 1 );
1555 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1557 // found a task where this conversion was ok so return
1565 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1567 bool retval = false;
1568 // only valid when on-stage
1571 CameraActor* camera = renderTask.GetCameraActor();
1575 renderTask.GetViewport( viewport );
1577 // need to translate coordinates to render tasks coordinate space
1578 Vector2 converted( screenX, screenY );
1579 if( renderTask.TranslateCoordinates( converted ) )
1581 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1588 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1590 // Early-out if not on stage
1596 // Get the ModelView matrix
1598 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1600 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1601 Matrix invertedMvp( false/*don't init*/);
1602 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1603 bool success = invertedMvp.Invert();
1605 // Convert to GL coordinates
1606 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1611 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1618 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1624 if( XyPlaneIntersect( nearPos, farPos, local ) )
1626 Vector3 size = GetCurrentSize();
1627 localX = local.x + size.x * 0.5f;
1628 localY = local.y + size.y * 0.5f;
1639 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1642 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1644 Mathematical Formulation
1646 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1648 ( p - c ) dot ( p - c ) = r^2
1650 Given a ray with a point of origin 'o', and a direction vector 'd':
1652 ray(t) = o + td, t >= 0
1654 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1656 (o + td - c ) dot ( o + td - c ) = r^2
1658 To solve for t we first expand the above into a more recognisable quadratic equation form
1660 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1669 B = 2( o - c ) dot d
1670 C = ( o - c ) dot ( o - c ) - r^2
1672 which can be solved using a standard quadratic formula.
1674 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1676 Practical Simplification
1678 In a renderer, we often differentiate between world space and object space. In the object space
1679 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1680 into object space, the mathematical solution presented above can be simplified significantly.
1682 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1686 and we can find the t at which the (transformed) ray intersects the sphere by
1688 ( o + td ) dot ( o + td ) = r^2
1690 According to the reasoning above, we expand the above quadratic equation into the general form
1694 which now has coefficients:
1701 // Early-out if not on stage
1707 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1709 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1710 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1711 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1713 // Compute the radius is not needed, square radius it's enough.
1714 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1716 // Scale the sphere.
1717 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1719 const float width = size.width * scale.width;
1720 const float height = size.height * scale.height;
1722 float squareSphereRadius = 0.5f * ( width * width + height * height );
1724 float a = rayDir.Dot( rayDir ); // a
1725 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1726 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1728 return ( b2 * b2 - a * c ) >= 0.f;
1731 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1737 // Transforms the ray to the local reference system.
1738 // Calculate the inverse of Model matrix
1739 Matrix invModelMatrix( false/*don't init*/);
1741 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1742 invModelMatrix = GetNode().GetWorldMatrix(0);
1743 invModelMatrix.Invert();
1745 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1746 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1748 // Test with the actor's XY plane (Normal = 0 0 1 1).
1750 float a = -rayOriginLocal.z;
1751 float b = rayDirLocal.z;
1753 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1755 // Ray travels distance * rayDirLocal to intersect with plane.
1758 const Vector3& size = GetNode().GetSize( bufferIndex );
1760 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1761 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1763 // Test with the actor's geometry.
1764 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1771 void Actor::SetLeaveRequired( bool required )
1773 mLeaveRequired = required;
1776 bool Actor::GetLeaveRequired() const
1778 return mLeaveRequired;
1781 void Actor::SetKeyboardFocusable( bool focusable )
1783 mKeyboardFocusable = focusable;
1786 bool Actor::IsKeyboardFocusable() const
1788 return mKeyboardFocusable;
1791 bool Actor::GetTouchRequired() const
1793 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1796 bool Actor::GetHoverRequired() const
1798 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1801 bool Actor::GetWheelEventRequired() const
1803 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1806 bool Actor::IsHittable() const
1808 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1811 ActorGestureData& Actor::GetGestureData()
1813 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1814 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1815 if( NULL == mGestureData )
1817 mGestureData = new ActorGestureData;
1819 return *mGestureData;
1822 bool Actor::IsGestureRequred( DevelGesture::Type type ) const
1824 return mGestureData && mGestureData->IsGestureRequred( type );
1827 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1829 bool consumed = false;
1831 if( !mTouchSignal.Empty() )
1833 Dali::Actor handle( this );
1834 consumed = mTouchSignal.Emit( handle, touch );
1837 if( !mTouchedSignal.Empty() )
1839 Dali::Actor handle( this );
1840 consumed |= mTouchedSignal.Emit( handle, event );
1845 // Notification for derived classes
1846 consumed = OnTouchEvent( event ); // TODO
1852 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1854 bool consumed = false;
1856 if( !mHoveredSignal.Empty() )
1858 Dali::Actor handle( this );
1859 consumed = mHoveredSignal.Emit( handle, event );
1864 // Notification for derived classes
1865 consumed = OnHoverEvent( event );
1871 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1873 bool consumed = false;
1875 if( !mWheelEventSignal.Empty() )
1877 Dali::Actor handle( this );
1878 consumed = mWheelEventSignal.Emit( handle, event );
1883 // Notification for derived classes
1884 consumed = OnWheelEvent( event );
1890 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1892 if( ! mVisibilityChangedSignal.Empty() )
1894 Dali::Actor handle( this );
1895 mVisibilityChangedSignal.Emit( handle, visible, type );
1899 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1901 if( ! mLayoutDirectionChangedSignal.Empty() )
1903 Dali::Actor handle( this );
1904 mLayoutDirectionChangedSignal.Emit( handle, type );
1908 void Actor::EmitChildAddedSignal( Actor& child )
1910 if( ! mChildAddedSignal.Empty() )
1912 Dali::Actor handle( &child );
1913 mChildAddedSignal.Emit( handle );
1917 void Actor::EmitChildRemovedSignal( Actor& child )
1919 if( ! mChildRemovedSignal.Empty() )
1921 Dali::Actor handle( &child );
1922 mChildRemovedSignal.Emit( handle );
1926 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1928 return mTouchedSignal;
1931 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1933 return mTouchSignal;
1936 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1938 return mHoveredSignal;
1941 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1943 return mWheelEventSignal;
1946 Dali::Actor::OnSceneSignalType& Actor::OnSceneSignal()
1948 return mOnSceneSignal;
1951 Dali::Actor::OffSceneSignalType& Actor::OffSceneSignal()
1953 return mOffSceneSignal;
1956 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1958 return mOnRelayoutSignal;
1961 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1963 return mVisibilityChangedSignal;
1966 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1968 return mLayoutDirectionChangedSignal;
1971 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1973 return mChildAddedSignal;
1976 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1978 return mChildRemovedSignal;
1981 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1983 return mChildOrderChangedSignal;
1986 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1988 bool connected( true );
1989 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1991 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1993 actor->TouchedSignal().Connect( tracker, functor );
1995 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1997 actor->HoveredSignal().Connect( tracker, functor );
1999 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2001 actor->WheelEventSignal().Connect( tracker, functor );
2003 else if( 0 == signalName.compare( SIGNAL_ON_SCENE ) )
2005 actor->OnSceneSignal().Connect( tracker, functor );
2007 else if( 0 == signalName.compare( SIGNAL_OFF_SCENE ) )
2009 actor->OffSceneSignal().Connect( tracker, functor );
2011 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2013 actor->OnRelayoutSignal().Connect( tracker, functor );
2015 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2017 actor->TouchSignal().Connect( tracker, functor );
2019 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
2021 actor->VisibilityChangedSignal().Connect( tracker, functor );
2023 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2025 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2027 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2029 actor->ChildAddedSignal().Connect( tracker, functor );
2031 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2033 actor->ChildRemovedSignal().Connect( tracker, functor );
2037 // signalName does not match any signal
2044 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2050 mParentOrigin( NULL ),
2051 mAnchorPoint( NULL ),
2052 mRelayoutData( NULL ),
2053 mGestureData( NULL ),
2057 mWheelEventSignal(),
2060 mOnRelayoutSignal(),
2061 mVisibilityChangedSignal(),
2062 mLayoutDirectionChangedSignal(),
2063 mChildAddedSignal(),
2064 mChildRemovedSignal(),
2065 mChildOrderChangedSignal(),
2066 mTargetOrientation( Quaternion::IDENTITY ),
2067 mTargetColor( Color::WHITE ),
2068 mTargetSize( Vector3::ZERO ),
2069 mTargetPosition( Vector3::ZERO ),
2070 mTargetScale( Vector3::ONE ),
2071 mAnimatedSize( Vector3::ZERO ),
2075 mUseAnimatedSize( AnimatedSizeFlag::CLEAR ),
2076 mIsRoot( ROOT_LAYER == derivedType ),
2077 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2078 mIsOnScene( false ),
2080 mLeaveRequired( false ),
2081 mKeyboardFocusable( false ),
2082 mDerivedRequiresTouch( false ),
2083 mDerivedRequiresHover( false ),
2084 mDerivedRequiresWheelEvent( false ),
2085 mOnSceneSignalled( false ),
2086 mInsideOnSizeSet( false ),
2087 mInheritPosition( true ),
2088 mInheritOrientation( true ),
2089 mInheritScale( true ),
2090 mPositionUsesAnchorPoint( true ),
2092 mInheritLayoutDirection( true ),
2093 mCaptureAllTouchAfterStart( false ),
2094 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2095 mDrawMode( DrawMode::NORMAL ),
2096 mColorMode( Node::DEFAULT_COLOR_MODE ),
2097 mClippingMode( ClippingMode::DISABLED )
2101 void Actor::Initialize()
2105 GetEventThreadServices().RegisterObject( this );
2110 // Remove mParent pointers from children even if we're destroying core,
2111 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2114 ActorConstIter endIter = mChildren->end();
2115 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2117 (*iter)->SetParent( NULL );
2123 // Guard to allow handle destruction after Core has been destroyed
2124 if( EventThreadServices::IsCoreRunning() )
2126 // Root layer will destroy its node in its own destructor
2129 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2131 GetEventThreadServices().UnregisterObject( this );
2135 // Cleanup optional gesture data
2136 delete mGestureData;
2138 // Cleanup optional parent origin and anchor
2139 delete mParentOrigin;
2140 delete mAnchorPoint;
2142 // Delete optional relayout data
2143 delete mRelayoutData;
2146 void Actor::ConnectToScene( uint32_t parentDepth )
2148 // This container is used instead of walking the Actor hierarchy.
2149 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
2150 ActorContainer connectionList;
2154 mScene->RequestRebuildDepthTree();
2157 // This stage is atomic i.e. not interrupted by user callbacks.
2158 RecursiveConnectToScene( connectionList, parentDepth + 1 );
2160 // Notify applications about the newly connected actors.
2161 const ActorIter endIter = connectionList.end();
2162 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2164 (*iter)->NotifyStageConnection();
2170 void Actor::RecursiveConnectToScene( ActorContainer& connectionList, uint32_t depth )
2172 DALI_ASSERT_ALWAYS( !OnScene() );
2175 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2177 ConnectToSceneGraph();
2179 // Notification for internal derived classes
2180 OnSceneConnectionInternal();
2182 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2183 connectionList.push_back( ActorPtr( this ) );
2185 // Recursively connect children
2188 ActorConstIter endIter = mChildren->end();
2189 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2191 (*iter)->SetScene( *mScene );
2192 (*iter)->RecursiveConnectToScene( connectionList, depth + 1 );
2198 * This method is called when the Actor is connected to the Stage.
2199 * The parent must have added its Node to the scene-graph.
2200 * The child must connect its Node to the parent's Node.
2201 * This is recursive; the child calls ConnectToScene() for its children.
2203 void Actor::ConnectToSceneGraph()
2205 DALI_ASSERT_DEBUG( mParent != NULL);
2207 // Reparent Node in next Update
2208 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2210 // Request relayout on all actors that are added to the scenegraph
2213 // Notification for Object::Observers
2217 void Actor::NotifyStageConnection()
2219 // Actors can be removed (in a callback), before the on-stage stage is reported.
2220 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
2221 if( OnScene() && !mOnSceneSignalled )
2223 // Notification for external (CustomActor) derived classes
2224 OnSceneConnectionExternal( mDepth );
2226 if( !mOnSceneSignal.Empty() )
2228 Dali::Actor handle( this );
2229 mOnSceneSignal.Emit( handle );
2232 // Guard against Remove during callbacks
2235 mOnSceneSignalled = true; // signal required next time Actor is removed
2240 void Actor::DisconnectFromStage()
2242 // This container is used instead of walking the Actor hierachy.
2243 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
2244 ActorContainer disconnectionList;
2248 mScene->RequestRebuildDepthTree();
2251 // This stage is atomic i.e. not interrupted by user callbacks
2252 RecursiveDisconnectFromStage( disconnectionList );
2254 // Notify applications about the newly disconnected actors.
2255 const ActorIter endIter = disconnectionList.end();
2256 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2258 (*iter)->NotifyStageDisconnection();
2262 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2264 // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
2267 // Recursively disconnect children
2270 ActorConstIter endIter = mChildren->end();
2271 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2273 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2277 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2278 disconnectionList.push_back( ActorPtr( this ) );
2280 // Notification for internal derived classes
2281 OnSceneDisconnectionInternal();
2283 DisconnectFromSceneGraph();
2287 * This method is called by an actor or its parent, before a node removal message is sent.
2288 * This is recursive; the child calls DisconnectFromStage() for its children.
2290 void Actor::DisconnectFromSceneGraph()
2292 // Notification for Object::Observers
2293 OnSceneObjectRemove();
2296 void Actor::NotifyStageDisconnection()
2298 // Actors can be added (in a callback), before the off-stage state is reported.
2299 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
2300 // only do this step if there is a stage, i.e. Core is not being shut down
2301 if ( EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled )
2303 // Notification for external (CustomeActor) derived classes
2304 OnSceneDisconnectionExternal();
2306 if( !mOffSceneSignal.Empty() )
2308 Dali::Actor handle( this );
2309 mOffSceneSignal.Emit( handle );
2312 // Guard against Add during callbacks
2315 mOnSceneSignalled = false; // signal required next time Actor is added
2320 bool Actor::IsNodeConnected() const
2322 bool connected( false );
2326 if( IsRoot() || GetNode().GetParent() )
2335 // This method initiates traversal of the actor tree using depth-first
2336 // traversal to set a depth index based on traversal order. It sends a
2337 // single message to update manager to update all the actor's nodes in
2338 // this tree with the depth index. The sceneGraphNodeDepths vector's
2339 // elements are ordered by depth, and could be used to reduce sorting
2340 // in the update thread.
2341 void Actor::RebuildDepthTree()
2343 DALI_LOG_TIMER_START(depthTimer);
2345 // Vector of scene-graph nodes and their depths to send to UpdateManager
2346 // in a single message
2347 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2349 int32_t depthIndex = 1;
2350 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2352 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2353 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2356 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2358 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2359 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2361 // Create/add to children of this node
2364 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2366 Actor* childActor = (*it).Get();
2368 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2373 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2377 case Dali::Actor::Property::PARENT_ORIGIN:
2379 Property::Type type = property.GetType();
2380 if( type == Property::VECTOR3 )
2382 SetParentOrigin( property.Get< Vector3 >() );
2384 else if ( type == Property::STRING )
2386 std::string parentOriginString;
2387 property.Get( parentOriginString );
2388 Vector3 parentOrigin;
2389 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2391 SetParentOrigin( parentOrigin );
2397 case Dali::Actor::Property::PARENT_ORIGIN_X:
2399 SetParentOriginX( property.Get< float >() );
2403 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2405 SetParentOriginY( property.Get< float >() );
2409 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2411 SetParentOriginZ( property.Get< float >() );
2415 case Dali::Actor::Property::ANCHOR_POINT:
2417 Property::Type type = property.GetType();
2418 if( type == Property::VECTOR3 )
2420 SetAnchorPoint( property.Get< Vector3 >() );
2422 else if ( type == Property::STRING )
2424 std::string anchorPointString;
2425 property.Get( anchorPointString );
2427 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2429 SetAnchorPoint( anchor );
2435 case Dali::Actor::Property::ANCHOR_POINT_X:
2437 SetAnchorPointX( property.Get< float >() );
2441 case Dali::Actor::Property::ANCHOR_POINT_Y:
2443 SetAnchorPointY( property.Get< float >() );
2447 case Dali::Actor::Property::ANCHOR_POINT_Z:
2449 SetAnchorPointZ( property.Get< float >() );
2453 case Dali::Actor::Property::SIZE:
2455 Property::Type type = property.GetType();
2456 if( type == Property::VECTOR2 )
2458 SetSize( property.Get< Vector2 >() );
2460 else if ( type == Property::VECTOR3 )
2462 SetSize( property.Get< Vector3 >() );
2467 case Dali::Actor::Property::SIZE_WIDTH:
2469 SetWidth( property.Get< float >() );
2473 case Dali::Actor::Property::SIZE_HEIGHT:
2475 SetHeight( property.Get< float >() );
2479 case Dali::Actor::Property::SIZE_DEPTH:
2481 SetDepth( property.Get< float >() );
2485 case Dali::Actor::Property::POSITION:
2487 Property::Type type = property.GetType();
2488 if( type == Property::VECTOR2 )
2490 Vector2 position = property.Get< Vector2 >();
2491 SetPosition( Vector3( position.x, position.y, 0.0f ) );
2493 else if ( type == Property::VECTOR3 )
2495 SetPosition( property.Get< Vector3 >() );
2500 case Dali::Actor::Property::POSITION_X:
2502 SetX( property.Get< float >() );
2506 case Dali::Actor::Property::POSITION_Y:
2508 SetY( property.Get< float >() );
2512 case Dali::Actor::Property::POSITION_Z:
2514 SetZ( property.Get< float >() );
2518 case Dali::Actor::Property::ORIENTATION:
2520 SetOrientation( property.Get< Quaternion >() );
2524 case Dali::Actor::Property::SCALE:
2526 Property::Type type = property.GetType();
2527 if( type == Property::FLOAT )
2529 float scale = property.Get< float >();
2530 SetScale( scale, scale, scale );
2532 else if ( type == Property::VECTOR3 )
2534 SetScale( property.Get< Vector3 >() );
2539 case Dali::Actor::Property::SCALE_X:
2541 SetScaleX( property.Get< float >() );
2545 case Dali::Actor::Property::SCALE_Y:
2547 SetScaleY( property.Get< float >() );
2551 case Dali::Actor::Property::SCALE_Z:
2553 SetScaleZ( property.Get< float >() );
2557 case Dali::Actor::Property::VISIBLE:
2559 SetVisible( property.Get< bool >() );
2563 case Dali::Actor::Property::COLOR:
2565 Property::Type type = property.GetType();
2566 if( type == Property::VECTOR3 )
2568 Vector3 color = property.Get< Vector3 >();
2569 SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2571 else if( type == Property::VECTOR4 )
2573 SetColor( property.Get< Vector4 >() );
2578 case Dali::Actor::Property::COLOR_RED:
2580 SetColorRed( property.Get< float >() );
2584 case Dali::Actor::Property::COLOR_GREEN:
2586 SetColorGreen( property.Get< float >() );
2590 case Dali::Actor::Property::COLOR_BLUE:
2592 SetColorBlue( property.Get< float >() );
2596 case Dali::Actor::Property::COLOR_ALPHA:
2597 case Dali::Actor::Property::OPACITY:
2600 if( property.Get( value ) )
2602 SetOpacity( value );
2607 case Dali::Actor::Property::NAME:
2609 SetName( property.Get< std::string >() );
2613 case Dali::Actor::Property::SENSITIVE:
2615 SetSensitive( property.Get< bool >() );
2619 case Dali::Actor::Property::LEAVE_REQUIRED:
2621 SetLeaveRequired( property.Get< bool >() );
2625 case Dali::Actor::Property::INHERIT_POSITION:
2627 SetInheritPosition( property.Get< bool >() );
2631 case Dali::Actor::Property::INHERIT_ORIENTATION:
2633 SetInheritOrientation( property.Get< bool >() );
2637 case Dali::Actor::Property::INHERIT_SCALE:
2639 SetInheritScale( property.Get< bool >() );
2643 case Dali::Actor::Property::COLOR_MODE:
2645 ColorMode mode = mColorMode;
2646 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2648 SetColorMode( mode );
2653 case Dali::Actor::Property::DRAW_MODE:
2655 DrawMode::Type mode = mDrawMode;
2656 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2658 SetDrawMode( mode );
2663 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2665 SetSizeModeFactor( property.Get< Vector3 >() );
2669 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2671 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2672 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2674 SetResizePolicy( type, Dimension::WIDTH );
2679 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2681 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2682 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2684 SetResizePolicy( type, Dimension::HEIGHT );
2689 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2691 SizeScalePolicy::Type type = GetSizeScalePolicy();
2692 if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2694 SetSizeScalePolicy( type );
2699 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2701 if( property.Get< bool >() )
2703 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2708 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2710 if( property.Get< bool >() )
2712 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2717 case Dali::Actor::Property::PADDING:
2719 Vector4 padding = property.Get< Vector4 >();
2720 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2721 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2725 case Dali::Actor::Property::MINIMUM_SIZE:
2727 Vector2 size = property.Get< Vector2 >();
2728 SetMinimumSize( size.x, Dimension::WIDTH );
2729 SetMinimumSize( size.y, Dimension::HEIGHT );
2733 case Dali::Actor::Property::MAXIMUM_SIZE:
2735 Vector2 size = property.Get< Vector2 >();
2736 SetMaximumSize( size.x, Dimension::WIDTH );
2737 SetMaximumSize( size.y, Dimension::HEIGHT );
2741 case Dali::DevelActor::Property::SIBLING_ORDER:
2745 if( property.Get( value ) )
2747 SetSiblingOrder( value );
2752 case Dali::Actor::Property::CLIPPING_MODE:
2754 ClippingMode::Type convertedValue = mClippingMode;
2755 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2757 mClippingMode = convertedValue;
2758 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2763 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
2766 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2768 mPositionUsesAnchorPoint = value;
2769 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2774 case Dali::Actor::Property::LAYOUT_DIRECTION:
2776 Dali::LayoutDirection::Type direction = mLayoutDirection;
2777 mInheritLayoutDirection = false;
2779 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2781 InheritLayoutDirectionRecursively( this, direction, true );
2786 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2789 if( property.Get( value ) )
2791 SetInheritLayoutDirection( value );
2796 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
2799 if( property.Get( value ) )
2801 SetKeyboardFocusable( value );
2806 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
2808 SetUpdateSizeHint( property.Get< Vector2 >() );
2812 case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START:
2814 bool boolValue = false;
2815 if ( property.Get( boolValue ) )
2817 mCaptureAllTouchAfterStart = boolValue;
2824 // this can happen in the case of a non-animatable default property so just do nothing
2830 // TODO: This method needs to be removed
2831 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2833 switch( entry.GetType() )
2835 case Property::BOOLEAN:
2837 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2838 DALI_ASSERT_DEBUG( NULL != property );
2840 // property is being used in a separate thread; queue a message to set the property
2841 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2846 case Property::INTEGER:
2848 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2849 DALI_ASSERT_DEBUG( NULL != property );
2851 // property is being used in a separate thread; queue a message to set the property
2852 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2857 case Property::FLOAT:
2859 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2860 DALI_ASSERT_DEBUG( NULL != property );
2862 // property is being used in a separate thread; queue a message to set the property
2863 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2868 case Property::VECTOR2:
2870 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2871 DALI_ASSERT_DEBUG( NULL != property );
2873 // property is being used in a separate thread; queue a message to set the property
2874 if(entry.componentIndex == 0)
2876 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2878 else if(entry.componentIndex == 1)
2880 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2884 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2890 case Property::VECTOR3:
2892 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2893 DALI_ASSERT_DEBUG( NULL != property );
2895 // property is being used in a separate thread; queue a message to set the property
2896 if(entry.componentIndex == 0)
2898 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2900 else if(entry.componentIndex == 1)
2902 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2904 else if(entry.componentIndex == 2)
2906 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2910 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2916 case Property::VECTOR4:
2918 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2919 DALI_ASSERT_DEBUG( NULL != property );
2921 // property is being used in a separate thread; queue a message to set the property
2922 if(entry.componentIndex == 0)
2924 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2926 else if(entry.componentIndex == 1)
2928 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2930 else if(entry.componentIndex == 2)
2932 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2934 else if(entry.componentIndex == 3)
2936 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2940 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2946 case Property::ROTATION:
2948 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2949 DALI_ASSERT_DEBUG( NULL != property );
2951 // property is being used in a separate thread; queue a message to set the property
2952 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2957 case Property::MATRIX:
2959 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2960 DALI_ASSERT_DEBUG( NULL != property );
2962 // property is being used in a separate thread; queue a message to set the property
2963 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2968 case Property::MATRIX3:
2970 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2971 DALI_ASSERT_DEBUG( NULL != property );
2973 // property is being used in a separate thread; queue a message to set the property
2974 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2981 // nothing to do for other types
2986 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2988 Property::Value value;
2990 if( ! GetCachedPropertyValue( index, value ) )
2992 // If property value is not stored in the event-side, then it must be a scene-graph only property
2993 GetCurrentPropertyValue( index, value );
2999 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3001 Property::Value value;
3003 if( ! GetCurrentPropertyValue( index, value ) )
3005 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3006 GetCachedPropertyValue( index, value );
3012 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3014 switch( animationType )
3017 case Animation::BETWEEN:
3021 case Dali::Actor::Property::SIZE:
3023 if( value.Get( mTargetSize ) )
3025 mAnimatedSize = mTargetSize;
3026 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3028 // Notify deriving classes
3029 OnSizeAnimation( animation, mTargetSize );
3034 case Dali::Actor::Property::SIZE_WIDTH:
3036 if( value.Get( mTargetSize.width ) )
3038 mAnimatedSize.width = mTargetSize.width;
3039 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3041 // Notify deriving classes
3042 OnSizeAnimation( animation, mTargetSize );
3047 case Dali::Actor::Property::SIZE_HEIGHT:
3049 if( value.Get( mTargetSize.height ) )
3051 mAnimatedSize.height = mTargetSize.height;
3052 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3054 // Notify deriving classes
3055 OnSizeAnimation( animation, mTargetSize );
3060 case Dali::Actor::Property::SIZE_DEPTH:
3062 if( value.Get( mTargetSize.depth ) )
3064 mAnimatedSize.depth = mTargetSize.depth;
3065 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3067 // Notify deriving classes
3068 OnSizeAnimation( animation, mTargetSize );
3073 case Dali::Actor::Property::POSITION:
3075 value.Get( mTargetPosition );
3079 case Dali::Actor::Property::POSITION_X:
3081 value.Get( mTargetPosition.x );
3085 case Dali::Actor::Property::POSITION_Y:
3087 value.Get( mTargetPosition.y );
3091 case Dali::Actor::Property::POSITION_Z:
3093 value.Get( mTargetPosition.z );
3097 case Dali::Actor::Property::ORIENTATION:
3099 value.Get( mTargetOrientation );
3103 case Dali::Actor::Property::SCALE:
3105 value.Get( mTargetScale );
3109 case Dali::Actor::Property::SCALE_X:
3111 value.Get( mTargetScale.x );
3115 case Dali::Actor::Property::SCALE_Y:
3117 value.Get( mTargetScale.y );
3121 case Dali::Actor::Property::SCALE_Z:
3123 value.Get( mTargetScale.z );
3127 case Dali::Actor::Property::VISIBLE:
3129 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3133 case Dali::Actor::Property::COLOR:
3135 value.Get( mTargetColor );
3139 case Dali::Actor::Property::COLOR_RED:
3141 value.Get( mTargetColor.r );
3145 case Dali::Actor::Property::COLOR_GREEN:
3147 value.Get( mTargetColor.g );
3151 case Dali::Actor::Property::COLOR_BLUE:
3153 value.Get( mTargetColor.b );
3157 case Dali::Actor::Property::COLOR_ALPHA:
3158 case Dali::Actor::Property::OPACITY:
3160 value.Get( mTargetColor.a );
3166 // Not an animatable property. Do nothing.
3177 case Dali::Actor::Property::SIZE:
3179 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3181 mAnimatedSize = mTargetSize;
3182 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3184 // Notify deriving classes
3185 OnSizeAnimation( animation, mTargetSize );
3190 case Dali::Actor::Property::SIZE_WIDTH:
3192 if( AdjustValue< float >( mTargetSize.width, value ) )
3194 mAnimatedSize.width = mTargetSize.width;
3195 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3197 // Notify deriving classes
3198 OnSizeAnimation( animation, mTargetSize );
3203 case Dali::Actor::Property::SIZE_HEIGHT:
3205 if( AdjustValue< float >( mTargetSize.height, value ) )
3207 mAnimatedSize.height = mTargetSize.height;
3208 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3210 // Notify deriving classes
3211 OnSizeAnimation( animation, mTargetSize );
3216 case Dali::Actor::Property::SIZE_DEPTH:
3218 if( AdjustValue< float >( mTargetSize.depth, value ) )
3220 mAnimatedSize.depth = mTargetSize.depth;
3221 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3223 // Notify deriving classes
3224 OnSizeAnimation( animation, mTargetSize );
3229 case Dali::Actor::Property::POSITION:
3231 AdjustValue< Vector3 >( mTargetPosition, value );
3235 case Dali::Actor::Property::POSITION_X:
3237 AdjustValue< float >( mTargetPosition.x, value );
3241 case Dali::Actor::Property::POSITION_Y:
3243 AdjustValue< float >( mTargetPosition.y, value );
3247 case Dali::Actor::Property::POSITION_Z:
3249 AdjustValue< float >( mTargetPosition.z, value );
3253 case Dali::Actor::Property::ORIENTATION:
3255 Quaternion relativeValue;
3256 if( value.Get( relativeValue ) )
3258 mTargetOrientation *= relativeValue;
3263 case Dali::Actor::Property::SCALE:
3265 AdjustValue< Vector3 >( mTargetScale, value );
3269 case Dali::Actor::Property::SCALE_X:
3271 AdjustValue< float >( mTargetScale.x, value );
3275 case Dali::Actor::Property::SCALE_Y:
3277 AdjustValue< float >( mTargetScale.y, value );
3281 case Dali::Actor::Property::SCALE_Z:
3283 AdjustValue< float >( mTargetScale.z, value );
3287 case Dali::Actor::Property::VISIBLE:
3289 bool relativeValue = false;
3290 if( value.Get( relativeValue ) )
3292 bool visible = mVisible || relativeValue;
3293 SetVisibleInternal( visible, SendMessage::FALSE );
3298 case Dali::Actor::Property::COLOR:
3300 AdjustValue< Vector4 >( mTargetColor, value );
3304 case Dali::Actor::Property::COLOR_RED:
3306 AdjustValue< float >( mTargetColor.r, value );
3310 case Dali::Actor::Property::COLOR_GREEN:
3312 AdjustValue< float >( mTargetColor.g, value );
3316 case Dali::Actor::Property::COLOR_BLUE:
3318 AdjustValue< float >( mTargetColor.b, value );
3322 case Dali::Actor::Property::COLOR_ALPHA:
3323 case Dali::Actor::Property::OPACITY:
3325 AdjustValue< float >( mTargetColor.a, value );
3331 // Not an animatable property. Do nothing.
3340 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3342 const PropertyBase* property( NULL );
3346 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3347 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3348 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3349 case Dali::Actor::Property::SIZE_DEPTH:
3351 property = &GetNode().mSize;
3354 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3355 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3356 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3357 case Dali::Actor::Property::POSITION_Z:
3359 property = &GetNode().mPosition;
3362 case Dali::Actor::Property::ORIENTATION:
3364 property = &GetNode().mOrientation;
3367 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3368 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3369 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3370 case Dali::Actor::Property::SCALE_Z:
3372 property = &GetNode().mScale;
3375 case Dali::Actor::Property::VISIBLE:
3377 property = &GetNode().mVisible;
3380 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3381 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3382 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3383 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3384 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3385 case Dali::Actor::Property::OPACITY:
3387 property = &GetNode().mColor;
3397 // not our property, ask base
3398 property = Object::GetSceneObjectAnimatableProperty( index );
3404 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3406 const PropertyInputImpl* property( NULL );
3410 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3411 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3412 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3413 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3415 property = &GetNode().mParentOrigin;
3418 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3419 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3420 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3421 case Dali::Actor::Property::ANCHOR_POINT_Z:
3423 property = &GetNode().mAnchorPoint;
3426 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3427 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3428 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3429 case Dali::Actor::Property::WORLD_POSITION_Z:
3431 property = &GetNode().mWorldPosition;
3434 case Dali::Actor::Property::WORLD_ORIENTATION:
3436 property = &GetNode().mWorldOrientation;
3439 case Dali::Actor::Property::WORLD_SCALE:
3441 property = &GetNode().mWorldScale;
3444 case Dali::Actor::Property::WORLD_COLOR:
3446 property = &GetNode().mWorldColor;
3449 case Dali::Actor::Property::WORLD_MATRIX:
3451 property = &GetNode().mWorldMatrix;
3454 case Dali::Actor::Property::CULLED:
3456 property = &GetNode().mCulled;
3466 // reuse animatable property getter as animatable properties are inputs as well
3467 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3468 property = GetSceneObjectAnimatableProperty( index );
3474 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3476 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3480 case Dali::Actor::Property::PARENT_ORIGIN_X:
3481 case Dali::Actor::Property::ANCHOR_POINT_X:
3482 case Dali::Actor::Property::SIZE_WIDTH:
3483 case Dali::Actor::Property::POSITION_X:
3484 case Dali::Actor::Property::WORLD_POSITION_X:
3485 case Dali::Actor::Property::SCALE_X:
3486 case Dali::Actor::Property::COLOR_RED:
3492 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3493 case Dali::Actor::Property::ANCHOR_POINT_Y:
3494 case Dali::Actor::Property::SIZE_HEIGHT:
3495 case Dali::Actor::Property::POSITION_Y:
3496 case Dali::Actor::Property::WORLD_POSITION_Y:
3497 case Dali::Actor::Property::SCALE_Y:
3498 case Dali::Actor::Property::COLOR_GREEN:
3504 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3505 case Dali::Actor::Property::ANCHOR_POINT_Z:
3506 case Dali::Actor::Property::SIZE_DEPTH:
3507 case Dali::Actor::Property::POSITION_Z:
3508 case Dali::Actor::Property::WORLD_POSITION_Z:
3509 case Dali::Actor::Property::SCALE_Z:
3510 case Dali::Actor::Property::COLOR_BLUE:
3516 case Dali::Actor::Property::COLOR_ALPHA:
3517 case Dali::Actor::Property::OPACITY:
3529 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3532 componentIndex = Object::GetPropertyComponentIndex( index );
3535 return componentIndex;
3538 void Actor::SetParent( Actor* parent )
3542 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3546 mScene = parent->mScene;
3548 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3551 // Instruct each actor to create a corresponding node in the scene graph
3552 ConnectToScene( parent->GetHierarchyDepth() );
3555 // Resolve the name and index for the child properties if any
3556 ResolveChildProperties();
3558 else // parent being set to NULL
3560 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3564 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3567 // Disconnect the Node & its children from the scene-graph.
3568 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3570 // Instruct each actor to discard pointers to the scene-graph
3571 DisconnectFromStage();
3578 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3581 Actor* actor = dynamic_cast< Actor* >( object );
3585 if( 0 == actionName.compare( ACTION_SHOW ) )
3587 actor->SetVisible( true );
3590 else if( 0 == actionName.compare( ACTION_HIDE ) )
3592 actor->SetVisible( false );
3600 Rect<> Actor::CalculateScreenExtents( ) const
3602 auto screenPosition = GetCurrentScreenPosition();
3603 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3604 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3605 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3606 return { position.x, position.y, size.x, size.y };
3609 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3611 bool valueSet = true;
3615 case Dali::Actor::Property::PARENT_ORIGIN:
3617 value = GetCurrentParentOrigin();
3621 case Dali::Actor::Property::PARENT_ORIGIN_X:
3623 value = GetCurrentParentOrigin().x;
3627 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3629 value = GetCurrentParentOrigin().y;
3633 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3635 value = GetCurrentParentOrigin().z;
3639 case Dali::Actor::Property::ANCHOR_POINT:
3641 value = GetCurrentAnchorPoint();
3645 case Dali::Actor::Property::ANCHOR_POINT_X:
3647 value = GetCurrentAnchorPoint().x;
3651 case Dali::Actor::Property::ANCHOR_POINT_Y:
3653 value = GetCurrentAnchorPoint().y;
3657 case Dali::Actor::Property::ANCHOR_POINT_Z:
3659 value = GetCurrentAnchorPoint().z;
3663 case Dali::Actor::Property::SIZE:
3665 value = GetTargetSize();
3669 case Dali::Actor::Property::SIZE_WIDTH:
3671 value = GetTargetSize().width;
3675 case Dali::Actor::Property::SIZE_HEIGHT:
3677 value = GetTargetSize().height;
3681 case Dali::Actor::Property::SIZE_DEPTH:
3683 value = GetTargetSize().depth;
3687 case Dali::Actor::Property::POSITION:
3689 value = GetTargetPosition();
3693 case Dali::Actor::Property::POSITION_X:
3695 value = GetTargetPosition().x;
3699 case Dali::Actor::Property::POSITION_Y:
3701 value = GetTargetPosition().y;
3705 case Dali::Actor::Property::POSITION_Z:
3707 value = GetTargetPosition().z;
3711 case Dali::Actor::Property::ORIENTATION:
3713 value = mTargetOrientation;
3717 case Dali::Actor::Property::SCALE:
3719 value = mTargetScale;
3723 case Dali::Actor::Property::SCALE_X:
3725 value = mTargetScale.x;
3729 case Dali::Actor::Property::SCALE_Y:
3731 value = mTargetScale.y;
3735 case Dali::Actor::Property::SCALE_Z:
3737 value = mTargetScale.z;
3741 case Dali::Actor::Property::VISIBLE:
3747 case Dali::Actor::Property::COLOR:
3749 value = mTargetColor;
3753 case Dali::Actor::Property::COLOR_RED:
3755 value = mTargetColor.r;
3759 case Dali::Actor::Property::COLOR_GREEN:
3761 value = mTargetColor.g;
3765 case Dali::Actor::Property::COLOR_BLUE:
3767 value = mTargetColor.b;
3771 case Dali::Actor::Property::COLOR_ALPHA:
3772 case Dali::Actor::Property::OPACITY:
3774 value = mTargetColor.a;
3778 case Dali::Actor::Property::NAME:
3784 case Dali::Actor::Property::SENSITIVE:
3786 value = IsSensitive();
3790 case Dali::Actor::Property::LEAVE_REQUIRED:
3792 value = GetLeaveRequired();
3796 case Dali::Actor::Property::INHERIT_POSITION:
3798 value = IsPositionInherited();
3802 case Dali::Actor::Property::INHERIT_ORIENTATION:
3804 value = IsOrientationInherited();
3808 case Dali::Actor::Property::INHERIT_SCALE:
3810 value = IsScaleInherited();
3814 case Dali::Actor::Property::COLOR_MODE:
3816 value = GetColorMode();
3820 case Dali::Actor::Property::DRAW_MODE:
3822 value = GetDrawMode();
3826 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3828 value = GetSizeModeFactor();
3832 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3834 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3838 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3840 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3844 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3846 value = GetSizeScalePolicy();
3850 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3852 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3856 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3858 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3862 case Dali::Actor::Property::PADDING:
3864 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3865 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3866 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3870 case Dali::Actor::Property::MINIMUM_SIZE:
3872 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3876 case Dali::Actor::Property::MAXIMUM_SIZE:
3878 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3882 case Dali::Actor::Property::CLIPPING_MODE:
3884 value = mClippingMode;
3888 case Dali::DevelActor::Property::SIBLING_ORDER:
3890 value = static_cast<int>( GetSiblingOrder() );
3894 case Dali::Actor::Property::SCREEN_POSITION:
3896 value = GetCurrentScreenPosition();
3900 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
3902 value = mPositionUsesAnchorPoint;
3906 case Dali::Actor::Property::LAYOUT_DIRECTION:
3908 value = mLayoutDirection;
3912 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3914 value = IsLayoutDirectionInherited();
3918 case Dali::Actor::Property::ID:
3920 value = static_cast<int>( GetId() );
3924 case Dali::Actor::Property::HIERARCHY_DEPTH:
3926 value = GetHierarchyDepth();
3930 case Dali::Actor::Property::IS_ROOT:
3936 case Dali::Actor::Property::IS_LAYER:
3942 case Dali::Actor::Property::CONNECTED_TO_SCENE:
3948 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
3950 value = IsKeyboardFocusable();
3954 case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START:
3956 value = mCaptureAllTouchAfterStart;
3962 // Must be a scene-graph only property
3971 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3973 bool valueSet = true;
3977 case Dali::Actor::Property::SIZE:
3979 value = GetCurrentSize();
3983 case Dali::Actor::Property::SIZE_WIDTH:
3985 value = GetCurrentSize().width;
3989 case Dali::Actor::Property::SIZE_HEIGHT:
3991 value = GetCurrentSize().height;
3995 case Dali::Actor::Property::SIZE_DEPTH:
3997 value = GetCurrentSize().depth;
4001 case Dali::Actor::Property::POSITION:
4003 value = GetCurrentPosition();
4007 case Dali::Actor::Property::POSITION_X:
4009 value = GetCurrentPosition().x;
4013 case Dali::Actor::Property::POSITION_Y:
4015 value = GetCurrentPosition().y;
4019 case Dali::Actor::Property::POSITION_Z:
4021 value = GetCurrentPosition().z;
4025 case Dali::Actor::Property::WORLD_POSITION:
4027 value = GetCurrentWorldPosition();
4031 case Dali::Actor::Property::WORLD_POSITION_X:
4033 value = GetCurrentWorldPosition().x;
4037 case Dali::Actor::Property::WORLD_POSITION_Y:
4039 value = GetCurrentWorldPosition().y;
4043 case Dali::Actor::Property::WORLD_POSITION_Z:
4045 value = GetCurrentWorldPosition().z;
4049 case Dali::Actor::Property::ORIENTATION:
4051 value = GetCurrentOrientation();
4055 case Dali::Actor::Property::WORLD_ORIENTATION:
4057 value = GetCurrentWorldOrientation();
4061 case Dali::Actor::Property::SCALE:
4063 value = GetCurrentScale();
4067 case Dali::Actor::Property::SCALE_X:
4069 value = GetCurrentScale().x;
4073 case Dali::Actor::Property::SCALE_Y:
4075 value = GetCurrentScale().y;
4079 case Dali::Actor::Property::SCALE_Z:
4081 value = GetCurrentScale().z;
4085 case Dali::Actor::Property::WORLD_SCALE:
4087 value = GetCurrentWorldScale();
4091 case Dali::Actor::Property::COLOR:
4093 value = GetCurrentColor();
4097 case Dali::Actor::Property::COLOR_RED:
4099 value = GetCurrentColor().r;
4103 case Dali::Actor::Property::COLOR_GREEN:
4105 value = GetCurrentColor().g;
4109 case Dali::Actor::Property::COLOR_BLUE:
4111 value = GetCurrentColor().b;
4115 case Dali::Actor::Property::COLOR_ALPHA:
4116 case Dali::Actor::Property::OPACITY:
4118 value = GetCurrentColor().a;
4122 case Dali::Actor::Property::WORLD_COLOR:
4124 value = GetCurrentWorldColor();
4128 case Dali::Actor::Property::WORLD_MATRIX:
4130 value = GetCurrentWorldMatrix();
4134 case Dali::Actor::Property::VISIBLE:
4136 value = IsVisible();
4140 case Dali::Actor::Property::CULLED:
4142 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4146 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
4148 value = GetUpdateSizeHint();
4154 // Must be an event-side only property
4163 void Actor::EnsureRelayoutData()
4165 // Assign relayout data.
4166 if( !mRelayoutData )
4168 mRelayoutData = new RelayoutData();
4172 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4174 // Check if actor is dependent on parent
4175 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4177 if( ( dimension & ( 1 << i ) ) )
4179 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4180 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4190 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4192 // Check if actor is dependent on children
4193 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4195 if( ( dimension & ( 1 << i ) ) )
4197 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4198 switch( resizePolicy )
4200 case ResizePolicy::FIT_TO_CHILDREN:
4201 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4217 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4219 return Actor::RelayoutDependentOnChildren( dimension );
4222 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4224 // Check each possible dimension and see if it is dependent on the input one
4225 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4227 if( dimension & ( 1 << i ) )
4229 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4236 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4238 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4240 if( dimension & ( 1 << i ) )
4242 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4247 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4249 // If more than one dimension is requested, just return the first one found
4250 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4252 if( ( dimension & ( 1 << i ) ) )
4254 return mRelayoutData->negotiatedDimensions[ i ];
4258 return 0.0f; // Default
4261 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4263 EnsureRelayoutData();
4265 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4267 if( dimension & ( 1 << i ) )
4269 mRelayoutData->dimensionPadding[ i ] = padding;
4274 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4276 if ( mRelayoutData )
4278 // If more than one dimension is requested, just return the first one found
4279 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4281 if( ( dimension & ( 1 << i ) ) )
4283 return mRelayoutData->dimensionPadding[ i ];
4288 return GetDefaultDimensionPadding();
4291 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4293 EnsureRelayoutData();
4295 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4297 if( dimension & ( 1 << i ) )
4299 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4304 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4306 if ( mRelayoutData )
4308 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4310 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4320 float Actor::GetHeightForWidthBase( float width )
4322 float height = 0.0f;
4324 const Vector3 naturalSize = GetNaturalSize();
4325 if( naturalSize.width > 0.0f )
4327 height = naturalSize.height * width / naturalSize.width;
4329 else // we treat 0 as 1:1 aspect ratio
4337 float Actor::GetWidthForHeightBase( float height )
4341 const Vector3 naturalSize = GetNaturalSize();
4342 if( naturalSize.height > 0.0f )
4344 width = naturalSize.width * height / naturalSize.height;
4346 else // we treat 0 as 1:1 aspect ratio
4354 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4356 // Fill to parent, taking size mode factor into account
4357 switch( child.GetResizePolicy( dimension ) )
4359 case ResizePolicy::FILL_TO_PARENT:
4361 return GetLatestSize( dimension );
4364 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4366 return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4369 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4371 return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4376 return GetLatestSize( dimension );
4381 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4383 // Can be overridden in derived class
4384 return CalculateChildSizeBase( child, dimension );
4387 float Actor::GetHeightForWidth( float width )
4389 // Can be overridden in derived class
4390 return GetHeightForWidthBase( width );
4393 float Actor::GetWidthForHeight( float height )
4395 // Can be overridden in derived class
4396 return GetWidthForHeightBase( height );
4399 float Actor::GetLatestSize( Dimension::Type dimension ) const
4401 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4404 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4406 Vector2 padding = GetPadding( dimension );
4408 return GetLatestSize( dimension ) + padding.x + padding.y;
4411 float Actor::NegotiateFromParent( Dimension::Type dimension )
4413 Actor* parent = GetParent();
4416 Vector2 padding( GetPadding( dimension ) );
4417 Vector2 parentPadding( parent->GetPadding( dimension ) );
4418 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4424 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4426 float maxDimensionPoint = 0.0f;
4428 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4430 ActorPtr child = GetChildAt( i );
4432 if( !child->RelayoutDependentOnParent( dimension ) )
4434 // Calculate the min and max points that the children range across
4435 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4436 float dimensionSize = child->GetRelayoutSize( dimension );
4437 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4441 return maxDimensionPoint;
4444 float Actor::GetSize( Dimension::Type dimension ) const
4446 return GetDimensionValue( mTargetSize, dimension );
4449 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4451 return GetDimensionValue( GetNaturalSize(), dimension );
4454 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4456 switch( GetResizePolicy( dimension ) )
4458 case ResizePolicy::USE_NATURAL_SIZE:
4460 return GetNaturalSize( dimension );
4463 case ResizePolicy::FIXED:
4465 return GetDimensionValue( GetPreferredSize(), dimension );
4468 case ResizePolicy::USE_ASSIGNED_SIZE:
4470 return GetDimensionValue( maximumSize, dimension );
4473 case ResizePolicy::FILL_TO_PARENT:
4474 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4475 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4477 return NegotiateFromParent( dimension );
4480 case ResizePolicy::FIT_TO_CHILDREN:
4482 return NegotiateFromChildren( dimension );
4485 case ResizePolicy::DIMENSION_DEPENDENCY:
4487 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4490 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4492 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4495 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4497 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4509 return 0.0f; // Default
4512 float Actor::ClampDimension( float size, Dimension::Type dimension )
4514 const float minSize = GetMinimumSize( dimension );
4515 const float maxSize = GetMaximumSize( dimension );
4517 return std::max( minSize, std::min( size, maxSize ) );
4520 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4522 // Check if it needs to be negotiated
4523 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4525 // Check that we havn't gotten into an infinite loop
4526 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4527 bool recursionFound = false;
4528 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4530 if( *it == searchActor )
4532 recursionFound = true;
4537 if( !recursionFound )
4539 // Record the path that we have taken
4540 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4542 // Dimension dependency check
4543 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4545 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4547 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4549 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4553 // Parent dependency check
4554 Actor* parent = GetParent();
4555 if( parent && RelayoutDependentOnParent( dimension ) )
4557 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4560 // Children dependency check
4561 if( RelayoutDependentOnChildren( dimension ) )
4563 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4565 ActorPtr child = GetChildAt( i );
4567 // Only relayout child first if it is not dependent on this actor
4568 if( !child->RelayoutDependentOnParent( dimension ) )
4570 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4575 // For deriving classes
4576 OnCalculateRelayoutSize( dimension );
4578 // All dependencies checked, calculate the size and set negotiated flag
4579 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4581 SetNegotiatedDimension( newSize, dimension );
4582 SetLayoutNegotiated( true, dimension );
4584 // For deriving classes
4585 OnLayoutNegotiated( newSize, dimension );
4587 // This actor has been successfully processed, pop it off the recursion stack
4588 recursionStack.pop_back();
4592 // TODO: Break infinite loop
4593 SetLayoutNegotiated( true, dimension );
4598 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4600 // Negotiate all dimensions that require it
4601 ActorDimensionStack recursionStack;
4603 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4605 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4608 NegotiateDimension( dimension, allocatedSize, recursionStack );
4612 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4614 switch( mRelayoutData->sizeSetPolicy )
4616 case SizeScalePolicy::USE_SIZE_SET:
4621 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4623 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4624 const Vector3 naturalSize = GetNaturalSize();
4625 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4627 const float sizeRatio = size.width / size.height;
4628 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4630 if( naturalSizeRatio < sizeRatio )
4632 return Vector2( naturalSizeRatio * size.height, size.height );
4634 else if( naturalSizeRatio > sizeRatio )
4636 return Vector2( size.width, size.width / naturalSizeRatio );
4647 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4649 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4650 const Vector3 naturalSize = GetNaturalSize();
4651 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4653 const float sizeRatio = size.width / size.height;
4654 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4656 if( naturalSizeRatio < sizeRatio )
4658 return Vector2( size.width, size.width / naturalSizeRatio );
4660 else if( naturalSizeRatio > sizeRatio )
4662 return Vector2( naturalSizeRatio * size.height, size.height );
4681 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4683 // Do the set actor size
4684 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4686 // Adjust for size set policy
4687 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4689 // Lock the flag to stop recursive relayouts on set size
4690 mRelayoutData->insideRelayout = true;
4691 SetSize( negotiatedSize );
4692 mRelayoutData->insideRelayout = false;
4694 // Clear flags for all dimensions
4695 SetLayoutDirty( false );
4697 // Give deriving classes a chance to respond
4698 OnRelayout( negotiatedSize, container );
4700 if( !mOnRelayoutSignal.Empty() )
4702 Dali::Actor handle( this );
4703 mOnRelayoutSignal.Emit( handle );
4707 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4709 // Force a size negotiation for actors that has assigned size during relayout
4710 // This is required as otherwise the flags that force a relayout will not
4711 // necessarilly be set. This will occur if the actor has already been laid out.
4712 // The dirty flags are then cleared. Then if the actor is added back into the
4713 // relayout container afterwards, the dirty flags would still be clear...
4714 // causing a relayout to be skipped. Here we force any actors added to the
4715 // container to be relayed out.
4716 DALI_LOG_TIMER_START( NegSizeTimer1 );
4718 if( GetUseAssignedSize(Dimension::WIDTH ) )
4720 SetLayoutNegotiated( false, Dimension::WIDTH );
4722 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4724 SetLayoutNegotiated( false, Dimension::HEIGHT );
4727 // Do the negotiation
4728 NegotiateDimensions( allocatedSize );
4730 // Set the actor size
4731 SetNegotiatedSize( container );
4733 // Negotiate down to children
4734 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4736 ActorPtr child = GetChildAt( i );
4738 // Forces children that have already been laid out to be relayed out
4739 // if they have assigned size during relayout.
4740 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4742 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4743 child->SetLayoutDirty(true, Dimension::WIDTH);
4746 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4748 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4749 child->SetLayoutDirty(true, Dimension::HEIGHT);
4752 // Only relayout if required
4753 if( child->RelayoutRequired() )
4755 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4758 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4761 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4765 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4767 if( dimension & ( 1 << i ) )
4769 mRelayoutData->useAssignedSize[ i ] = use;
4775 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4777 if ( mRelayoutData )
4779 // If more than one dimension is requested, just return the first one found
4780 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4782 if( dimension & ( 1 << i ) )
4784 return mRelayoutData->useAssignedSize[ i ];
4792 void Actor::RelayoutRequest( Dimension::Type dimension )
4794 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4795 if( relayoutController )
4797 Dali::Actor self( this );
4798 relayoutController->RequestRelayout( self, dimension );
4802 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4806 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4810 void Actor::SetPreferredSize( const Vector2& size )
4812 EnsureRelayoutData();
4814 // If valid width or height, then set the resize policy to FIXED
4815 // 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,
4816 // then change to FIXED as well
4818 if( size.width > 0.0f )
4820 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4823 if( size.height > 0.0f )
4825 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4828 mRelayoutData->preferredSize = size;
4830 mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4835 Vector2 Actor::GetPreferredSize() const
4837 if ( mRelayoutData )
4839 return Vector2( mRelayoutData->preferredSize );
4842 return GetDefaultPreferredSize();
4845 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4847 EnsureRelayoutData();
4849 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4851 if( dimension & ( 1 << i ) )
4853 mRelayoutData->minimumSize[ i ] = size;
4860 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4862 if ( mRelayoutData )
4864 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4866 if( dimension & ( 1 << i ) )
4868 return mRelayoutData->minimumSize[ i ];
4873 return 0.0f; // Default
4876 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4878 EnsureRelayoutData();
4880 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4882 if( dimension & ( 1 << i ) )
4884 mRelayoutData->maximumSize[ i ] = size;
4891 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4893 if ( mRelayoutData )
4895 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4897 if( dimension & ( 1 << i ) )
4899 return mRelayoutData->maximumSize[ i ];
4904 return FLT_MAX; // Default
4907 Object* Actor::GetParentObject() const
4912 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4914 if( mVisible != visible )
4916 if( sendMessage == SendMessage::TRUE )
4918 // node is being used in a separate thread; queue a message to set the value & base value
4919 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4924 // Emit the signal on this actor and all its children
4925 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4929 void Actor::SetSiblingOrder( uint32_t order )
4933 ActorContainer& siblings = *(mParent->mChildren);
4934 uint32_t currentOrder = GetSiblingOrder();
4936 if( order != currentOrder )
4942 else if( order < siblings.size() -1 )
4944 if( order > currentOrder )
4946 RaiseAbove( *siblings[order] );
4950 LowerBelow( *siblings[order] );
4961 uint32_t Actor::GetSiblingOrder() const
4967 ActorContainer& siblings = *(mParent->mChildren);
4968 for( std::size_t i = 0; i < siblings.size(); ++i )
4970 if( siblings[i] == this )
4972 order = static_cast<uint32_t>( i );
4981 void Actor::RequestRebuildDepthTree()
4987 mScene->RequestRebuildDepthTree();
4996 ActorContainer& siblings = *(mParent->mChildren);
4997 if( siblings.back() != this ) // If not already at end
4999 for( std::size_t i=0; i<siblings.size(); ++i )
5001 if( siblings[i] == this )
5004 ActorPtr next = siblings[i+1];
5005 siblings[i+1] = this;
5012 Dali::Actor handle( this );
5013 mParent->mChildOrderChangedSignal.Emit( handle );
5015 RequestRebuildDepthTree();
5019 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5027 ActorContainer& siblings = *(mParent->mChildren);
5028 if( siblings.front() != this ) // If not already at beginning
5030 for( std::size_t i=1; i<siblings.size(); ++i )
5032 if( siblings[i] == this )
5034 // Swap with previous
5035 ActorPtr previous = siblings[i-1];
5036 siblings[i-1] = this;
5037 siblings[i] = previous;
5043 Dali::Actor handle( this );
5044 mParent->mChildOrderChangedSignal.Emit( handle );
5046 RequestRebuildDepthTree();
5050 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5054 void Actor::RaiseToTop()
5058 ActorContainer& siblings = *(mParent->mChildren);
5059 if( siblings.back() != this ) // If not already at end
5061 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5062 if( iter != siblings.end() )
5064 siblings.erase(iter);
5065 siblings.push_back(ActorPtr(this));
5069 Dali::Actor handle( this );
5070 mParent->mChildOrderChangedSignal.Emit( handle );
5072 RequestRebuildDepthTree();
5076 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5080 void Actor::LowerToBottom()
5084 ActorContainer& siblings = *(mParent->mChildren);
5085 if( siblings.front() != this ) // If not already at bottom,
5087 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5089 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5090 if( iter != siblings.end() )
5092 siblings.erase(iter);
5093 siblings.insert(siblings.begin(), thisPtr);
5097 Dali::Actor handle( this );
5098 mParent->mChildOrderChangedSignal.Emit( handle );
5100 RequestRebuildDepthTree();
5104 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5108 void Actor::RaiseAbove( Internal::Actor& target )
5112 ActorContainer& siblings = *(mParent->mChildren);
5113 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5115 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5117 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5118 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5119 if( thisIter < targetIter )
5121 siblings.erase(thisIter);
5122 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5123 // invalidate thisIter)
5124 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5126 siblings.insert(targetIter, thisPtr);
5129 Dali::Actor handle( this );
5130 mParent->mChildOrderChangedSignal.Emit( handle );
5132 RequestRebuildDepthTree();
5137 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5141 void Actor::LowerBelow( Internal::Actor& target )
5145 ActorContainer& siblings = *(mParent->mChildren);
5146 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5148 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5150 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5151 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5153 if( thisIter > targetIter )
5155 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5156 siblings.insert(targetIter, thisPtr);
5159 Dali::Actor handle( this );
5160 mParent->mChildOrderChangedSignal.Emit( handle );
5162 RequestRebuildDepthTree();
5167 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5171 void Actor::SetScene( Scene& scene )
5176 Scene& Actor::GetScene() const
5181 void Actor::SetInheritLayoutDirection( bool inherit )
5183 if( mInheritLayoutDirection != inherit )
5185 mInheritLayoutDirection = inherit;
5187 if( inherit && mParent )
5189 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5194 bool Actor::IsLayoutDirectionInherited() const
5196 return mInheritLayoutDirection;
5199 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5201 if( actor && ( actor->mInheritLayoutDirection || set ) )
5203 if( actor->mLayoutDirection != direction )
5205 actor->mLayoutDirection = direction;
5206 actor->EmitLayoutDirectionChangedSignal( direction );
5207 actor->RelayoutRequest();
5210 if( actor->GetChildCount() > 0 )
5212 ActorContainer& children = actor->GetChildrenInternal();
5213 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5215 InheritLayoutDirectionRecursively( *iter, direction );
5221 void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint )
5223 // node is being used in a separate thread; queue a message to set the value & base value
5224 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) );
5227 Vector2 Actor::GetUpdateSizeHint() const
5229 // node is being used in a separate thread, the value from the previous update is the same, set by user
5230 Vector3 updateSizeHint = GetNode().GetUpdateSizeHint();
5231 return Vector2( updateSizeHint.width, updateSizeHint.height );
5234 } // namespace Internal