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 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2094 mDrawMode( DrawMode::NORMAL ),
2095 mColorMode( Node::DEFAULT_COLOR_MODE ),
2096 mClippingMode( ClippingMode::DISABLED )
2100 void Actor::Initialize()
2104 GetEventThreadServices().RegisterObject( this );
2109 // Remove mParent pointers from children even if we're destroying core,
2110 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2113 ActorConstIter endIter = mChildren->end();
2114 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2116 (*iter)->SetParent( NULL );
2122 // Guard to allow handle destruction after Core has been destroyed
2123 if( EventThreadServices::IsCoreRunning() )
2125 // Root layer will destroy its node in its own destructor
2128 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2130 GetEventThreadServices().UnregisterObject( this );
2134 // Cleanup optional gesture data
2135 delete mGestureData;
2137 // Cleanup optional parent origin and anchor
2138 delete mParentOrigin;
2139 delete mAnchorPoint;
2141 // Delete optional relayout data
2142 delete mRelayoutData;
2145 void Actor::ConnectToScene( uint32_t parentDepth )
2147 // This container is used instead of walking the Actor hierarchy.
2148 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
2149 ActorContainer connectionList;
2153 mScene->RequestRebuildDepthTree();
2156 // This stage is atomic i.e. not interrupted by user callbacks.
2157 RecursiveConnectToScene( connectionList, parentDepth + 1 );
2159 // Notify applications about the newly connected actors.
2160 const ActorIter endIter = connectionList.end();
2161 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2163 (*iter)->NotifyStageConnection();
2169 void Actor::RecursiveConnectToScene( ActorContainer& connectionList, uint32_t depth )
2171 DALI_ASSERT_ALWAYS( !OnScene() );
2174 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2176 ConnectToSceneGraph();
2178 // Notification for internal derived classes
2179 OnSceneConnectionInternal();
2181 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2182 connectionList.push_back( ActorPtr( this ) );
2184 // Recursively connect children
2187 ActorConstIter endIter = mChildren->end();
2188 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2190 (*iter)->SetScene( *mScene );
2191 (*iter)->RecursiveConnectToScene( connectionList, depth + 1 );
2197 * This method is called when the Actor is connected to the Stage.
2198 * The parent must have added its Node to the scene-graph.
2199 * The child must connect its Node to the parent's Node.
2200 * This is recursive; the child calls ConnectToScene() for its children.
2202 void Actor::ConnectToSceneGraph()
2204 DALI_ASSERT_DEBUG( mParent != NULL);
2206 // Reparent Node in next Update
2207 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2209 // Request relayout on all actors that are added to the scenegraph
2212 // Notification for Object::Observers
2216 void Actor::NotifyStageConnection()
2218 // Actors can be removed (in a callback), before the on-stage stage is reported.
2219 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
2220 if( OnScene() && !mOnSceneSignalled )
2222 // Notification for external (CustomActor) derived classes
2223 OnSceneConnectionExternal( mDepth );
2225 if( !mOnSceneSignal.Empty() )
2227 Dali::Actor handle( this );
2228 mOnSceneSignal.Emit( handle );
2231 // Guard against Remove during callbacks
2234 mOnSceneSignalled = true; // signal required next time Actor is removed
2239 void Actor::DisconnectFromStage()
2241 // This container is used instead of walking the Actor hierachy.
2242 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
2243 ActorContainer disconnectionList;
2247 mScene->RequestRebuildDepthTree();
2250 // This stage is atomic i.e. not interrupted by user callbacks
2251 RecursiveDisconnectFromStage( disconnectionList );
2253 // Notify applications about the newly disconnected actors.
2254 const ActorIter endIter = disconnectionList.end();
2255 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2257 (*iter)->NotifyStageDisconnection();
2261 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2263 // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
2266 // Recursively disconnect children
2269 ActorConstIter endIter = mChildren->end();
2270 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2272 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2276 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2277 disconnectionList.push_back( ActorPtr( this ) );
2279 // Notification for internal derived classes
2280 OnSceneDisconnectionInternal();
2282 DisconnectFromSceneGraph();
2286 * This method is called by an actor or its parent, before a node removal message is sent.
2287 * This is recursive; the child calls DisconnectFromStage() for its children.
2289 void Actor::DisconnectFromSceneGraph()
2291 // Notification for Object::Observers
2292 OnSceneObjectRemove();
2295 void Actor::NotifyStageDisconnection()
2297 // Actors can be added (in a callback), before the off-stage state is reported.
2298 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
2299 // only do this step if there is a stage, i.e. Core is not being shut down
2300 if ( EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled )
2302 // Notification for external (CustomeActor) derived classes
2303 OnSceneDisconnectionExternal();
2305 if( !mOffSceneSignal.Empty() )
2307 Dali::Actor handle( this );
2308 mOffSceneSignal.Emit( handle );
2311 // Guard against Add during callbacks
2314 mOnSceneSignalled = false; // signal required next time Actor is added
2319 bool Actor::IsNodeConnected() const
2321 bool connected( false );
2325 if( IsRoot() || GetNode().GetParent() )
2334 // This method initiates traversal of the actor tree using depth-first
2335 // traversal to set a depth index based on traversal order. It sends a
2336 // single message to update manager to update all the actor's nodes in
2337 // this tree with the depth index. The sceneGraphNodeDepths vector's
2338 // elements are ordered by depth, and could be used to reduce sorting
2339 // in the update thread.
2340 void Actor::RebuildDepthTree()
2342 DALI_LOG_TIMER_START(depthTimer);
2344 // Vector of scene-graph nodes and their depths to send to UpdateManager
2345 // in a single message
2346 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2348 int32_t depthIndex = 1;
2349 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2351 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2352 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2355 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2357 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2358 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2360 // Create/add to children of this node
2363 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2365 Actor* childActor = (*it).Get();
2367 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2372 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2376 case Dali::Actor::Property::PARENT_ORIGIN:
2378 Property::Type type = property.GetType();
2379 if( type == Property::VECTOR3 )
2381 SetParentOrigin( property.Get< Vector3 >() );
2383 else if ( type == Property::STRING )
2385 std::string parentOriginString;
2386 property.Get( parentOriginString );
2387 Vector3 parentOrigin;
2388 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2390 SetParentOrigin( parentOrigin );
2396 case Dali::Actor::Property::PARENT_ORIGIN_X:
2398 SetParentOriginX( property.Get< float >() );
2402 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2404 SetParentOriginY( property.Get< float >() );
2408 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2410 SetParentOriginZ( property.Get< float >() );
2414 case Dali::Actor::Property::ANCHOR_POINT:
2416 Property::Type type = property.GetType();
2417 if( type == Property::VECTOR3 )
2419 SetAnchorPoint( property.Get< Vector3 >() );
2421 else if ( type == Property::STRING )
2423 std::string anchorPointString;
2424 property.Get( anchorPointString );
2426 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2428 SetAnchorPoint( anchor );
2434 case Dali::Actor::Property::ANCHOR_POINT_X:
2436 SetAnchorPointX( property.Get< float >() );
2440 case Dali::Actor::Property::ANCHOR_POINT_Y:
2442 SetAnchorPointY( property.Get< float >() );
2446 case Dali::Actor::Property::ANCHOR_POINT_Z:
2448 SetAnchorPointZ( property.Get< float >() );
2452 case Dali::Actor::Property::SIZE:
2454 Property::Type type = property.GetType();
2455 if( type == Property::VECTOR2 )
2457 SetSize( property.Get< Vector2 >() );
2459 else if ( type == Property::VECTOR3 )
2461 SetSize( property.Get< Vector3 >() );
2466 case Dali::Actor::Property::SIZE_WIDTH:
2468 SetWidth( property.Get< float >() );
2472 case Dali::Actor::Property::SIZE_HEIGHT:
2474 SetHeight( property.Get< float >() );
2478 case Dali::Actor::Property::SIZE_DEPTH:
2480 SetDepth( property.Get< float >() );
2484 case Dali::Actor::Property::POSITION:
2486 Property::Type type = property.GetType();
2487 if( type == Property::VECTOR2 )
2489 Vector2 position = property.Get< Vector2 >();
2490 SetPosition( Vector3( position.x, position.y, 0.0f ) );
2492 else if ( type == Property::VECTOR3 )
2494 SetPosition( property.Get< Vector3 >() );
2499 case Dali::Actor::Property::POSITION_X:
2501 SetX( property.Get< float >() );
2505 case Dali::Actor::Property::POSITION_Y:
2507 SetY( property.Get< float >() );
2511 case Dali::Actor::Property::POSITION_Z:
2513 SetZ( property.Get< float >() );
2517 case Dali::Actor::Property::ORIENTATION:
2519 SetOrientation( property.Get< Quaternion >() );
2523 case Dali::Actor::Property::SCALE:
2525 Property::Type type = property.GetType();
2526 if( type == Property::FLOAT )
2528 float scale = property.Get< float >();
2529 SetScale( scale, scale, scale );
2531 else if ( type == Property::VECTOR3 )
2533 SetScale( property.Get< Vector3 >() );
2538 case Dali::Actor::Property::SCALE_X:
2540 SetScaleX( property.Get< float >() );
2544 case Dali::Actor::Property::SCALE_Y:
2546 SetScaleY( property.Get< float >() );
2550 case Dali::Actor::Property::SCALE_Z:
2552 SetScaleZ( property.Get< float >() );
2556 case Dali::Actor::Property::VISIBLE:
2558 SetVisible( property.Get< bool >() );
2562 case Dali::Actor::Property::COLOR:
2564 Property::Type type = property.GetType();
2565 if( type == Property::VECTOR3 )
2567 Vector3 color = property.Get< Vector3 >();
2568 SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2570 else if( type == Property::VECTOR4 )
2572 SetColor( property.Get< Vector4 >() );
2577 case Dali::Actor::Property::COLOR_RED:
2579 SetColorRed( property.Get< float >() );
2583 case Dali::Actor::Property::COLOR_GREEN:
2585 SetColorGreen( property.Get< float >() );
2589 case Dali::Actor::Property::COLOR_BLUE:
2591 SetColorBlue( property.Get< float >() );
2595 case Dali::Actor::Property::COLOR_ALPHA:
2596 case Dali::Actor::Property::OPACITY:
2599 if( property.Get( value ) )
2601 SetOpacity( value );
2606 case Dali::Actor::Property::NAME:
2608 SetName( property.Get< std::string >() );
2612 case Dali::Actor::Property::SENSITIVE:
2614 SetSensitive( property.Get< bool >() );
2618 case Dali::Actor::Property::LEAVE_REQUIRED:
2620 SetLeaveRequired( property.Get< bool >() );
2624 case Dali::Actor::Property::INHERIT_POSITION:
2626 SetInheritPosition( property.Get< bool >() );
2630 case Dali::Actor::Property::INHERIT_ORIENTATION:
2632 SetInheritOrientation( property.Get< bool >() );
2636 case Dali::Actor::Property::INHERIT_SCALE:
2638 SetInheritScale( property.Get< bool >() );
2642 case Dali::Actor::Property::COLOR_MODE:
2644 ColorMode mode = mColorMode;
2645 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2647 SetColorMode( mode );
2652 case Dali::Actor::Property::DRAW_MODE:
2654 DrawMode::Type mode = mDrawMode;
2655 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2657 SetDrawMode( mode );
2662 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2664 SetSizeModeFactor( property.Get< Vector3 >() );
2668 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2670 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2671 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2673 SetResizePolicy( type, Dimension::WIDTH );
2678 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2680 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2681 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2683 SetResizePolicy( type, Dimension::HEIGHT );
2688 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2690 SizeScalePolicy::Type type = GetSizeScalePolicy();
2691 if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2693 SetSizeScalePolicy( type );
2698 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2700 if( property.Get< bool >() )
2702 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2707 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2709 if( property.Get< bool >() )
2711 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2716 case Dali::Actor::Property::PADDING:
2718 Vector4 padding = property.Get< Vector4 >();
2719 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2720 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2724 case Dali::Actor::Property::MINIMUM_SIZE:
2726 Vector2 size = property.Get< Vector2 >();
2727 SetMinimumSize( size.x, Dimension::WIDTH );
2728 SetMinimumSize( size.y, Dimension::HEIGHT );
2732 case Dali::Actor::Property::MAXIMUM_SIZE:
2734 Vector2 size = property.Get< Vector2 >();
2735 SetMaximumSize( size.x, Dimension::WIDTH );
2736 SetMaximumSize( size.y, Dimension::HEIGHT );
2740 case Dali::DevelActor::Property::SIBLING_ORDER:
2744 if( property.Get( value ) )
2746 SetSiblingOrder( value );
2751 case Dali::Actor::Property::CLIPPING_MODE:
2753 ClippingMode::Type convertedValue = mClippingMode;
2754 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2756 mClippingMode = convertedValue;
2757 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2762 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
2765 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2767 mPositionUsesAnchorPoint = value;
2768 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2773 case Dali::Actor::Property::LAYOUT_DIRECTION:
2775 Dali::LayoutDirection::Type direction = mLayoutDirection;
2776 mInheritLayoutDirection = false;
2778 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2780 InheritLayoutDirectionRecursively( this, direction, true );
2785 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2788 if( property.Get( value ) )
2790 SetInheritLayoutDirection( value );
2795 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
2798 if( property.Get( value ) )
2800 SetKeyboardFocusable( value );
2805 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
2807 SetUpdateSizeHint( property.Get< Vector2 >() );
2811 case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START:
2813 bool boolValue = false;
2814 if ( property.Get( boolValue ) )
2816 mCaptureAllTouchAfterStart = boolValue;
2823 // this can happen in the case of a non-animatable default property so just do nothing
2829 // TODO: This method needs to be removed
2830 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2832 switch( entry.GetType() )
2834 case Property::BOOLEAN:
2836 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2837 DALI_ASSERT_DEBUG( NULL != property );
2839 // property is being used in a separate thread; queue a message to set the property
2840 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2845 case Property::INTEGER:
2847 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2848 DALI_ASSERT_DEBUG( NULL != property );
2850 // property is being used in a separate thread; queue a message to set the property
2851 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2856 case Property::FLOAT:
2858 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2859 DALI_ASSERT_DEBUG( NULL != property );
2861 // property is being used in a separate thread; queue a message to set the property
2862 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2867 case Property::VECTOR2:
2869 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2870 DALI_ASSERT_DEBUG( NULL != property );
2872 // property is being used in a separate thread; queue a message to set the property
2873 if(entry.componentIndex == 0)
2875 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2877 else if(entry.componentIndex == 1)
2879 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2883 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2889 case Property::VECTOR3:
2891 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2892 DALI_ASSERT_DEBUG( NULL != property );
2894 // property is being used in a separate thread; queue a message to set the property
2895 if(entry.componentIndex == 0)
2897 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2899 else if(entry.componentIndex == 1)
2901 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2903 else if(entry.componentIndex == 2)
2905 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2909 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2915 case Property::VECTOR4:
2917 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2918 DALI_ASSERT_DEBUG( NULL != property );
2920 // property is being used in a separate thread; queue a message to set the property
2921 if(entry.componentIndex == 0)
2923 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2925 else if(entry.componentIndex == 1)
2927 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2929 else if(entry.componentIndex == 2)
2931 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2933 else if(entry.componentIndex == 3)
2935 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2939 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2945 case Property::ROTATION:
2947 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2948 DALI_ASSERT_DEBUG( NULL != property );
2950 // property is being used in a separate thread; queue a message to set the property
2951 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2956 case Property::MATRIX:
2958 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2959 DALI_ASSERT_DEBUG( NULL != property );
2961 // property is being used in a separate thread; queue a message to set the property
2962 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2967 case Property::MATRIX3:
2969 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2970 DALI_ASSERT_DEBUG( NULL != property );
2972 // property is being used in a separate thread; queue a message to set the property
2973 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2980 // nothing to do for other types
2985 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2987 Property::Value value;
2989 if( ! GetCachedPropertyValue( index, value ) )
2991 // If property value is not stored in the event-side, then it must be a scene-graph only property
2992 GetCurrentPropertyValue( index, value );
2998 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3000 Property::Value value;
3002 if( ! GetCurrentPropertyValue( index, value ) )
3004 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3005 GetCachedPropertyValue( index, value );
3011 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3013 switch( animationType )
3016 case Animation::BETWEEN:
3020 case Dali::Actor::Property::SIZE:
3022 if( value.Get( mTargetSize ) )
3024 mAnimatedSize = mTargetSize;
3025 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3027 // Notify deriving classes
3028 OnSizeAnimation( animation, mTargetSize );
3033 case Dali::Actor::Property::SIZE_WIDTH:
3035 if( value.Get( mTargetSize.width ) )
3037 mAnimatedSize.width = mTargetSize.width;
3038 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3040 // Notify deriving classes
3041 OnSizeAnimation( animation, mTargetSize );
3046 case Dali::Actor::Property::SIZE_HEIGHT:
3048 if( value.Get( mTargetSize.height ) )
3050 mAnimatedSize.height = mTargetSize.height;
3051 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3053 // Notify deriving classes
3054 OnSizeAnimation( animation, mTargetSize );
3059 case Dali::Actor::Property::SIZE_DEPTH:
3061 if( value.Get( mTargetSize.depth ) )
3063 mAnimatedSize.depth = mTargetSize.depth;
3064 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3066 // Notify deriving classes
3067 OnSizeAnimation( animation, mTargetSize );
3072 case Dali::Actor::Property::POSITION:
3074 value.Get( mTargetPosition );
3078 case Dali::Actor::Property::POSITION_X:
3080 value.Get( mTargetPosition.x );
3084 case Dali::Actor::Property::POSITION_Y:
3086 value.Get( mTargetPosition.y );
3090 case Dali::Actor::Property::POSITION_Z:
3092 value.Get( mTargetPosition.z );
3096 case Dali::Actor::Property::ORIENTATION:
3098 value.Get( mTargetOrientation );
3102 case Dali::Actor::Property::SCALE:
3104 value.Get( mTargetScale );
3108 case Dali::Actor::Property::SCALE_X:
3110 value.Get( mTargetScale.x );
3114 case Dali::Actor::Property::SCALE_Y:
3116 value.Get( mTargetScale.y );
3120 case Dali::Actor::Property::SCALE_Z:
3122 value.Get( mTargetScale.z );
3126 case Dali::Actor::Property::VISIBLE:
3128 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3132 case Dali::Actor::Property::COLOR:
3134 value.Get( mTargetColor );
3138 case Dali::Actor::Property::COLOR_RED:
3140 value.Get( mTargetColor.r );
3144 case Dali::Actor::Property::COLOR_GREEN:
3146 value.Get( mTargetColor.g );
3150 case Dali::Actor::Property::COLOR_BLUE:
3152 value.Get( mTargetColor.b );
3156 case Dali::Actor::Property::COLOR_ALPHA:
3157 case Dali::Actor::Property::OPACITY:
3159 value.Get( mTargetColor.a );
3165 // Not an animatable property. Do nothing.
3176 case Dali::Actor::Property::SIZE:
3178 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3180 mAnimatedSize = mTargetSize;
3181 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3183 // Notify deriving classes
3184 OnSizeAnimation( animation, mTargetSize );
3189 case Dali::Actor::Property::SIZE_WIDTH:
3191 if( AdjustValue< float >( mTargetSize.width, value ) )
3193 mAnimatedSize.width = mTargetSize.width;
3194 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3196 // Notify deriving classes
3197 OnSizeAnimation( animation, mTargetSize );
3202 case Dali::Actor::Property::SIZE_HEIGHT:
3204 if( AdjustValue< float >( mTargetSize.height, value ) )
3206 mAnimatedSize.height = mTargetSize.height;
3207 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3209 // Notify deriving classes
3210 OnSizeAnimation( animation, mTargetSize );
3215 case Dali::Actor::Property::SIZE_DEPTH:
3217 if( AdjustValue< float >( mTargetSize.depth, value ) )
3219 mAnimatedSize.depth = mTargetSize.depth;
3220 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3222 // Notify deriving classes
3223 OnSizeAnimation( animation, mTargetSize );
3228 case Dali::Actor::Property::POSITION:
3230 AdjustValue< Vector3 >( mTargetPosition, value );
3234 case Dali::Actor::Property::POSITION_X:
3236 AdjustValue< float >( mTargetPosition.x, value );
3240 case Dali::Actor::Property::POSITION_Y:
3242 AdjustValue< float >( mTargetPosition.y, value );
3246 case Dali::Actor::Property::POSITION_Z:
3248 AdjustValue< float >( mTargetPosition.z, value );
3252 case Dali::Actor::Property::ORIENTATION:
3254 Quaternion relativeValue;
3255 if( value.Get( relativeValue ) )
3257 mTargetOrientation *= relativeValue;
3262 case Dali::Actor::Property::SCALE:
3264 AdjustValue< Vector3 >( mTargetScale, value );
3268 case Dali::Actor::Property::SCALE_X:
3270 AdjustValue< float >( mTargetScale.x, value );
3274 case Dali::Actor::Property::SCALE_Y:
3276 AdjustValue< float >( mTargetScale.y, value );
3280 case Dali::Actor::Property::SCALE_Z:
3282 AdjustValue< float >( mTargetScale.z, value );
3286 case Dali::Actor::Property::VISIBLE:
3288 bool relativeValue = false;
3289 if( value.Get( relativeValue ) )
3291 bool visible = mVisible || relativeValue;
3292 SetVisibleInternal( visible, SendMessage::FALSE );
3297 case Dali::Actor::Property::COLOR:
3299 AdjustValue< Vector4 >( mTargetColor, value );
3303 case Dali::Actor::Property::COLOR_RED:
3305 AdjustValue< float >( mTargetColor.r, value );
3309 case Dali::Actor::Property::COLOR_GREEN:
3311 AdjustValue< float >( mTargetColor.g, value );
3315 case Dali::Actor::Property::COLOR_BLUE:
3317 AdjustValue< float >( mTargetColor.b, value );
3321 case Dali::Actor::Property::COLOR_ALPHA:
3322 case Dali::Actor::Property::OPACITY:
3324 AdjustValue< float >( mTargetColor.a, value );
3330 // Not an animatable property. Do nothing.
3339 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3341 const PropertyBase* property( NULL );
3345 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3346 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3347 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3348 case Dali::Actor::Property::SIZE_DEPTH:
3350 property = &GetNode().mSize;
3353 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3354 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3355 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3356 case Dali::Actor::Property::POSITION_Z:
3358 property = &GetNode().mPosition;
3361 case Dali::Actor::Property::ORIENTATION:
3363 property = &GetNode().mOrientation;
3366 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3367 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3368 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3369 case Dali::Actor::Property::SCALE_Z:
3371 property = &GetNode().mScale;
3374 case Dali::Actor::Property::VISIBLE:
3376 property = &GetNode().mVisible;
3379 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3380 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3381 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3382 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3383 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3384 case Dali::Actor::Property::OPACITY:
3386 property = &GetNode().mColor;
3396 // not our property, ask base
3397 property = Object::GetSceneObjectAnimatableProperty( index );
3403 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3405 const PropertyInputImpl* property( NULL );
3409 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3410 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3411 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3412 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3414 property = &GetNode().mParentOrigin;
3417 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3418 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3419 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3420 case Dali::Actor::Property::ANCHOR_POINT_Z:
3422 property = &GetNode().mAnchorPoint;
3425 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3426 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3427 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3428 case Dali::Actor::Property::WORLD_POSITION_Z:
3430 property = &GetNode().mWorldPosition;
3433 case Dali::Actor::Property::WORLD_ORIENTATION:
3435 property = &GetNode().mWorldOrientation;
3438 case Dali::Actor::Property::WORLD_SCALE:
3440 property = &GetNode().mWorldScale;
3443 case Dali::Actor::Property::WORLD_COLOR:
3445 property = &GetNode().mWorldColor;
3448 case Dali::Actor::Property::WORLD_MATRIX:
3450 property = &GetNode().mWorldMatrix;
3453 case Dali::Actor::Property::CULLED:
3455 property = &GetNode().mCulled;
3465 // reuse animatable property getter as animatable properties are inputs as well
3466 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3467 property = GetSceneObjectAnimatableProperty( index );
3473 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3475 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3479 case Dali::Actor::Property::PARENT_ORIGIN_X:
3480 case Dali::Actor::Property::ANCHOR_POINT_X:
3481 case Dali::Actor::Property::SIZE_WIDTH:
3482 case Dali::Actor::Property::POSITION_X:
3483 case Dali::Actor::Property::WORLD_POSITION_X:
3484 case Dali::Actor::Property::SCALE_X:
3485 case Dali::Actor::Property::COLOR_RED:
3491 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3492 case Dali::Actor::Property::ANCHOR_POINT_Y:
3493 case Dali::Actor::Property::SIZE_HEIGHT:
3494 case Dali::Actor::Property::POSITION_Y:
3495 case Dali::Actor::Property::WORLD_POSITION_Y:
3496 case Dali::Actor::Property::SCALE_Y:
3497 case Dali::Actor::Property::COLOR_GREEN:
3503 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3504 case Dali::Actor::Property::ANCHOR_POINT_Z:
3505 case Dali::Actor::Property::SIZE_DEPTH:
3506 case Dali::Actor::Property::POSITION_Z:
3507 case Dali::Actor::Property::WORLD_POSITION_Z:
3508 case Dali::Actor::Property::SCALE_Z:
3509 case Dali::Actor::Property::COLOR_BLUE:
3515 case Dali::Actor::Property::COLOR_ALPHA:
3516 case Dali::Actor::Property::OPACITY:
3528 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3531 componentIndex = Object::GetPropertyComponentIndex( index );
3534 return componentIndex;
3537 void Actor::SetParent( Actor* parent )
3541 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3545 mScene = parent->mScene;
3547 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3550 // Instruct each actor to create a corresponding node in the scene graph
3551 ConnectToScene( parent->GetHierarchyDepth() );
3554 // Resolve the name and index for the child properties if any
3555 ResolveChildProperties();
3557 else // parent being set to NULL
3559 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3563 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3566 // Disconnect the Node & its children from the scene-graph.
3567 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3569 // Instruct each actor to discard pointers to the scene-graph
3570 DisconnectFromStage();
3577 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3580 Actor* actor = dynamic_cast< Actor* >( object );
3584 if( 0 == actionName.compare( ACTION_SHOW ) )
3586 actor->SetVisible( true );
3589 else if( 0 == actionName.compare( ACTION_HIDE ) )
3591 actor->SetVisible( false );
3599 Rect<> Actor::CalculateScreenExtents( ) const
3601 auto screenPosition = GetCurrentScreenPosition();
3602 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3603 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3604 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3605 return { position.x, position.y, size.x, size.y };
3608 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3610 bool valueSet = true;
3614 case Dali::Actor::Property::PARENT_ORIGIN:
3616 value = GetCurrentParentOrigin();
3620 case Dali::Actor::Property::PARENT_ORIGIN_X:
3622 value = GetCurrentParentOrigin().x;
3626 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3628 value = GetCurrentParentOrigin().y;
3632 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3634 value = GetCurrentParentOrigin().z;
3638 case Dali::Actor::Property::ANCHOR_POINT:
3640 value = GetCurrentAnchorPoint();
3644 case Dali::Actor::Property::ANCHOR_POINT_X:
3646 value = GetCurrentAnchorPoint().x;
3650 case Dali::Actor::Property::ANCHOR_POINT_Y:
3652 value = GetCurrentAnchorPoint().y;
3656 case Dali::Actor::Property::ANCHOR_POINT_Z:
3658 value = GetCurrentAnchorPoint().z;
3662 case Dali::Actor::Property::SIZE:
3664 value = GetTargetSize();
3668 case Dali::Actor::Property::SIZE_WIDTH:
3670 value = GetTargetSize().width;
3674 case Dali::Actor::Property::SIZE_HEIGHT:
3676 value = GetTargetSize().height;
3680 case Dali::Actor::Property::SIZE_DEPTH:
3682 value = GetTargetSize().depth;
3686 case Dali::Actor::Property::POSITION:
3688 value = GetTargetPosition();
3692 case Dali::Actor::Property::POSITION_X:
3694 value = GetTargetPosition().x;
3698 case Dali::Actor::Property::POSITION_Y:
3700 value = GetTargetPosition().y;
3704 case Dali::Actor::Property::POSITION_Z:
3706 value = GetTargetPosition().z;
3710 case Dali::Actor::Property::ORIENTATION:
3712 value = mTargetOrientation;
3716 case Dali::Actor::Property::SCALE:
3718 value = mTargetScale;
3722 case Dali::Actor::Property::SCALE_X:
3724 value = mTargetScale.x;
3728 case Dali::Actor::Property::SCALE_Y:
3730 value = mTargetScale.y;
3734 case Dali::Actor::Property::SCALE_Z:
3736 value = mTargetScale.z;
3740 case Dali::Actor::Property::VISIBLE:
3746 case Dali::Actor::Property::COLOR:
3748 value = mTargetColor;
3752 case Dali::Actor::Property::COLOR_RED:
3754 value = mTargetColor.r;
3758 case Dali::Actor::Property::COLOR_GREEN:
3760 value = mTargetColor.g;
3764 case Dali::Actor::Property::COLOR_BLUE:
3766 value = mTargetColor.b;
3770 case Dali::Actor::Property::COLOR_ALPHA:
3771 case Dali::Actor::Property::OPACITY:
3773 value = mTargetColor.a;
3777 case Dali::Actor::Property::NAME:
3783 case Dali::Actor::Property::SENSITIVE:
3785 value = IsSensitive();
3789 case Dali::Actor::Property::LEAVE_REQUIRED:
3791 value = GetLeaveRequired();
3795 case Dali::Actor::Property::INHERIT_POSITION:
3797 value = IsPositionInherited();
3801 case Dali::Actor::Property::INHERIT_ORIENTATION:
3803 value = IsOrientationInherited();
3807 case Dali::Actor::Property::INHERIT_SCALE:
3809 value = IsScaleInherited();
3813 case Dali::Actor::Property::COLOR_MODE:
3815 value = GetColorMode();
3819 case Dali::Actor::Property::DRAW_MODE:
3821 value = GetDrawMode();
3825 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3827 value = GetSizeModeFactor();
3831 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3833 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3837 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3839 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3843 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3845 value = GetSizeScalePolicy();
3849 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3851 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3855 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3857 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3861 case Dali::Actor::Property::PADDING:
3863 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3864 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3865 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3869 case Dali::Actor::Property::MINIMUM_SIZE:
3871 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3875 case Dali::Actor::Property::MAXIMUM_SIZE:
3877 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3881 case Dali::Actor::Property::CLIPPING_MODE:
3883 value = mClippingMode;
3887 case Dali::DevelActor::Property::SIBLING_ORDER:
3889 value = static_cast<int>( GetSiblingOrder() );
3893 case Dali::Actor::Property::SCREEN_POSITION:
3895 value = GetCurrentScreenPosition();
3899 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
3901 value = mPositionUsesAnchorPoint;
3905 case Dali::Actor::Property::LAYOUT_DIRECTION:
3907 value = mLayoutDirection;
3911 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3913 value = IsLayoutDirectionInherited();
3917 case Dali::Actor::Property::ID:
3919 value = static_cast<int>( GetId() );
3923 case Dali::Actor::Property::HIERARCHY_DEPTH:
3925 value = GetHierarchyDepth();
3929 case Dali::Actor::Property::IS_ROOT:
3935 case Dali::Actor::Property::IS_LAYER:
3941 case Dali::Actor::Property::CONNECTED_TO_SCENE:
3947 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
3949 value = IsKeyboardFocusable();
3953 case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START:
3955 value = mCaptureAllTouchAfterStart;
3961 // Must be a scene-graph only property
3970 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3972 bool valueSet = true;
3976 case Dali::Actor::Property::SIZE:
3978 value = GetCurrentSize();
3982 case Dali::Actor::Property::SIZE_WIDTH:
3984 value = GetCurrentSize().width;
3988 case Dali::Actor::Property::SIZE_HEIGHT:
3990 value = GetCurrentSize().height;
3994 case Dali::Actor::Property::SIZE_DEPTH:
3996 value = GetCurrentSize().depth;
4000 case Dali::Actor::Property::POSITION:
4002 value = GetCurrentPosition();
4006 case Dali::Actor::Property::POSITION_X:
4008 value = GetCurrentPosition().x;
4012 case Dali::Actor::Property::POSITION_Y:
4014 value = GetCurrentPosition().y;
4018 case Dali::Actor::Property::POSITION_Z:
4020 value = GetCurrentPosition().z;
4024 case Dali::Actor::Property::WORLD_POSITION:
4026 value = GetCurrentWorldPosition();
4030 case Dali::Actor::Property::WORLD_POSITION_X:
4032 value = GetCurrentWorldPosition().x;
4036 case Dali::Actor::Property::WORLD_POSITION_Y:
4038 value = GetCurrentWorldPosition().y;
4042 case Dali::Actor::Property::WORLD_POSITION_Z:
4044 value = GetCurrentWorldPosition().z;
4048 case Dali::Actor::Property::ORIENTATION:
4050 value = GetCurrentOrientation();
4054 case Dali::Actor::Property::WORLD_ORIENTATION:
4056 value = GetCurrentWorldOrientation();
4060 case Dali::Actor::Property::SCALE:
4062 value = GetCurrentScale();
4066 case Dali::Actor::Property::SCALE_X:
4068 value = GetCurrentScale().x;
4072 case Dali::Actor::Property::SCALE_Y:
4074 value = GetCurrentScale().y;
4078 case Dali::Actor::Property::SCALE_Z:
4080 value = GetCurrentScale().z;
4084 case Dali::Actor::Property::WORLD_SCALE:
4086 value = GetCurrentWorldScale();
4090 case Dali::Actor::Property::COLOR:
4092 value = GetCurrentColor();
4096 case Dali::Actor::Property::COLOR_RED:
4098 value = GetCurrentColor().r;
4102 case Dali::Actor::Property::COLOR_GREEN:
4104 value = GetCurrentColor().g;
4108 case Dali::Actor::Property::COLOR_BLUE:
4110 value = GetCurrentColor().b;
4114 case Dali::Actor::Property::COLOR_ALPHA:
4115 case Dali::Actor::Property::OPACITY:
4117 value = GetCurrentColor().a;
4121 case Dali::Actor::Property::WORLD_COLOR:
4123 value = GetCurrentWorldColor();
4127 case Dali::Actor::Property::WORLD_MATRIX:
4129 value = GetCurrentWorldMatrix();
4133 case Dali::Actor::Property::VISIBLE:
4135 value = IsVisible();
4139 case Dali::Actor::Property::CULLED:
4141 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4145 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
4147 value = GetUpdateSizeHint();
4153 // Must be an event-side only property
4162 void Actor::EnsureRelayoutData()
4164 // Assign relayout data.
4165 if( !mRelayoutData )
4167 mRelayoutData = new RelayoutData();
4171 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4173 // Check if actor is dependent on parent
4174 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4176 if( ( dimension & ( 1 << i ) ) )
4178 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4179 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4189 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4191 // Check if actor is dependent on children
4192 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4194 if( ( dimension & ( 1 << i ) ) )
4196 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4197 switch( resizePolicy )
4199 case ResizePolicy::FIT_TO_CHILDREN:
4200 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4216 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4218 return Actor::RelayoutDependentOnChildren( dimension );
4221 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4223 // Check each possible dimension and see if it is dependent on the input one
4224 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4226 if( dimension & ( 1 << i ) )
4228 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4235 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4237 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4239 if( dimension & ( 1 << i ) )
4241 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4246 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4248 // If more than one dimension is requested, just return the first one found
4249 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4251 if( ( dimension & ( 1 << i ) ) )
4253 return mRelayoutData->negotiatedDimensions[ i ];
4257 return 0.0f; // Default
4260 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4262 EnsureRelayoutData();
4264 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4266 if( dimension & ( 1 << i ) )
4268 mRelayoutData->dimensionPadding[ i ] = padding;
4273 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4275 if ( mRelayoutData )
4277 // If more than one dimension is requested, just return the first one found
4278 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4280 if( ( dimension & ( 1 << i ) ) )
4282 return mRelayoutData->dimensionPadding[ i ];
4287 return GetDefaultDimensionPadding();
4290 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4292 EnsureRelayoutData();
4294 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4296 if( dimension & ( 1 << i ) )
4298 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4303 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4305 if ( mRelayoutData )
4307 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4309 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4319 float Actor::GetHeightForWidthBase( float width )
4321 float height = 0.0f;
4323 const Vector3 naturalSize = GetNaturalSize();
4324 if( naturalSize.width > 0.0f )
4326 height = naturalSize.height * width / naturalSize.width;
4328 else // we treat 0 as 1:1 aspect ratio
4336 float Actor::GetWidthForHeightBase( float height )
4340 const Vector3 naturalSize = GetNaturalSize();
4341 if( naturalSize.height > 0.0f )
4343 width = naturalSize.width * height / naturalSize.height;
4345 else // we treat 0 as 1:1 aspect ratio
4353 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4355 // Fill to parent, taking size mode factor into account
4356 switch( child.GetResizePolicy( dimension ) )
4358 case ResizePolicy::FILL_TO_PARENT:
4360 return GetLatestSize( dimension );
4363 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4365 return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4368 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4370 return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4375 return GetLatestSize( dimension );
4380 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4382 // Can be overridden in derived class
4383 return CalculateChildSizeBase( child, dimension );
4386 float Actor::GetHeightForWidth( float width )
4388 // Can be overridden in derived class
4389 return GetHeightForWidthBase( width );
4392 float Actor::GetWidthForHeight( float height )
4394 // Can be overridden in derived class
4395 return GetWidthForHeightBase( height );
4398 float Actor::GetLatestSize( Dimension::Type dimension ) const
4400 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4403 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4405 Vector2 padding = GetPadding( dimension );
4407 return GetLatestSize( dimension ) + padding.x + padding.y;
4410 float Actor::NegotiateFromParent( Dimension::Type dimension )
4412 Actor* parent = GetParent();
4415 Vector2 padding( GetPadding( dimension ) );
4416 Vector2 parentPadding( parent->GetPadding( dimension ) );
4417 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4423 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4425 float maxDimensionPoint = 0.0f;
4427 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4429 ActorPtr child = GetChildAt( i );
4431 if( !child->RelayoutDependentOnParent( dimension ) )
4433 // Calculate the min and max points that the children range across
4434 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4435 float dimensionSize = child->GetRelayoutSize( dimension );
4436 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4440 return maxDimensionPoint;
4443 float Actor::GetSize( Dimension::Type dimension ) const
4445 return GetDimensionValue( mTargetSize, dimension );
4448 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4450 return GetDimensionValue( GetNaturalSize(), dimension );
4453 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4455 switch( GetResizePolicy( dimension ) )
4457 case ResizePolicy::USE_NATURAL_SIZE:
4459 return GetNaturalSize( dimension );
4462 case ResizePolicy::FIXED:
4464 return GetDimensionValue( GetPreferredSize(), dimension );
4467 case ResizePolicy::USE_ASSIGNED_SIZE:
4469 return GetDimensionValue( maximumSize, dimension );
4472 case ResizePolicy::FILL_TO_PARENT:
4473 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4474 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4476 return NegotiateFromParent( dimension );
4479 case ResizePolicy::FIT_TO_CHILDREN:
4481 return NegotiateFromChildren( dimension );
4484 case ResizePolicy::DIMENSION_DEPENDENCY:
4486 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4489 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4491 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4494 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4496 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4508 return 0.0f; // Default
4511 float Actor::ClampDimension( float size, Dimension::Type dimension )
4513 const float minSize = GetMinimumSize( dimension );
4514 const float maxSize = GetMaximumSize( dimension );
4516 return std::max( minSize, std::min( size, maxSize ) );
4519 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4521 // Check if it needs to be negotiated
4522 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4524 // Check that we havn't gotten into an infinite loop
4525 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4526 bool recursionFound = false;
4527 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4529 if( *it == searchActor )
4531 recursionFound = true;
4536 if( !recursionFound )
4538 // Record the path that we have taken
4539 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4541 // Dimension dependency check
4542 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4544 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4546 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4548 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4552 // Parent dependency check
4553 Actor* parent = GetParent();
4554 if( parent && RelayoutDependentOnParent( dimension ) )
4556 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4559 // Children dependency check
4560 if( RelayoutDependentOnChildren( dimension ) )
4562 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4564 ActorPtr child = GetChildAt( i );
4566 // Only relayout child first if it is not dependent on this actor
4567 if( !child->RelayoutDependentOnParent( dimension ) )
4569 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4574 // For deriving classes
4575 OnCalculateRelayoutSize( dimension );
4577 // All dependencies checked, calculate the size and set negotiated flag
4578 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4580 SetNegotiatedDimension( newSize, dimension );
4581 SetLayoutNegotiated( true, dimension );
4583 // For deriving classes
4584 OnLayoutNegotiated( newSize, dimension );
4586 // This actor has been successfully processed, pop it off the recursion stack
4587 recursionStack.pop_back();
4591 // TODO: Break infinite loop
4592 SetLayoutNegotiated( true, dimension );
4597 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4599 // Negotiate all dimensions that require it
4600 ActorDimensionStack recursionStack;
4602 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4604 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4607 NegotiateDimension( dimension, allocatedSize, recursionStack );
4611 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4613 switch( mRelayoutData->sizeSetPolicy )
4615 case SizeScalePolicy::USE_SIZE_SET:
4620 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4622 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4623 const Vector3 naturalSize = GetNaturalSize();
4624 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4626 const float sizeRatio = size.width / size.height;
4627 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4629 if( naturalSizeRatio < sizeRatio )
4631 return Vector2( naturalSizeRatio * size.height, size.height );
4633 else if( naturalSizeRatio > sizeRatio )
4635 return Vector2( size.width, size.width / naturalSizeRatio );
4646 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4648 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4649 const Vector3 naturalSize = GetNaturalSize();
4650 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4652 const float sizeRatio = size.width / size.height;
4653 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4655 if( naturalSizeRatio < sizeRatio )
4657 return Vector2( size.width, size.width / naturalSizeRatio );
4659 else if( naturalSizeRatio > sizeRatio )
4661 return Vector2( naturalSizeRatio * size.height, size.height );
4680 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4682 // Do the set actor size
4683 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4685 // Adjust for size set policy
4686 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4688 // Lock the flag to stop recursive relayouts on set size
4689 mRelayoutData->insideRelayout = true;
4690 SetSize( negotiatedSize );
4691 mRelayoutData->insideRelayout = false;
4693 // Clear flags for all dimensions
4694 SetLayoutDirty( false );
4696 // Give deriving classes a chance to respond
4697 OnRelayout( negotiatedSize, container );
4699 if( !mOnRelayoutSignal.Empty() )
4701 Dali::Actor handle( this );
4702 mOnRelayoutSignal.Emit( handle );
4706 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4708 // Force a size negotiation for actors that has assigned size during relayout
4709 // This is required as otherwise the flags that force a relayout will not
4710 // necessarilly be set. This will occur if the actor has already been laid out.
4711 // The dirty flags are then cleared. Then if the actor is added back into the
4712 // relayout container afterwards, the dirty flags would still be clear...
4713 // causing a relayout to be skipped. Here we force any actors added to the
4714 // container to be relayed out.
4715 DALI_LOG_TIMER_START( NegSizeTimer1 );
4717 if( GetUseAssignedSize(Dimension::WIDTH ) )
4719 SetLayoutNegotiated( false, Dimension::WIDTH );
4721 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4723 SetLayoutNegotiated( false, Dimension::HEIGHT );
4726 // Do the negotiation
4727 NegotiateDimensions( allocatedSize );
4729 // Set the actor size
4730 SetNegotiatedSize( container );
4732 // Negotiate down to children
4733 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4735 ActorPtr child = GetChildAt( i );
4737 // Forces children that have already been laid out to be relayed out
4738 // if they have assigned size during relayout.
4739 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4741 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4742 child->SetLayoutDirty(true, Dimension::WIDTH);
4745 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4747 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4748 child->SetLayoutDirty(true, Dimension::HEIGHT);
4751 // Only relayout if required
4752 if( child->RelayoutRequired() )
4754 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4757 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4760 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4764 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4766 if( dimension & ( 1 << i ) )
4768 mRelayoutData->useAssignedSize[ i ] = use;
4774 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4776 if ( mRelayoutData )
4778 // If more than one dimension is requested, just return the first one found
4779 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4781 if( dimension & ( 1 << i ) )
4783 return mRelayoutData->useAssignedSize[ i ];
4791 void Actor::RelayoutRequest( Dimension::Type dimension )
4793 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4794 if( relayoutController )
4796 Dali::Actor self( this );
4797 relayoutController->RequestRelayout( self, dimension );
4801 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4805 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4809 void Actor::SetPreferredSize( const Vector2& size )
4811 EnsureRelayoutData();
4813 // If valid width or height, then set the resize policy to FIXED
4814 // 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,
4815 // then change to FIXED as well
4817 if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4819 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4822 if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4824 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4827 mRelayoutData->preferredSize = size;
4829 mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4834 Vector2 Actor::GetPreferredSize() const
4836 if ( mRelayoutData )
4838 return Vector2( mRelayoutData->preferredSize );
4841 return GetDefaultPreferredSize();
4844 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4846 EnsureRelayoutData();
4848 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4850 if( dimension & ( 1 << i ) )
4852 mRelayoutData->minimumSize[ i ] = size;
4859 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4861 if ( mRelayoutData )
4863 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4865 if( dimension & ( 1 << i ) )
4867 return mRelayoutData->minimumSize[ i ];
4872 return 0.0f; // Default
4875 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4877 EnsureRelayoutData();
4879 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4881 if( dimension & ( 1 << i ) )
4883 mRelayoutData->maximumSize[ i ] = size;
4890 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4892 if ( mRelayoutData )
4894 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4896 if( dimension & ( 1 << i ) )
4898 return mRelayoutData->maximumSize[ i ];
4903 return FLT_MAX; // Default
4906 Object* Actor::GetParentObject() const
4911 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4913 if( mVisible != visible )
4915 if( sendMessage == SendMessage::TRUE )
4917 // node is being used in a separate thread; queue a message to set the value & base value
4918 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4923 // Emit the signal on this actor and all its children
4924 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4928 void Actor::SetSiblingOrder( uint32_t order )
4932 ActorContainer& siblings = *(mParent->mChildren);
4933 uint32_t currentOrder = GetSiblingOrder();
4935 if( order != currentOrder )
4941 else if( order < siblings.size() -1 )
4943 if( order > currentOrder )
4945 RaiseAbove( *siblings[order] );
4949 LowerBelow( *siblings[order] );
4960 uint32_t Actor::GetSiblingOrder() const
4966 ActorContainer& siblings = *(mParent->mChildren);
4967 for( std::size_t i = 0; i < siblings.size(); ++i )
4969 if( siblings[i] == this )
4971 order = static_cast<uint32_t>( i );
4980 void Actor::RequestRebuildDepthTree()
4986 mScene->RequestRebuildDepthTree();
4995 ActorContainer& siblings = *(mParent->mChildren);
4996 if( siblings.back() != this ) // If not already at end
4998 for( std::size_t i=0; i<siblings.size(); ++i )
5000 if( siblings[i] == this )
5003 ActorPtr next = siblings[i+1];
5004 siblings[i+1] = this;
5011 Dali::Actor handle( this );
5012 mParent->mChildOrderChangedSignal.Emit( handle );
5014 RequestRebuildDepthTree();
5018 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5026 ActorContainer& siblings = *(mParent->mChildren);
5027 if( siblings.front() != this ) // If not already at beginning
5029 for( std::size_t i=1; i<siblings.size(); ++i )
5031 if( siblings[i] == this )
5033 // Swap with previous
5034 ActorPtr previous = siblings[i-1];
5035 siblings[i-1] = this;
5036 siblings[i] = previous;
5042 Dali::Actor handle( this );
5043 mParent->mChildOrderChangedSignal.Emit( handle );
5045 RequestRebuildDepthTree();
5049 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5053 void Actor::RaiseToTop()
5057 ActorContainer& siblings = *(mParent->mChildren);
5058 if( siblings.back() != this ) // If not already at end
5060 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5061 if( iter != siblings.end() )
5063 siblings.erase(iter);
5064 siblings.push_back(ActorPtr(this));
5068 Dali::Actor handle( this );
5069 mParent->mChildOrderChangedSignal.Emit( handle );
5071 RequestRebuildDepthTree();
5075 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5079 void Actor::LowerToBottom()
5083 ActorContainer& siblings = *(mParent->mChildren);
5084 if( siblings.front() != this ) // If not already at bottom,
5086 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5088 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5089 if( iter != siblings.end() )
5091 siblings.erase(iter);
5092 siblings.insert(siblings.begin(), thisPtr);
5096 Dali::Actor handle( this );
5097 mParent->mChildOrderChangedSignal.Emit( handle );
5099 RequestRebuildDepthTree();
5103 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5107 void Actor::RaiseAbove( Internal::Actor& target )
5111 ActorContainer& siblings = *(mParent->mChildren);
5112 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5114 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5116 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5117 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5118 if( thisIter < targetIter )
5120 siblings.erase(thisIter);
5121 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5122 // invalidate thisIter)
5123 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5125 siblings.insert(targetIter, thisPtr);
5128 Dali::Actor handle( this );
5129 mParent->mChildOrderChangedSignal.Emit( handle );
5131 RequestRebuildDepthTree();
5136 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5140 void Actor::LowerBelow( Internal::Actor& target )
5144 ActorContainer& siblings = *(mParent->mChildren);
5145 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5147 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5149 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5150 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5152 if( thisIter > targetIter )
5154 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5155 siblings.insert(targetIter, thisPtr);
5158 Dali::Actor handle( this );
5159 mParent->mChildOrderChangedSignal.Emit( handle );
5161 RequestRebuildDepthTree();
5166 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5170 void Actor::SetScene( Scene& scene )
5175 Scene& Actor::GetScene() const
5180 void Actor::SetInheritLayoutDirection( bool inherit )
5182 if( mInheritLayoutDirection != inherit )
5184 mInheritLayoutDirection = inherit;
5186 if( inherit && mParent )
5188 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5193 bool Actor::IsLayoutDirectionInherited() const
5195 return mInheritLayoutDirection;
5198 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5200 if( actor && ( actor->mInheritLayoutDirection || set ) )
5202 if( actor->mLayoutDirection != direction )
5204 actor->mLayoutDirection = direction;
5205 actor->EmitLayoutDirectionChangedSignal( direction );
5206 actor->RelayoutRequest();
5209 if( actor->GetChildCount() > 0 )
5211 ActorContainer& children = actor->GetChildrenInternal();
5212 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5214 InheritLayoutDirectionRecursively( *iter, direction );
5220 void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint )
5222 // node is being used in a separate thread; queue a message to set the value & base value
5223 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) );
5226 Vector2 Actor::GetUpdateSizeHint() const
5228 // node is being used in a separate thread, the value from the previous update is the same, set by user
5229 Vector3 updateSizeHint = GetNode().GetUpdateSizeHint();
5230 return Vector2( updateSizeHint.width, updateSizeHint.height );
5233 } // namespace Internal