2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-event.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/common/scene-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/animation/constraint-impl.h>
48 #include <dali/internal/event/common/projection.h>
49 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
50 #include <dali/internal/update/common/animatable-property.h>
51 #include <dali/internal/update/nodes/node-messages.h>
52 #include <dali/internal/update/nodes/node-declarations.h>
53 #include <dali/internal/update/animation/scene-graph-constraint.h>
54 #include <dali/internal/event/events/actor-gesture-data.h>
55 #include <dali/internal/common/message.h>
56 #include <dali/integration-api/debug.h>
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::PropertyBase;
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
64 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
75 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
76 inline const Vector3& GetDefaultSizeModeFactor()
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultPreferredSize()
87 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
88 inline const Vector2& GetDefaultDimensionPadding()
93 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
95 } // unnamed namespace
98 * Struct to collect relayout variables
100 struct Actor::RelayoutData
103 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
105 // Set size negotiation defaults
106 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
108 resizePolicies[ i ] = ResizePolicy::DEFAULT;
109 useAssignedSize[ i ] = false;
110 negotiatedDimensions[ i ] = 0.0f;
111 dimensionNegotiated[ i ] = false;
112 dimensionDirty[ i ] = false;
113 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
114 dimensionPadding[ i ] = GetDefaultDimensionPadding();
115 minimumSize[ i ] = 0.0f;
116 maximumSize[ i ] = FLT_MAX;
120 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
121 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
123 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
125 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
127 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
129 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
130 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
132 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
133 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
135 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
137 Vector2 preferredSize; ///< The preferred size of the actor
139 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
141 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
142 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
145 namespace // unnamed namespace
151 * We want to discourage the use of property strings (minimize string comparisons),
152 * particularly for the default properties.
153 * Name Type writable animatable constraint-input enum for index-checking
155 DALI_PROPERTY_TABLE_BEGIN
156 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
157 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
158 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
159 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
160 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
161 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
162 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
163 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
164 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
165 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
166 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
167 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
168 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
169 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
170 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
171 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
172 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
173 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
174 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
175 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
176 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
177 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
178 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
179 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
180 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
181 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
182 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
183 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
184 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
185 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
186 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
187 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
188 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
189 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
190 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
191 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
192 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
193 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
194 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
195 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
196 DALI_PROPERTY( "colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE )
198 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
199 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
200 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
201 DALI_PROPERTY( "sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
202 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
203 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
204 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
205 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
206 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
207 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
208 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
209 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
210 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
211 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY )
212 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION )
213 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT )
214 DALI_PROPERTY( "culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED )
215 DALI_PROPERTY( "id", INTEGER, false, false, false, Dali::Actor::Property::ID )
216 DALI_PROPERTY( "hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH )
217 DALI_PROPERTY( "isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT )
218 DALI_PROPERTY( "isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER )
219 DALI_PROPERTY( "connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE )
220 DALI_PROPERTY( "keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE )
221 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
222 DALI_PROPERTY( "updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT )
223 DALI_PROPERTY( "captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START )
224 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
228 const char* const SIGNAL_HOVERED = "hovered";
229 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
230 const char* const SIGNAL_ON_SCENE = "onScene";
231 const char* const SIGNAL_OFF_SCENE = "offScene";
232 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
233 const char* const SIGNAL_TOUCH = "touch";
234 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
235 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
236 const char* const SIGNAL_CHILD_ADDED = "childAdded";
237 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
241 const char* const ACTION_SHOW = "show";
242 const char* const ACTION_HIDE = "hide";
244 BaseHandle CreateActor()
246 return Dali::Actor::New();
249 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
251 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector4( mType, SIGNAL_ON_SCENE, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_SCENE, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
256 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
257 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
258 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
259 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
260 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
262 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
263 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
268 const Vector3& value;
271 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
276 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
281 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
283 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
284 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
285 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
286 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
287 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
288 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
290 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
293 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
295 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
299 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
300 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
304 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
306 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
307 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
310 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
312 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
315 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
317 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
318 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
319 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
320 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
322 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
324 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
326 uint32_t sizeIgnored = 0;
327 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
329 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
336 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
338 // Values are the same so just use the same table as anchor-point
339 return GetAnchorPointConstant( value, parentOrigin );
343 * @brief Extract a given dimension from a Vector2
345 * @param[in] values The values to extract from
346 * @param[in] dimension The dimension to extract
347 * @return Return the value for the dimension
349 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
353 case Dimension::WIDTH:
357 case Dimension::HEIGHT:
359 return values.height;
370 * @brief Extract a given dimension from a Vector3
372 * @param[in] values The values to extract from
373 * @param[in] dimension The dimension to extract
374 * @return Return the value for the dimension
376 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
378 return GetDimensionValue( values.GetVectorXY(), dimension );
382 * @brief Recursively emits the visibility-changed-signal on the actor tree.
383 * @param[in] actor The actor to emit the signal on
384 * @param[in] visible The new visibility of the actor
385 * @param[in] type Whether the actor's visible property has changed or a parent's
387 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
391 actor->EmitVisibilityChangedSignal( visible, type );
393 if( actor->GetChildCount() > 0 )
395 ActorContainer& children = actor->GetChildrenInternal();
396 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
398 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
404 } // unnamed namespace
406 ActorPtr Actor::New()
408 // pass a reference to actor, actor does not own its node
409 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
411 // Second-phase construction
417 const SceneGraph::Node* Actor::CreateNode()
419 // create node. Nodes are owned by the update manager
420 SceneGraph::Node* node = SceneGraph::Node::New();
421 OwnerPointer< SceneGraph::Node > transferOwnership( node );
422 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
424 DALI_ASSERT_ALWAYS( tls && "ThreadLocalStorage is null" );
426 AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
431 const std::string& Actor::GetName() const
436 void Actor::SetName( const std::string& name )
440 // ATTENTION: string for debug purposes is not thread safe.
441 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
444 uint32_t Actor::GetId() const
446 return GetNode().GetId();
449 bool Actor::OnScene() const
454 Dali::Layer Actor::GetLayer()
458 // Short-circuit for Layer derived actors
461 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
464 // Find the immediate Layer parent
465 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
467 if( parent->IsLayer() )
469 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
476 void Actor::Add( Actor& child )
478 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
479 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
483 mChildren = new ActorContainer;
486 Actor* const oldParent( child.mParent );
488 // child might already be ours
489 if( this != oldParent )
491 // if we already have parent, unparent us first
494 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
496 // Old parent may need to readjust to missing child
497 if( oldParent->RelayoutDependentOnChildren() )
499 oldParent->RelayoutRequest();
503 // Guard against Add() during previous OnChildRemove callback
506 // Do this first, since user callbacks from within SetParent() may need to remove child
507 mChildren->push_back( ActorPtr( &child ) );
509 // SetParent asserts that child can be added
510 child.SetParent( this );
512 // Notification for derived classes
514 EmitChildAddedSignal( child );
516 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
518 // Only put in a relayout request if there is a suitable dependency
519 if( RelayoutDependentOnChildren() )
527 void Actor::Remove( Actor& child )
529 if( (this == &child) || (!mChildren) )
531 // no children or removing itself
537 // Find the child in mChildren, and unparent it
538 ActorIter end = mChildren->end();
539 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
541 ActorPtr actor = (*iter);
543 if( actor.Get() == &child )
545 // Keep handle for OnChildRemove notification
548 // Do this first, since user callbacks from within SetParent() may need to add the child
549 mChildren->erase( iter );
551 DALI_ASSERT_DEBUG( actor->GetParent() == this );
552 actor->SetParent( NULL );
560 // Only put in a relayout request if there is a suitable dependency
561 if( RelayoutDependentOnChildren() )
567 // Notification for derived classes
568 OnChildRemove( child );
569 EmitChildRemovedSignal( child );
572 void Actor::Unparent()
576 // Remove this actor from the parent. The remove will put a relayout request in for
577 // the parent if required
578 mParent->Remove( *this );
579 // mParent is now NULL!
583 uint32_t Actor::GetChildCount() const
585 return ( NULL != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
588 ActorPtr Actor::GetChildAt( uint32_t index ) const
590 DALI_ASSERT_ALWAYS( index < GetChildCount() );
592 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
595 ActorPtr Actor::FindChildByName( const std::string& actorName )
598 if( actorName == mName )
604 ActorIter end = mChildren->end();
605 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
607 child = (*iter)->FindChildByName( actorName );
618 ActorPtr Actor::FindChildById( const uint32_t id )
627 ActorIter end = mChildren->end();
628 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
630 child = (*iter)->FindChildById( id );
641 void Actor::SetParentOrigin( const Vector3& origin )
643 // node is being used in a separate thread; queue a message to set the value & base value
644 SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
646 // Cache for event-thread access
649 // not allocated, check if different from default
650 if( ParentOrigin::DEFAULT != origin )
652 mParentOrigin = new Vector3( origin );
657 // check if different from current costs more than just set
658 *mParentOrigin = origin;
662 void Actor::SetParentOriginX( float x )
664 const Vector3& current = GetCurrentParentOrigin();
666 SetParentOrigin( Vector3( x, current.y, current.z ) );
669 void Actor::SetParentOriginY( float y )
671 const Vector3& current = GetCurrentParentOrigin();
673 SetParentOrigin( Vector3( current.x, y, current.z ) );
676 void Actor::SetParentOriginZ( float z )
678 const Vector3& current = GetCurrentParentOrigin();
680 SetParentOrigin( Vector3( current.x, current.y, z ) );
683 const Vector3& Actor::GetCurrentParentOrigin() const
685 // Cached for event-thread access
686 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
689 void Actor::SetAnchorPoint( const Vector3& anchor )
691 // node is being used in a separate thread; queue a message to set the value & base value
692 SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
694 // Cache for event-thread access
697 // not allocated, check if different from default
698 if( AnchorPoint::DEFAULT != anchor )
700 mAnchorPoint = new Vector3( anchor );
705 // check if different from current costs more than just set
706 *mAnchorPoint = anchor;
710 void Actor::SetAnchorPointX( float x )
712 const Vector3& current = GetCurrentAnchorPoint();
714 SetAnchorPoint( Vector3( x, current.y, current.z ) );
717 void Actor::SetAnchorPointY( float y )
719 const Vector3& current = GetCurrentAnchorPoint();
721 SetAnchorPoint( Vector3( current.x, y, current.z ) );
724 void Actor::SetAnchorPointZ( float z )
726 const Vector3& current = GetCurrentAnchorPoint();
728 SetAnchorPoint( Vector3( current.x, current.y, z ) );
731 const Vector3& Actor::GetCurrentAnchorPoint() const
733 // Cached for event-thread access
734 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
737 void Actor::SetPosition( float x, float y )
739 SetPosition( Vector3( x, y, 0.0f ) );
742 void Actor::SetPosition( float x, float y, float z )
744 SetPosition( Vector3( x, y, z ) );
747 void Actor::SetPosition( const Vector3& position )
749 mTargetPosition = position;
751 // node is being used in a separate thread; queue a message to set the value & base value
752 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
755 void Actor::SetX( float x )
757 mTargetPosition.x = x;
759 // node is being used in a separate thread; queue a message to set the value & base value
760 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
763 void Actor::SetY( float y )
765 mTargetPosition.y = y;
767 // node is being used in a separate thread; queue a message to set the value & base value
768 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
771 void Actor::SetZ( float z )
773 mTargetPosition.z = z;
775 // node is being used in a separate thread; queue a message to set the value & base value
776 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
779 void Actor::TranslateBy( const Vector3& distance )
781 mTargetPosition += distance;
783 // node is being used in a separate thread; queue a message to set the value & base value
784 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
787 const Vector3& Actor::GetCurrentPosition() const
789 // node is being used in a separate thread; copy the value from the previous update
790 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
793 const Vector3& Actor::GetTargetPosition() const
795 return mTargetPosition;
798 const Vector3& Actor::GetCurrentWorldPosition() const
800 // node is being used in a separate thread; copy the value from the previous update
801 return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
804 const Vector2 Actor::GetCurrentScreenPosition() const
806 if( mScene && OnScene() )
808 Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
809 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
810 worldPosition -= cameraPosition;
812 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
813 Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
814 Vector3 halfActorSize( actorSize * 0.5f );
815 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
817 return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
818 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
821 return Vector2::ZERO;
824 void Actor::SetInheritPosition( bool inherit )
826 if( mInheritPosition != inherit )
828 // non animatable so keep local copy
829 mInheritPosition = inherit;
830 SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
834 bool Actor::IsPositionInherited() const
836 return mInheritPosition;
839 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
841 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
842 normalizedAxis.Normalize();
844 Quaternion orientation( angle, normalizedAxis );
846 SetOrientation( orientation );
849 void Actor::SetOrientation( const Quaternion& orientation )
851 mTargetOrientation = orientation;
853 // node is being used in a separate thread; queue a message to set the value & base value
854 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
857 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
859 RotateBy( Quaternion(angle, axis) );
862 void Actor::RotateBy( const Quaternion& relativeRotation )
864 mTargetOrientation *= Quaternion( relativeRotation );
866 // node is being used in a separate thread; queue a message to set the value & base value
867 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
870 const Quaternion& Actor::GetCurrentOrientation() const
872 // node is being used in a separate thread; copy the value from the previous update
873 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
876 const Quaternion& Actor::GetCurrentWorldOrientation() const
878 // node is being used in a separate thread; copy the value from the previous update
879 return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
882 void Actor::SetScale( float scale )
884 SetScale( Vector3( scale, scale, scale ) );
887 void Actor::SetScale( float x, float y, float z )
889 SetScale( Vector3( x, y, z ) );
892 void Actor::SetScale( const Vector3& scale )
894 mTargetScale = scale;
896 // node is being used in a separate thread; queue a message to set the value & base value
897 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
900 void Actor::SetScaleX( float x )
904 // node is being used in a separate thread; queue a message to set the value & base value
905 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
908 void Actor::SetScaleY( float y )
912 // node is being used in a separate thread; queue a message to set the value & base value
913 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
916 void Actor::SetScaleZ( float z )
920 // node is being used in a separate thread; queue a message to set the value & base value
921 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
924 void Actor::ScaleBy(const Vector3& relativeScale)
926 mTargetScale *= relativeScale;
928 // node is being used in a separate thread; queue a message to set the value & base value
929 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
932 const Vector3& Actor::GetCurrentScale() const
934 // node is being used in a separate thread; copy the value from the previous update
935 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
938 const Vector3& Actor::GetCurrentWorldScale() const
940 // node is being used in a separate thread; copy the value from the previous update
941 return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
944 void Actor::SetInheritScale( bool inherit )
946 if( mInheritScale != inherit )
948 // non animatable so keep local copy
949 mInheritScale = inherit;
950 // node is being used in a separate thread; queue a message to set the value
951 SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
955 bool Actor::IsScaleInherited() const
957 return mInheritScale;
960 Matrix Actor::GetCurrentWorldMatrix() const
962 return GetNode().GetWorldMatrix(0);
965 void Actor::SetVisible( bool visible )
967 SetVisibleInternal( visible, SendMessage::TRUE );
970 bool Actor::IsVisible() const
972 // node is being used in a separate thread; copy the value from the previous update
973 return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
976 void Actor::SetOpacity( float opacity )
978 mTargetColor.a = opacity;
980 // node is being used in a separate thread; queue a message to set the value & base value
981 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
984 float Actor::GetCurrentOpacity() const
986 // node is being used in a separate thread; copy the value from the previous update
987 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
990 ClippingMode::Type Actor::GetClippingMode() const
992 return mClippingMode;
995 uint32_t Actor::GetSortingDepth()
1000 const Vector4& Actor::GetCurrentWorldColor() const
1002 return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1005 void Actor::SetColor( const Vector4& color )
1007 mTargetColor = color;
1009 // node is being used in a separate thread; queue a message to set the value & base value
1010 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
1013 void Actor::SetColorRed( float red )
1015 mTargetColor.r = red;
1017 // node is being used in a separate thread; queue a message to set the value & base value
1018 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
1021 void Actor::SetColorGreen( float green )
1023 mTargetColor.g = green;
1025 // node is being used in a separate thread; queue a message to set the value & base value
1026 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green );
1029 void Actor::SetColorBlue( float blue )
1031 mTargetColor.b = blue;
1033 // node is being used in a separate thread; queue a message to set the value & base value
1034 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1037 const Vector4& Actor::GetCurrentColor() const
1039 // node is being used in a separate thread; copy the value from the previous update
1040 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
1043 void Actor::SetInheritOrientation( bool inherit )
1045 if( mInheritOrientation != inherit )
1047 // non animatable so keep local copy
1048 mInheritOrientation = inherit;
1049 // node is being used in a separate thread; queue a message to set the value
1050 SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
1054 bool Actor::IsOrientationInherited() const
1056 return mInheritOrientation;
1059 void Actor::SetSizeModeFactor( const Vector3& factor )
1061 EnsureRelayoutData();
1063 mRelayoutData->sizeModeFactor = factor;
1066 const Vector3& Actor::GetSizeModeFactor() const
1068 if ( mRelayoutData )
1070 return mRelayoutData->sizeModeFactor;
1073 return GetDefaultSizeModeFactor();
1076 void Actor::SetColorMode( ColorMode colorMode )
1078 // non animatable so keep local copy
1079 mColorMode = colorMode;
1080 // node is being used in a separate thread; queue a message to set the value
1081 SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
1084 ColorMode Actor::GetColorMode() const
1086 // we have cached copy
1090 void Actor::SetSize( float width, float height )
1092 SetSize( Vector2( width, height ) );
1095 void Actor::SetSize( float width, float height, float depth )
1097 SetSize( Vector3( width, height, depth ) );
1100 void Actor::SetSize( const Vector2& size )
1102 SetSize( Vector3( size.width, size.height, 0.f ) );
1105 void Actor::SetSizeInternal( const Vector2& size )
1107 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1110 void Actor::SetSize( const Vector3& size )
1112 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1114 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1115 SetPreferredSize( size.GetVectorXY() );
1119 SetSizeInternal( size );
1123 void Actor::SetSizeInternal( const Vector3& size )
1125 // dont allow recursive loop
1126 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1127 // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
1128 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1129 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1130 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1134 // node is being used in a separate thread; queue a message to set the value & base value
1135 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1137 // Notification for derived classes
1138 mInsideOnSizeSet = true;
1139 OnSizeSet( mTargetSize );
1140 mInsideOnSizeSet = false;
1142 // Raise a relayout request if the flag is not locked
1143 if( mRelayoutData && !mRelayoutData->insideRelayout )
1150 void Actor::SetWidth( float width )
1152 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1154 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1155 mRelayoutData->preferredSize.width = width;
1159 mTargetSize.width = width;
1161 // node is being used in a separate thread; queue a message to set the value & base value
1162 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1165 mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
1170 void Actor::SetHeight( float height )
1172 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1174 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1175 mRelayoutData->preferredSize.height = height;
1179 mTargetSize.height = height;
1181 // node is being used in a separate thread; queue a message to set the value & base value
1182 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1185 mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
1190 void Actor::SetDepth( float depth )
1192 mTargetSize.depth = depth;
1194 mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
1196 // node is being used in a separate thread; queue a message to set the value & base value
1197 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1200 Vector3 Actor::GetTargetSize() const
1202 Vector3 size = mTargetSize;
1204 if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH )
1206 // Should return animated size if size is animated
1207 size.width = mAnimatedSize.width;
1211 // Should return preferred size if size is fixed as set by SetSize
1212 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1214 size.width = GetPreferredSize().width;
1218 if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT )
1220 size.height = mAnimatedSize.height;
1224 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1226 size.height = GetPreferredSize().height;
1230 if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH )
1232 size.depth = mAnimatedSize.depth;
1238 const Vector3& Actor::GetCurrentSize() const
1240 // node is being used in a separate thread; copy the value from the previous update
1241 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1244 Vector3 Actor::GetNaturalSize() const
1246 // It is up to deriving classes to return the appropriate natural size
1247 return Vector3( 0.0f, 0.0f, 0.0f );
1250 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1252 EnsureRelayoutData();
1254 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1255 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1257 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1259 if( dimension & ( 1 << i ) )
1261 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1263 mRelayoutData->useAssignedSize[ i ] = true;
1267 mRelayoutData->resizePolicies[ i ] = policy;
1268 mRelayoutData->useAssignedSize[ i ] = false;
1273 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1275 if( dimension & Dimension::WIDTH )
1277 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1280 if( dimension & Dimension::HEIGHT )
1282 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1286 // If calling SetResizePolicy, assume we want relayout enabled
1287 SetRelayoutEnabled( true );
1289 // If the resize policy is set to be FIXED, the preferred size
1290 // should be overrided by the target size. Otherwise the target
1291 // size should be overrided by the preferred size.
1293 if( dimension & Dimension::WIDTH )
1295 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1297 mRelayoutData->preferredSize.width = mTargetSize.width;
1299 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1301 mTargetSize.width = mRelayoutData->preferredSize.width;
1305 if( dimension & Dimension::HEIGHT )
1307 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1309 mRelayoutData->preferredSize.height = mTargetSize.height;
1311 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1313 mTargetSize.height = mRelayoutData->preferredSize.height;
1317 OnSetResizePolicy( policy, dimension );
1319 // Trigger relayout on this control
1323 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1325 if ( mRelayoutData )
1327 // If more than one dimension is requested, just return the first one found
1328 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1330 if( ( dimension & ( 1 << i ) ) )
1332 if( mRelayoutData->useAssignedSize[ i ] )
1334 return ResizePolicy::USE_ASSIGNED_SIZE;
1338 return mRelayoutData->resizePolicies[ i ];
1344 return ResizePolicy::DEFAULT;
1347 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1349 EnsureRelayoutData();
1351 mRelayoutData->sizeSetPolicy = policy;
1353 // Trigger relayout on this control
1357 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1359 if ( mRelayoutData )
1361 return mRelayoutData->sizeSetPolicy;
1364 return DEFAULT_SIZE_SCALE_POLICY;
1367 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1369 EnsureRelayoutData();
1371 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1373 if( dimension & ( 1 << i ) )
1375 mRelayoutData->dimensionDependencies[ i ] = dependency;
1380 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1382 if ( mRelayoutData )
1384 // If more than one dimension is requested, just return the first one found
1385 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1387 if( ( dimension & ( 1 << i ) ) )
1389 return mRelayoutData->dimensionDependencies[ i ];
1394 return Dimension::ALL_DIMENSIONS; // Default
1397 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1399 // If relayout data has not been allocated yet and the client is requesting
1400 // to disable it, do nothing
1401 if( mRelayoutData || relayoutEnabled )
1403 EnsureRelayoutData();
1405 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1407 mRelayoutData->relayoutEnabled = relayoutEnabled;
1411 bool Actor::IsRelayoutEnabled() const
1413 // Assume that if relayout data has not been allocated yet then
1414 // relayout is disabled
1415 return mRelayoutData && mRelayoutData->relayoutEnabled;
1418 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1420 EnsureRelayoutData();
1422 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1424 if( dimension & ( 1 << i ) )
1426 mRelayoutData->dimensionDirty[ i ] = dirty;
1431 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1433 if ( mRelayoutData )
1435 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1437 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1447 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1449 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1452 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1454 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1457 uint32_t Actor::AddRenderer( Renderer& renderer )
1461 mRenderers = new RendererContainer;
1464 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1465 RendererPtr rendererPtr = RendererPtr( &renderer );
1466 mRenderers->push_back( rendererPtr );
1467 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1471 uint32_t Actor::GetRendererCount() const
1473 uint32_t rendererCount(0);
1476 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1479 return rendererCount;
1482 RendererPtr Actor::GetRendererAt( uint32_t index )
1484 RendererPtr renderer;
1485 if( index < GetRendererCount() )
1487 renderer = ( *mRenderers )[ index ];
1493 void Actor::RemoveRenderer( Renderer& renderer )
1497 RendererIter end = mRenderers->end();
1498 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1500 if( (*iter).Get() == &renderer )
1502 mRenderers->erase( iter );
1503 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1510 void Actor::RemoveRenderer( uint32_t index )
1512 if( index < GetRendererCount() )
1514 RendererPtr renderer = ( *mRenderers )[ index ];
1515 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1516 mRenderers->erase( mRenderers->begin()+index );
1520 bool Actor::IsOverlay() const
1522 return ( DrawMode::OVERLAY_2D == mDrawMode );
1525 void Actor::SetDrawMode( DrawMode::Type drawMode )
1527 // this flag is not animatable so keep the value
1528 mDrawMode = drawMode;
1530 // node is being used in a separate thread; queue a message to set the value
1531 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1534 DrawMode::Type Actor::GetDrawMode() const
1539 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1541 // only valid when on-stage
1542 if( mScene && OnScene() )
1544 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1546 Vector2 converted( screenX, screenY );
1548 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1549 uint32_t taskCount = taskList.GetTaskCount();
1550 for( uint32_t i = taskCount; i > 0; --i )
1552 RenderTaskPtr task = taskList.GetTask( i - 1 );
1553 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1555 // found a task where this conversion was ok so return
1563 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1565 bool retval = false;
1566 // only valid when on-stage
1569 CameraActor* camera = renderTask.GetCameraActor();
1573 renderTask.GetViewport( viewport );
1575 // need to translate coordinates to render tasks coordinate space
1576 Vector2 converted( screenX, screenY );
1577 if( renderTask.TranslateCoordinates( converted ) )
1579 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1586 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1588 // Early-out if not on stage
1594 // Get the ModelView matrix
1596 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1598 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1599 Matrix invertedMvp( false/*don't init*/);
1600 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1601 bool success = invertedMvp.Invert();
1603 // Convert to GL coordinates
1604 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1609 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1616 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1622 if( XyPlaneIntersect( nearPos, farPos, local ) )
1624 Vector3 size = GetCurrentSize();
1625 localX = local.x + size.x * 0.5f;
1626 localY = local.y + size.y * 0.5f;
1637 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1640 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1642 Mathematical Formulation
1644 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1646 ( p - c ) dot ( p - c ) = r^2
1648 Given a ray with a point of origin 'o', and a direction vector 'd':
1650 ray(t) = o + td, t >= 0
1652 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1654 (o + td - c ) dot ( o + td - c ) = r^2
1656 To solve for t we first expand the above into a more recognisable quadratic equation form
1658 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1667 B = 2( o - c ) dot d
1668 C = ( o - c ) dot ( o - c ) - r^2
1670 which can be solved using a standard quadratic formula.
1672 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1674 Practical Simplification
1676 In a renderer, we often differentiate between world space and object space. In the object space
1677 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1678 into object space, the mathematical solution presented above can be simplified significantly.
1680 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1684 and we can find the t at which the (transformed) ray intersects the sphere by
1686 ( o + td ) dot ( o + td ) = r^2
1688 According to the reasoning above, we expand the above quadratic equation into the general form
1692 which now has coefficients:
1699 // Early-out if not on stage
1705 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1707 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1708 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1709 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1711 // Compute the radius is not needed, square radius it's enough.
1712 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1714 // Scale the sphere.
1715 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1717 const float width = size.width * scale.width;
1718 const float height = size.height * scale.height;
1720 float squareSphereRadius = 0.5f * ( width * width + height * height );
1722 float a = rayDir.Dot( rayDir ); // a
1723 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1724 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1726 return ( b2 * b2 - a * c ) >= 0.f;
1729 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1735 // Transforms the ray to the local reference system.
1736 // Calculate the inverse of Model matrix
1737 Matrix invModelMatrix( false/*don't init*/);
1739 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1740 invModelMatrix = GetNode().GetWorldMatrix(0);
1741 invModelMatrix.Invert();
1743 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1744 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1746 // Test with the actor's XY plane (Normal = 0 0 1 1).
1748 float a = -rayOriginLocal.z;
1749 float b = rayDirLocal.z;
1751 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1753 // Ray travels distance * rayDirLocal to intersect with plane.
1756 const Vector3& size = GetNode().GetSize( bufferIndex );
1758 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1759 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1761 // Test with the actor's geometry.
1762 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1769 void Actor::SetLeaveRequired( bool required )
1771 mLeaveRequired = required;
1774 bool Actor::GetLeaveRequired() const
1776 return mLeaveRequired;
1779 void Actor::SetKeyboardFocusable( bool focusable )
1781 mKeyboardFocusable = focusable;
1784 bool Actor::IsKeyboardFocusable() const
1786 return mKeyboardFocusable;
1789 bool Actor::GetTouchRequired() const
1791 return !mTouchSignal.Empty() || mDerivedRequiresTouch;
1794 bool Actor::GetHoverRequired() const
1796 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1799 bool Actor::GetWheelEventRequired() const
1801 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1804 bool Actor::IsHittable() const
1806 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1809 ActorGestureData& Actor::GetGestureData()
1811 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1812 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1813 if( NULL == mGestureData )
1815 mGestureData = new ActorGestureData;
1817 return *mGestureData;
1820 bool Actor::IsGestureRequred( Gesture::Type type ) const
1822 return mGestureData && mGestureData->IsGestureRequred( type );
1825 bool Actor::EmitTouchEventSignal( const Dali::TouchEvent& touch )
1827 bool consumed = false;
1829 if( !mTouchSignal.Empty() )
1831 Dali::Actor handle( this );
1832 consumed = mTouchSignal.Emit( handle, touch );
1838 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1840 bool consumed = false;
1842 if( !mHoveredSignal.Empty() )
1844 Dali::Actor handle( this );
1845 consumed = mHoveredSignal.Emit( handle, event );
1850 // Notification for derived classes
1851 consumed = OnHoverEvent( event );
1857 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1859 bool consumed = false;
1861 if( !mWheelEventSignal.Empty() )
1863 Dali::Actor handle( this );
1864 consumed = mWheelEventSignal.Emit( handle, event );
1869 // Notification for derived classes
1870 consumed = OnWheelEvent( event );
1876 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1878 if( ! mVisibilityChangedSignal.Empty() )
1880 Dali::Actor handle( this );
1881 mVisibilityChangedSignal.Emit( handle, visible, type );
1885 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1887 if( ! mLayoutDirectionChangedSignal.Empty() )
1889 Dali::Actor handle( this );
1890 mLayoutDirectionChangedSignal.Emit( handle, type );
1894 void Actor::EmitChildAddedSignal( Actor& child )
1896 if( ! mChildAddedSignal.Empty() )
1898 Dali::Actor handle( &child );
1899 mChildAddedSignal.Emit( handle );
1903 void Actor::EmitChildRemovedSignal( Actor& child )
1905 if( ! mChildRemovedSignal.Empty() )
1907 Dali::Actor handle( &child );
1908 mChildRemovedSignal.Emit( handle );
1912 Dali::Actor::TouchEventSignalType& Actor::TouchSignal()
1914 return mTouchSignal;
1917 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1919 return mHoveredSignal;
1922 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1924 return mWheelEventSignal;
1927 Dali::Actor::OnSceneSignalType& Actor::OnSceneSignal()
1929 return mOnSceneSignal;
1932 Dali::Actor::OffSceneSignalType& Actor::OffSceneSignal()
1934 return mOffSceneSignal;
1937 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1939 return mOnRelayoutSignal;
1942 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1944 return mVisibilityChangedSignal;
1947 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1949 return mLayoutDirectionChangedSignal;
1952 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1954 return mChildAddedSignal;
1957 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1959 return mChildRemovedSignal;
1962 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1964 return mChildOrderChangedSignal;
1967 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1969 bool connected( true );
1970 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1972 if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1974 actor->HoveredSignal().Connect( tracker, functor );
1976 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1978 actor->WheelEventSignal().Connect( tracker, functor );
1980 else if( 0 == signalName.compare( SIGNAL_ON_SCENE ) )
1982 actor->OnSceneSignal().Connect( tracker, functor );
1984 else if( 0 == signalName.compare( SIGNAL_OFF_SCENE ) )
1986 actor->OffSceneSignal().Connect( tracker, functor );
1988 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1990 actor->OnRelayoutSignal().Connect( tracker, functor );
1992 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1994 actor->TouchSignal().Connect( tracker, functor );
1996 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
1998 actor->VisibilityChangedSignal().Connect( tracker, functor );
2000 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2002 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2004 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2006 actor->ChildAddedSignal().Connect( tracker, functor );
2008 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2010 actor->ChildRemovedSignal().Connect( tracker, functor );
2014 // signalName does not match any signal
2021 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2027 mParentOrigin( NULL ),
2028 mAnchorPoint( NULL ),
2029 mRelayoutData( NULL ),
2030 mGestureData( NULL ),
2033 mWheelEventSignal(),
2036 mOnRelayoutSignal(),
2037 mVisibilityChangedSignal(),
2038 mLayoutDirectionChangedSignal(),
2039 mChildAddedSignal(),
2040 mChildRemovedSignal(),
2041 mChildOrderChangedSignal(),
2042 mTargetOrientation( Quaternion::IDENTITY ),
2043 mTargetColor( Color::WHITE ),
2044 mTargetSize( Vector3::ZERO ),
2045 mTargetPosition( Vector3::ZERO ),
2046 mTargetScale( Vector3::ONE ),
2047 mAnimatedSize( Vector3::ZERO ),
2051 mUseAnimatedSize( AnimatedSizeFlag::CLEAR ),
2052 mIsRoot( ROOT_LAYER == derivedType ),
2053 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2054 mIsOnScene( false ),
2056 mLeaveRequired( false ),
2057 mKeyboardFocusable( false ),
2058 mDerivedRequiresTouch( false ),
2059 mDerivedRequiresHover( false ),
2060 mDerivedRequiresWheelEvent( false ),
2061 mOnSceneSignalled( false ),
2062 mInsideOnSizeSet( false ),
2063 mInheritPosition( true ),
2064 mInheritOrientation( true ),
2065 mInheritScale( true ),
2066 mPositionUsesAnchorPoint( true ),
2068 mInheritLayoutDirection( true ),
2069 mCaptureAllTouchAfterStart( false ),
2070 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2071 mDrawMode( DrawMode::NORMAL ),
2072 mColorMode( Node::DEFAULT_COLOR_MODE ),
2073 mClippingMode( ClippingMode::DISABLED )
2077 void Actor::Initialize()
2081 GetEventThreadServices().RegisterObject( this );
2086 // Remove mParent pointers from children even if we're destroying core,
2087 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2090 ActorConstIter endIter = mChildren->end();
2091 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2093 (*iter)->SetParent( NULL );
2099 // Guard to allow handle destruction after Core has been destroyed
2100 if( EventThreadServices::IsCoreRunning() )
2102 // Root layer will destroy its node in its own destructor
2105 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2107 GetEventThreadServices().UnregisterObject( this );
2111 // Cleanup optional gesture data
2112 delete mGestureData;
2114 // Cleanup optional parent origin and anchor
2115 delete mParentOrigin;
2116 delete mAnchorPoint;
2118 // Delete optional relayout data
2119 delete mRelayoutData;
2122 void Actor::ConnectToScene( uint32_t parentDepth )
2124 // This container is used instead of walking the Actor hierarchy.
2125 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
2126 ActorContainer connectionList;
2130 mScene->RequestRebuildDepthTree();
2133 // This stage is atomic i.e. not interrupted by user callbacks.
2134 RecursiveConnectToScene( connectionList, parentDepth + 1 );
2136 // Notify applications about the newly connected actors.
2137 const ActorIter endIter = connectionList.end();
2138 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2140 (*iter)->NotifyStageConnection();
2146 void Actor::RecursiveConnectToScene( ActorContainer& connectionList, uint32_t depth )
2148 DALI_ASSERT_ALWAYS( !OnScene() );
2151 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2153 ConnectToSceneGraph();
2155 // Notification for internal derived classes
2156 OnSceneConnectionInternal();
2158 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2159 connectionList.push_back( ActorPtr( this ) );
2161 // Recursively connect children
2164 ActorConstIter endIter = mChildren->end();
2165 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2167 (*iter)->SetScene( *mScene );
2168 (*iter)->RecursiveConnectToScene( connectionList, depth + 1 );
2174 * This method is called when the Actor is connected to the Stage.
2175 * The parent must have added its Node to the scene-graph.
2176 * The child must connect its Node to the parent's Node.
2177 * This is recursive; the child calls ConnectToScene() for its children.
2179 void Actor::ConnectToSceneGraph()
2181 DALI_ASSERT_DEBUG( mParent != NULL);
2183 // Reparent Node in next Update
2184 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2186 // Request relayout on all actors that are added to the scenegraph
2189 // Notification for Object::Observers
2193 void Actor::NotifyStageConnection()
2195 // Actors can be removed (in a callback), before the on-stage stage is reported.
2196 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
2197 if( OnScene() && !mOnSceneSignalled )
2199 // Notification for external (CustomActor) derived classes
2200 OnSceneConnectionExternal( mDepth );
2202 if( !mOnSceneSignal.Empty() )
2204 Dali::Actor handle( this );
2205 mOnSceneSignal.Emit( handle );
2208 // Guard against Remove during callbacks
2211 mOnSceneSignalled = true; // signal required next time Actor is removed
2216 void Actor::DisconnectFromStage()
2218 // This container is used instead of walking the Actor hierachy.
2219 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
2220 ActorContainer disconnectionList;
2224 mScene->RequestRebuildDepthTree();
2227 // This stage is atomic i.e. not interrupted by user callbacks
2228 RecursiveDisconnectFromStage( disconnectionList );
2230 // Notify applications about the newly disconnected actors.
2231 const ActorIter endIter = disconnectionList.end();
2232 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2234 (*iter)->NotifyStageDisconnection();
2238 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2240 // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
2243 // Recursively disconnect children
2246 ActorConstIter endIter = mChildren->end();
2247 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2249 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2253 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2254 disconnectionList.push_back( ActorPtr( this ) );
2256 // Notification for internal derived classes
2257 OnSceneDisconnectionInternal();
2259 DisconnectFromSceneGraph();
2263 * This method is called by an actor or its parent, before a node removal message is sent.
2264 * This is recursive; the child calls DisconnectFromStage() for its children.
2266 void Actor::DisconnectFromSceneGraph()
2268 // Notification for Object::Observers
2269 OnSceneObjectRemove();
2272 void Actor::NotifyStageDisconnection()
2274 // Actors can be added (in a callback), before the off-stage state is reported.
2275 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
2276 // only do this step if there is a stage, i.e. Core is not being shut down
2277 if ( EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled )
2279 // Notification for external (CustomeActor) derived classes
2280 OnSceneDisconnectionExternal();
2282 if( !mOffSceneSignal.Empty() )
2284 Dali::Actor handle( this );
2285 mOffSceneSignal.Emit( handle );
2288 // Guard against Add during callbacks
2291 mOnSceneSignalled = false; // signal required next time Actor is added
2296 bool Actor::IsNodeConnected() const
2298 bool connected( false );
2302 if( IsRoot() || GetNode().GetParent() )
2311 // This method initiates traversal of the actor tree using depth-first
2312 // traversal to set a depth index based on traversal order. It sends a
2313 // single message to update manager to update all the actor's nodes in
2314 // this tree with the depth index. The sceneGraphNodeDepths vector's
2315 // elements are ordered by depth, and could be used to reduce sorting
2316 // in the update thread.
2317 void Actor::RebuildDepthTree()
2319 DALI_LOG_TIMER_START(depthTimer);
2321 // Vector of scene-graph nodes and their depths to send to UpdateManager
2322 // in a single message
2323 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2325 int32_t depthIndex = 1;
2326 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2328 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2329 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2332 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2334 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2335 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2337 // Create/add to children of this node
2340 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2342 Actor* childActor = (*it).Get();
2344 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2349 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2353 case Dali::Actor::Property::PARENT_ORIGIN:
2355 Property::Type type = property.GetType();
2356 if( type == Property::VECTOR3 )
2358 SetParentOrigin( property.Get< Vector3 >() );
2360 else if ( type == Property::STRING )
2362 std::string parentOriginString;
2363 property.Get( parentOriginString );
2364 Vector3 parentOrigin;
2365 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2367 SetParentOrigin( parentOrigin );
2373 case Dali::Actor::Property::PARENT_ORIGIN_X:
2375 SetParentOriginX( property.Get< float >() );
2379 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2381 SetParentOriginY( property.Get< float >() );
2385 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2387 SetParentOriginZ( property.Get< float >() );
2391 case Dali::Actor::Property::ANCHOR_POINT:
2393 Property::Type type = property.GetType();
2394 if( type == Property::VECTOR3 )
2396 SetAnchorPoint( property.Get< Vector3 >() );
2398 else if ( type == Property::STRING )
2400 std::string anchorPointString;
2401 property.Get( anchorPointString );
2403 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2405 SetAnchorPoint( anchor );
2411 case Dali::Actor::Property::ANCHOR_POINT_X:
2413 SetAnchorPointX( property.Get< float >() );
2417 case Dali::Actor::Property::ANCHOR_POINT_Y:
2419 SetAnchorPointY( property.Get< float >() );
2423 case Dali::Actor::Property::ANCHOR_POINT_Z:
2425 SetAnchorPointZ( property.Get< float >() );
2429 case Dali::Actor::Property::SIZE:
2431 Property::Type type = property.GetType();
2432 if( type == Property::VECTOR2 )
2434 SetSize( property.Get< Vector2 >() );
2436 else if ( type == Property::VECTOR3 )
2438 SetSize( property.Get< Vector3 >() );
2443 case Dali::Actor::Property::SIZE_WIDTH:
2445 SetWidth( property.Get< float >() );
2449 case Dali::Actor::Property::SIZE_HEIGHT:
2451 SetHeight( property.Get< float >() );
2455 case Dali::Actor::Property::SIZE_DEPTH:
2457 SetDepth( property.Get< float >() );
2461 case Dali::Actor::Property::POSITION:
2463 Property::Type type = property.GetType();
2464 if( type == Property::VECTOR2 )
2466 Vector2 position = property.Get< Vector2 >();
2467 SetPosition( Vector3( position.x, position.y, 0.0f ) );
2469 else if ( type == Property::VECTOR3 )
2471 SetPosition( property.Get< Vector3 >() );
2476 case Dali::Actor::Property::POSITION_X:
2478 SetX( property.Get< float >() );
2482 case Dali::Actor::Property::POSITION_Y:
2484 SetY( property.Get< float >() );
2488 case Dali::Actor::Property::POSITION_Z:
2490 SetZ( property.Get< float >() );
2494 case Dali::Actor::Property::ORIENTATION:
2496 SetOrientation( property.Get< Quaternion >() );
2500 case Dali::Actor::Property::SCALE:
2502 Property::Type type = property.GetType();
2503 if( type == Property::FLOAT )
2505 float scale = property.Get< float >();
2506 SetScale( scale, scale, scale );
2508 else if ( type == Property::VECTOR3 )
2510 SetScale( property.Get< Vector3 >() );
2515 case Dali::Actor::Property::SCALE_X:
2517 SetScaleX( property.Get< float >() );
2521 case Dali::Actor::Property::SCALE_Y:
2523 SetScaleY( property.Get< float >() );
2527 case Dali::Actor::Property::SCALE_Z:
2529 SetScaleZ( property.Get< float >() );
2533 case Dali::Actor::Property::VISIBLE:
2535 SetVisible( property.Get< bool >() );
2539 case Dali::Actor::Property::COLOR:
2541 Property::Type type = property.GetType();
2542 if( type == Property::VECTOR3 )
2544 Vector3 color = property.Get< Vector3 >();
2545 SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2547 else if( type == Property::VECTOR4 )
2549 SetColor( property.Get< Vector4 >() );
2554 case Dali::Actor::Property::COLOR_RED:
2556 SetColorRed( property.Get< float >() );
2560 case Dali::Actor::Property::COLOR_GREEN:
2562 SetColorGreen( property.Get< float >() );
2566 case Dali::Actor::Property::COLOR_BLUE:
2568 SetColorBlue( property.Get< float >() );
2572 case Dali::Actor::Property::COLOR_ALPHA:
2573 case Dali::Actor::Property::OPACITY:
2576 if( property.Get( value ) )
2578 SetOpacity( value );
2583 case Dali::Actor::Property::NAME:
2585 SetName( property.Get< std::string >() );
2589 case Dali::Actor::Property::SENSITIVE:
2591 SetSensitive( property.Get< bool >() );
2595 case Dali::Actor::Property::LEAVE_REQUIRED:
2597 SetLeaveRequired( property.Get< bool >() );
2601 case Dali::Actor::Property::INHERIT_POSITION:
2603 SetInheritPosition( property.Get< bool >() );
2607 case Dali::Actor::Property::INHERIT_ORIENTATION:
2609 SetInheritOrientation( property.Get< bool >() );
2613 case Dali::Actor::Property::INHERIT_SCALE:
2615 SetInheritScale( property.Get< bool >() );
2619 case Dali::Actor::Property::COLOR_MODE:
2621 ColorMode mode = mColorMode;
2622 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2624 SetColorMode( mode );
2629 case Dali::Actor::Property::DRAW_MODE:
2631 DrawMode::Type mode = mDrawMode;
2632 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2634 SetDrawMode( mode );
2639 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2641 SetSizeModeFactor( property.Get< Vector3 >() );
2645 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2647 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2648 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2650 SetResizePolicy( type, Dimension::WIDTH );
2655 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2657 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2658 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2660 SetResizePolicy( type, Dimension::HEIGHT );
2665 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2667 SizeScalePolicy::Type type = GetSizeScalePolicy();
2668 if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2670 SetSizeScalePolicy( type );
2675 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2677 if( property.Get< bool >() )
2679 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2684 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2686 if( property.Get< bool >() )
2688 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2693 case Dali::Actor::Property::PADDING:
2695 Vector4 padding = property.Get< Vector4 >();
2696 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2697 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2701 case Dali::Actor::Property::MINIMUM_SIZE:
2703 Vector2 size = property.Get< Vector2 >();
2704 SetMinimumSize( size.x, Dimension::WIDTH );
2705 SetMinimumSize( size.y, Dimension::HEIGHT );
2709 case Dali::Actor::Property::MAXIMUM_SIZE:
2711 Vector2 size = property.Get< Vector2 >();
2712 SetMaximumSize( size.x, Dimension::WIDTH );
2713 SetMaximumSize( size.y, Dimension::HEIGHT );
2717 case Dali::DevelActor::Property::SIBLING_ORDER:
2721 if( property.Get( value ) )
2723 SetSiblingOrder( value );
2728 case Dali::Actor::Property::CLIPPING_MODE:
2730 ClippingMode::Type convertedValue = mClippingMode;
2731 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2733 mClippingMode = convertedValue;
2734 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2739 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
2742 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2744 mPositionUsesAnchorPoint = value;
2745 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2750 case Dali::Actor::Property::LAYOUT_DIRECTION:
2752 Dali::LayoutDirection::Type direction = mLayoutDirection;
2753 mInheritLayoutDirection = false;
2755 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2757 InheritLayoutDirectionRecursively( this, direction, true );
2762 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2765 if( property.Get( value ) )
2767 SetInheritLayoutDirection( value );
2772 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
2775 if( property.Get( value ) )
2777 SetKeyboardFocusable( value );
2782 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
2784 SetUpdateSizeHint( property.Get< Vector2 >() );
2788 case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START:
2790 bool boolValue = false;
2791 if ( property.Get( boolValue ) )
2793 mCaptureAllTouchAfterStart = boolValue;
2800 // this can happen in the case of a non-animatable default property so just do nothing
2806 // TODO: This method needs to be removed
2807 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2809 switch( entry.GetType() )
2811 case Property::BOOLEAN:
2813 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2814 DALI_ASSERT_DEBUG( NULL != property );
2816 // property is being used in a separate thread; queue a message to set the property
2817 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2822 case Property::INTEGER:
2824 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2825 DALI_ASSERT_DEBUG( NULL != property );
2827 // property is being used in a separate thread; queue a message to set the property
2828 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2833 case Property::FLOAT:
2835 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2836 DALI_ASSERT_DEBUG( NULL != property );
2838 // property is being used in a separate thread; queue a message to set the property
2839 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2844 case Property::VECTOR2:
2846 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2847 DALI_ASSERT_DEBUG( NULL != property );
2849 // property is being used in a separate thread; queue a message to set the property
2850 if(entry.componentIndex == 0)
2852 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2854 else if(entry.componentIndex == 1)
2856 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2860 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2866 case Property::VECTOR3:
2868 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2869 DALI_ASSERT_DEBUG( NULL != property );
2871 // property is being used in a separate thread; queue a message to set the property
2872 if(entry.componentIndex == 0)
2874 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2876 else if(entry.componentIndex == 1)
2878 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2880 else if(entry.componentIndex == 2)
2882 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2886 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2892 case Property::VECTOR4:
2894 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2895 DALI_ASSERT_DEBUG( NULL != property );
2897 // property is being used in a separate thread; queue a message to set the property
2898 if(entry.componentIndex == 0)
2900 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2902 else if(entry.componentIndex == 1)
2904 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2906 else if(entry.componentIndex == 2)
2908 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2910 else if(entry.componentIndex == 3)
2912 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2916 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2922 case Property::ROTATION:
2924 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2925 DALI_ASSERT_DEBUG( NULL != property );
2927 // property is being used in a separate thread; queue a message to set the property
2928 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2933 case Property::MATRIX:
2935 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2936 DALI_ASSERT_DEBUG( NULL != property );
2938 // property is being used in a separate thread; queue a message to set the property
2939 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2944 case Property::MATRIX3:
2946 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2947 DALI_ASSERT_DEBUG( NULL != property );
2949 // property is being used in a separate thread; queue a message to set the property
2950 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2957 // nothing to do for other types
2962 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2964 Property::Value value;
2966 if( ! GetCachedPropertyValue( index, value ) )
2968 // If property value is not stored in the event-side, then it must be a scene-graph only property
2969 GetCurrentPropertyValue( index, value );
2975 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2977 Property::Value value;
2979 if( ! GetCurrentPropertyValue( index, value ) )
2981 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2982 GetCachedPropertyValue( index, value );
2988 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2990 switch( animationType )
2993 case Animation::BETWEEN:
2997 case Dali::Actor::Property::SIZE:
2999 if( value.Get( mTargetSize ) )
3001 mAnimatedSize = mTargetSize;
3002 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3004 // Notify deriving classes
3005 OnSizeAnimation( animation, mTargetSize );
3010 case Dali::Actor::Property::SIZE_WIDTH:
3012 if( value.Get( mTargetSize.width ) )
3014 mAnimatedSize.width = mTargetSize.width;
3015 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3017 // Notify deriving classes
3018 OnSizeAnimation( animation, mTargetSize );
3023 case Dali::Actor::Property::SIZE_HEIGHT:
3025 if( value.Get( mTargetSize.height ) )
3027 mAnimatedSize.height = mTargetSize.height;
3028 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3030 // Notify deriving classes
3031 OnSizeAnimation( animation, mTargetSize );
3036 case Dali::Actor::Property::SIZE_DEPTH:
3038 if( value.Get( mTargetSize.depth ) )
3040 mAnimatedSize.depth = mTargetSize.depth;
3041 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3043 // Notify deriving classes
3044 OnSizeAnimation( animation, mTargetSize );
3049 case Dali::Actor::Property::POSITION:
3051 value.Get( mTargetPosition );
3055 case Dali::Actor::Property::POSITION_X:
3057 value.Get( mTargetPosition.x );
3061 case Dali::Actor::Property::POSITION_Y:
3063 value.Get( mTargetPosition.y );
3067 case Dali::Actor::Property::POSITION_Z:
3069 value.Get( mTargetPosition.z );
3073 case Dali::Actor::Property::ORIENTATION:
3075 value.Get( mTargetOrientation );
3079 case Dali::Actor::Property::SCALE:
3081 value.Get( mTargetScale );
3085 case Dali::Actor::Property::SCALE_X:
3087 value.Get( mTargetScale.x );
3091 case Dali::Actor::Property::SCALE_Y:
3093 value.Get( mTargetScale.y );
3097 case Dali::Actor::Property::SCALE_Z:
3099 value.Get( mTargetScale.z );
3103 case Dali::Actor::Property::VISIBLE:
3105 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3109 case Dali::Actor::Property::COLOR:
3111 value.Get( mTargetColor );
3115 case Dali::Actor::Property::COLOR_RED:
3117 value.Get( mTargetColor.r );
3121 case Dali::Actor::Property::COLOR_GREEN:
3123 value.Get( mTargetColor.g );
3127 case Dali::Actor::Property::COLOR_BLUE:
3129 value.Get( mTargetColor.b );
3133 case Dali::Actor::Property::COLOR_ALPHA:
3134 case Dali::Actor::Property::OPACITY:
3136 value.Get( mTargetColor.a );
3142 // Not an animatable property. Do nothing.
3153 case Dali::Actor::Property::SIZE:
3155 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3157 mAnimatedSize = mTargetSize;
3158 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3160 // Notify deriving classes
3161 OnSizeAnimation( animation, mTargetSize );
3166 case Dali::Actor::Property::SIZE_WIDTH:
3168 if( AdjustValue< float >( mTargetSize.width, value ) )
3170 mAnimatedSize.width = mTargetSize.width;
3171 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3173 // Notify deriving classes
3174 OnSizeAnimation( animation, mTargetSize );
3179 case Dali::Actor::Property::SIZE_HEIGHT:
3181 if( AdjustValue< float >( mTargetSize.height, value ) )
3183 mAnimatedSize.height = mTargetSize.height;
3184 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3186 // Notify deriving classes
3187 OnSizeAnimation( animation, mTargetSize );
3192 case Dali::Actor::Property::SIZE_DEPTH:
3194 if( AdjustValue< float >( mTargetSize.depth, value ) )
3196 mAnimatedSize.depth = mTargetSize.depth;
3197 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3199 // Notify deriving classes
3200 OnSizeAnimation( animation, mTargetSize );
3205 case Dali::Actor::Property::POSITION:
3207 AdjustValue< Vector3 >( mTargetPosition, value );
3211 case Dali::Actor::Property::POSITION_X:
3213 AdjustValue< float >( mTargetPosition.x, value );
3217 case Dali::Actor::Property::POSITION_Y:
3219 AdjustValue< float >( mTargetPosition.y, value );
3223 case Dali::Actor::Property::POSITION_Z:
3225 AdjustValue< float >( mTargetPosition.z, value );
3229 case Dali::Actor::Property::ORIENTATION:
3231 Quaternion relativeValue;
3232 if( value.Get( relativeValue ) )
3234 mTargetOrientation *= relativeValue;
3239 case Dali::Actor::Property::SCALE:
3241 AdjustValue< Vector3 >( mTargetScale, value );
3245 case Dali::Actor::Property::SCALE_X:
3247 AdjustValue< float >( mTargetScale.x, value );
3251 case Dali::Actor::Property::SCALE_Y:
3253 AdjustValue< float >( mTargetScale.y, value );
3257 case Dali::Actor::Property::SCALE_Z:
3259 AdjustValue< float >( mTargetScale.z, value );
3263 case Dali::Actor::Property::VISIBLE:
3265 bool relativeValue = false;
3266 if( value.Get( relativeValue ) )
3268 bool visible = mVisible || relativeValue;
3269 SetVisibleInternal( visible, SendMessage::FALSE );
3274 case Dali::Actor::Property::COLOR:
3276 AdjustValue< Vector4 >( mTargetColor, value );
3280 case Dali::Actor::Property::COLOR_RED:
3282 AdjustValue< float >( mTargetColor.r, value );
3286 case Dali::Actor::Property::COLOR_GREEN:
3288 AdjustValue< float >( mTargetColor.g, value );
3292 case Dali::Actor::Property::COLOR_BLUE:
3294 AdjustValue< float >( mTargetColor.b, value );
3298 case Dali::Actor::Property::COLOR_ALPHA:
3299 case Dali::Actor::Property::OPACITY:
3301 AdjustValue< float >( mTargetColor.a, value );
3307 // Not an animatable property. Do nothing.
3316 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3318 const PropertyBase* property( NULL );
3322 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3323 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3324 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3325 case Dali::Actor::Property::SIZE_DEPTH:
3327 property = &GetNode().mSize;
3330 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3331 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3332 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3333 case Dali::Actor::Property::POSITION_Z:
3335 property = &GetNode().mPosition;
3338 case Dali::Actor::Property::ORIENTATION:
3340 property = &GetNode().mOrientation;
3343 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3344 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3345 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3346 case Dali::Actor::Property::SCALE_Z:
3348 property = &GetNode().mScale;
3351 case Dali::Actor::Property::VISIBLE:
3353 property = &GetNode().mVisible;
3356 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3357 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3358 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3359 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3360 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3361 case Dali::Actor::Property::OPACITY:
3363 property = &GetNode().mColor;
3373 // not our property, ask base
3374 property = Object::GetSceneObjectAnimatableProperty( index );
3380 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3382 const PropertyInputImpl* property( NULL );
3386 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3387 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3388 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3389 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3391 property = &GetNode().mParentOrigin;
3394 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3395 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3396 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3397 case Dali::Actor::Property::ANCHOR_POINT_Z:
3399 property = &GetNode().mAnchorPoint;
3402 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3403 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3404 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3405 case Dali::Actor::Property::WORLD_POSITION_Z:
3407 property = &GetNode().mWorldPosition;
3410 case Dali::Actor::Property::WORLD_ORIENTATION:
3412 property = &GetNode().mWorldOrientation;
3415 case Dali::Actor::Property::WORLD_SCALE:
3417 property = &GetNode().mWorldScale;
3420 case Dali::Actor::Property::WORLD_COLOR:
3422 property = &GetNode().mWorldColor;
3425 case Dali::Actor::Property::WORLD_MATRIX:
3427 property = &GetNode().mWorldMatrix;
3430 case Dali::Actor::Property::CULLED:
3432 property = &GetNode().mCulled;
3442 // reuse animatable property getter as animatable properties are inputs as well
3443 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3444 property = GetSceneObjectAnimatableProperty( index );
3450 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3452 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3456 case Dali::Actor::Property::PARENT_ORIGIN_X:
3457 case Dali::Actor::Property::ANCHOR_POINT_X:
3458 case Dali::Actor::Property::SIZE_WIDTH:
3459 case Dali::Actor::Property::POSITION_X:
3460 case Dali::Actor::Property::WORLD_POSITION_X:
3461 case Dali::Actor::Property::SCALE_X:
3462 case Dali::Actor::Property::COLOR_RED:
3468 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3469 case Dali::Actor::Property::ANCHOR_POINT_Y:
3470 case Dali::Actor::Property::SIZE_HEIGHT:
3471 case Dali::Actor::Property::POSITION_Y:
3472 case Dali::Actor::Property::WORLD_POSITION_Y:
3473 case Dali::Actor::Property::SCALE_Y:
3474 case Dali::Actor::Property::COLOR_GREEN:
3480 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3481 case Dali::Actor::Property::ANCHOR_POINT_Z:
3482 case Dali::Actor::Property::SIZE_DEPTH:
3483 case Dali::Actor::Property::POSITION_Z:
3484 case Dali::Actor::Property::WORLD_POSITION_Z:
3485 case Dali::Actor::Property::SCALE_Z:
3486 case Dali::Actor::Property::COLOR_BLUE:
3492 case Dali::Actor::Property::COLOR_ALPHA:
3493 case Dali::Actor::Property::OPACITY:
3505 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3508 componentIndex = Object::GetPropertyComponentIndex( index );
3511 return componentIndex;
3514 void Actor::SetParent( Actor* parent )
3518 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3522 mScene = parent->mScene;
3524 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3527 // Instruct each actor to create a corresponding node in the scene graph
3528 ConnectToScene( parent->GetHierarchyDepth() );
3531 // Resolve the name and index for the child properties if any
3532 ResolveChildProperties();
3534 else // parent being set to NULL
3536 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3540 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3543 // Disconnect the Node & its children from the scene-graph.
3544 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3546 // Instruct each actor to discard pointers to the scene-graph
3547 DisconnectFromStage();
3554 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3557 Actor* actor = dynamic_cast< Actor* >( object );
3561 if( 0 == actionName.compare( ACTION_SHOW ) )
3563 actor->SetVisible( true );
3566 else if( 0 == actionName.compare( ACTION_HIDE ) )
3568 actor->SetVisible( false );
3576 Rect<> Actor::CalculateScreenExtents( ) const
3578 auto screenPosition = GetCurrentScreenPosition();
3579 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3580 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3581 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3582 return { position.x, position.y, size.x, size.y };
3585 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3587 bool valueSet = true;
3591 case Dali::Actor::Property::PARENT_ORIGIN:
3593 value = GetCurrentParentOrigin();
3597 case Dali::Actor::Property::PARENT_ORIGIN_X:
3599 value = GetCurrentParentOrigin().x;
3603 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3605 value = GetCurrentParentOrigin().y;
3609 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3611 value = GetCurrentParentOrigin().z;
3615 case Dali::Actor::Property::ANCHOR_POINT:
3617 value = GetCurrentAnchorPoint();
3621 case Dali::Actor::Property::ANCHOR_POINT_X:
3623 value = GetCurrentAnchorPoint().x;
3627 case Dali::Actor::Property::ANCHOR_POINT_Y:
3629 value = GetCurrentAnchorPoint().y;
3633 case Dali::Actor::Property::ANCHOR_POINT_Z:
3635 value = GetCurrentAnchorPoint().z;
3639 case Dali::Actor::Property::SIZE:
3641 value = GetTargetSize();
3645 case Dali::Actor::Property::SIZE_WIDTH:
3647 value = GetTargetSize().width;
3651 case Dali::Actor::Property::SIZE_HEIGHT:
3653 value = GetTargetSize().height;
3657 case Dali::Actor::Property::SIZE_DEPTH:
3659 value = GetTargetSize().depth;
3663 case Dali::Actor::Property::POSITION:
3665 value = GetTargetPosition();
3669 case Dali::Actor::Property::POSITION_X:
3671 value = GetTargetPosition().x;
3675 case Dali::Actor::Property::POSITION_Y:
3677 value = GetTargetPosition().y;
3681 case Dali::Actor::Property::POSITION_Z:
3683 value = GetTargetPosition().z;
3687 case Dali::Actor::Property::ORIENTATION:
3689 value = mTargetOrientation;
3693 case Dali::Actor::Property::SCALE:
3695 value = mTargetScale;
3699 case Dali::Actor::Property::SCALE_X:
3701 value = mTargetScale.x;
3705 case Dali::Actor::Property::SCALE_Y:
3707 value = mTargetScale.y;
3711 case Dali::Actor::Property::SCALE_Z:
3713 value = mTargetScale.z;
3717 case Dali::Actor::Property::VISIBLE:
3723 case Dali::Actor::Property::COLOR:
3725 value = mTargetColor;
3729 case Dali::Actor::Property::COLOR_RED:
3731 value = mTargetColor.r;
3735 case Dali::Actor::Property::COLOR_GREEN:
3737 value = mTargetColor.g;
3741 case Dali::Actor::Property::COLOR_BLUE:
3743 value = mTargetColor.b;
3747 case Dali::Actor::Property::COLOR_ALPHA:
3748 case Dali::Actor::Property::OPACITY:
3750 value = mTargetColor.a;
3754 case Dali::Actor::Property::NAME:
3760 case Dali::Actor::Property::SENSITIVE:
3762 value = IsSensitive();
3766 case Dali::Actor::Property::LEAVE_REQUIRED:
3768 value = GetLeaveRequired();
3772 case Dali::Actor::Property::INHERIT_POSITION:
3774 value = IsPositionInherited();
3778 case Dali::Actor::Property::INHERIT_ORIENTATION:
3780 value = IsOrientationInherited();
3784 case Dali::Actor::Property::INHERIT_SCALE:
3786 value = IsScaleInherited();
3790 case Dali::Actor::Property::COLOR_MODE:
3792 value = GetColorMode();
3796 case Dali::Actor::Property::DRAW_MODE:
3798 value = GetDrawMode();
3802 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3804 value = GetSizeModeFactor();
3808 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3810 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3814 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3816 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3820 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3822 value = GetSizeScalePolicy();
3826 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3828 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3832 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3834 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3838 case Dali::Actor::Property::PADDING:
3840 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3841 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3842 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3846 case Dali::Actor::Property::MINIMUM_SIZE:
3848 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3852 case Dali::Actor::Property::MAXIMUM_SIZE:
3854 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3858 case Dali::Actor::Property::CLIPPING_MODE:
3860 value = mClippingMode;
3864 case Dali::DevelActor::Property::SIBLING_ORDER:
3866 value = static_cast<int>( GetSiblingOrder() );
3870 case Dali::Actor::Property::SCREEN_POSITION:
3872 value = GetCurrentScreenPosition();
3876 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
3878 value = mPositionUsesAnchorPoint;
3882 case Dali::Actor::Property::LAYOUT_DIRECTION:
3884 value = mLayoutDirection;
3888 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3890 value = IsLayoutDirectionInherited();
3894 case Dali::Actor::Property::ID:
3896 value = static_cast<int>( GetId() );
3900 case Dali::Actor::Property::HIERARCHY_DEPTH:
3902 value = GetHierarchyDepth();
3906 case Dali::Actor::Property::IS_ROOT:
3912 case Dali::Actor::Property::IS_LAYER:
3918 case Dali::Actor::Property::CONNECTED_TO_SCENE:
3924 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
3926 value = IsKeyboardFocusable();
3930 case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START:
3932 value = mCaptureAllTouchAfterStart;
3938 // Must be a scene-graph only property
3947 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3949 bool valueSet = true;
3953 case Dali::Actor::Property::SIZE:
3955 value = GetCurrentSize();
3959 case Dali::Actor::Property::SIZE_WIDTH:
3961 value = GetCurrentSize().width;
3965 case Dali::Actor::Property::SIZE_HEIGHT:
3967 value = GetCurrentSize().height;
3971 case Dali::Actor::Property::SIZE_DEPTH:
3973 value = GetCurrentSize().depth;
3977 case Dali::Actor::Property::POSITION:
3979 value = GetCurrentPosition();
3983 case Dali::Actor::Property::POSITION_X:
3985 value = GetCurrentPosition().x;
3989 case Dali::Actor::Property::POSITION_Y:
3991 value = GetCurrentPosition().y;
3995 case Dali::Actor::Property::POSITION_Z:
3997 value = GetCurrentPosition().z;
4001 case Dali::Actor::Property::WORLD_POSITION:
4003 value = GetCurrentWorldPosition();
4007 case Dali::Actor::Property::WORLD_POSITION_X:
4009 value = GetCurrentWorldPosition().x;
4013 case Dali::Actor::Property::WORLD_POSITION_Y:
4015 value = GetCurrentWorldPosition().y;
4019 case Dali::Actor::Property::WORLD_POSITION_Z:
4021 value = GetCurrentWorldPosition().z;
4025 case Dali::Actor::Property::ORIENTATION:
4027 value = GetCurrentOrientation();
4031 case Dali::Actor::Property::WORLD_ORIENTATION:
4033 value = GetCurrentWorldOrientation();
4037 case Dali::Actor::Property::SCALE:
4039 value = GetCurrentScale();
4043 case Dali::Actor::Property::SCALE_X:
4045 value = GetCurrentScale().x;
4049 case Dali::Actor::Property::SCALE_Y:
4051 value = GetCurrentScale().y;
4055 case Dali::Actor::Property::SCALE_Z:
4057 value = GetCurrentScale().z;
4061 case Dali::Actor::Property::WORLD_SCALE:
4063 value = GetCurrentWorldScale();
4067 case Dali::Actor::Property::COLOR:
4069 value = GetCurrentColor();
4073 case Dali::Actor::Property::COLOR_RED:
4075 value = GetCurrentColor().r;
4079 case Dali::Actor::Property::COLOR_GREEN:
4081 value = GetCurrentColor().g;
4085 case Dali::Actor::Property::COLOR_BLUE:
4087 value = GetCurrentColor().b;
4091 case Dali::Actor::Property::COLOR_ALPHA:
4092 case Dali::Actor::Property::OPACITY:
4094 value = GetCurrentColor().a;
4098 case Dali::Actor::Property::WORLD_COLOR:
4100 value = GetCurrentWorldColor();
4104 case Dali::Actor::Property::WORLD_MATRIX:
4106 value = GetCurrentWorldMatrix();
4110 case Dali::Actor::Property::VISIBLE:
4112 value = IsVisible();
4116 case Dali::Actor::Property::CULLED:
4118 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4122 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
4124 value = GetUpdateSizeHint();
4130 // Must be an event-side only property
4139 void Actor::EnsureRelayoutData()
4141 // Assign relayout data.
4142 if( !mRelayoutData )
4144 mRelayoutData = new RelayoutData();
4148 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4150 // Check if actor is dependent on parent
4151 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4153 if( ( dimension & ( 1 << i ) ) )
4155 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4156 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4166 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4168 // Check if actor is dependent on children
4169 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4171 if( ( dimension & ( 1 << i ) ) )
4173 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4174 switch( resizePolicy )
4176 case ResizePolicy::FIT_TO_CHILDREN:
4177 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4193 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4195 return Actor::RelayoutDependentOnChildren( dimension );
4198 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4200 // Check each possible dimension and see if it is dependent on the input one
4201 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4203 if( dimension & ( 1 << i ) )
4205 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4212 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4214 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4216 if( dimension & ( 1 << i ) )
4218 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4223 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4225 // If more than one dimension is requested, just return the first one found
4226 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4228 if( ( dimension & ( 1 << i ) ) )
4230 return mRelayoutData->negotiatedDimensions[ i ];
4234 return 0.0f; // Default
4237 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4239 EnsureRelayoutData();
4241 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4243 if( dimension & ( 1 << i ) )
4245 mRelayoutData->dimensionPadding[ i ] = padding;
4250 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4252 if ( mRelayoutData )
4254 // If more than one dimension is requested, just return the first one found
4255 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4257 if( ( dimension & ( 1 << i ) ) )
4259 return mRelayoutData->dimensionPadding[ i ];
4264 return GetDefaultDimensionPadding();
4267 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4269 EnsureRelayoutData();
4271 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4273 if( dimension & ( 1 << i ) )
4275 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4280 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4282 if ( mRelayoutData )
4284 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4286 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4296 float Actor::GetHeightForWidthBase( float width )
4298 float height = 0.0f;
4300 const Vector3 naturalSize = GetNaturalSize();
4301 if( naturalSize.width > 0.0f )
4303 height = naturalSize.height * width / naturalSize.width;
4305 else // we treat 0 as 1:1 aspect ratio
4313 float Actor::GetWidthForHeightBase( float height )
4317 const Vector3 naturalSize = GetNaturalSize();
4318 if( naturalSize.height > 0.0f )
4320 width = naturalSize.width * height / naturalSize.height;
4322 else // we treat 0 as 1:1 aspect ratio
4330 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4332 // Fill to parent, taking size mode factor into account
4333 switch( child.GetResizePolicy( dimension ) )
4335 case ResizePolicy::FILL_TO_PARENT:
4337 return GetLatestSize( dimension );
4340 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4342 return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4345 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4347 return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4352 return GetLatestSize( dimension );
4357 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4359 // Can be overridden in derived class
4360 return CalculateChildSizeBase( child, dimension );
4363 float Actor::GetHeightForWidth( float width )
4365 // Can be overridden in derived class
4366 return GetHeightForWidthBase( width );
4369 float Actor::GetWidthForHeight( float height )
4371 // Can be overridden in derived class
4372 return GetWidthForHeightBase( height );
4375 float Actor::GetLatestSize( Dimension::Type dimension ) const
4377 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4380 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4382 Vector2 padding = GetPadding( dimension );
4384 return GetLatestSize( dimension ) + padding.x + padding.y;
4387 float Actor::NegotiateFromParent( Dimension::Type dimension )
4389 Actor* parent = GetParent();
4392 Vector2 padding( GetPadding( dimension ) );
4393 Vector2 parentPadding( parent->GetPadding( dimension ) );
4394 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4400 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4402 float maxDimensionPoint = 0.0f;
4404 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4406 ActorPtr child = GetChildAt( i );
4408 if( !child->RelayoutDependentOnParent( dimension ) )
4410 // Calculate the min and max points that the children range across
4411 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4412 float dimensionSize = child->GetRelayoutSize( dimension );
4413 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4417 return maxDimensionPoint;
4420 float Actor::GetSize( Dimension::Type dimension ) const
4422 return GetDimensionValue( mTargetSize, dimension );
4425 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4427 return GetDimensionValue( GetNaturalSize(), dimension );
4430 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4432 switch( GetResizePolicy( dimension ) )
4434 case ResizePolicy::USE_NATURAL_SIZE:
4436 return GetNaturalSize( dimension );
4439 case ResizePolicy::FIXED:
4441 return GetDimensionValue( GetPreferredSize(), dimension );
4444 case ResizePolicy::USE_ASSIGNED_SIZE:
4446 return GetDimensionValue( maximumSize, dimension );
4449 case ResizePolicy::FILL_TO_PARENT:
4450 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4451 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4453 return NegotiateFromParent( dimension );
4456 case ResizePolicy::FIT_TO_CHILDREN:
4458 return NegotiateFromChildren( dimension );
4461 case ResizePolicy::DIMENSION_DEPENDENCY:
4463 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4466 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4468 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4471 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4473 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4485 return 0.0f; // Default
4488 float Actor::ClampDimension( float size, Dimension::Type dimension )
4490 const float minSize = GetMinimumSize( dimension );
4491 const float maxSize = GetMaximumSize( dimension );
4493 return std::max( minSize, std::min( size, maxSize ) );
4496 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4498 // Check if it needs to be negotiated
4499 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4501 // Check that we havn't gotten into an infinite loop
4502 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4503 bool recursionFound = false;
4504 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4506 if( *it == searchActor )
4508 recursionFound = true;
4513 if( !recursionFound )
4515 // Record the path that we have taken
4516 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4518 // Dimension dependency check
4519 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4521 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4523 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4525 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4529 // Parent dependency check
4530 Actor* parent = GetParent();
4531 if( parent && RelayoutDependentOnParent( dimension ) )
4533 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4536 // Children dependency check
4537 if( RelayoutDependentOnChildren( dimension ) )
4539 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4541 ActorPtr child = GetChildAt( i );
4543 // Only relayout child first if it is not dependent on this actor
4544 if( !child->RelayoutDependentOnParent( dimension ) )
4546 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4551 // For deriving classes
4552 OnCalculateRelayoutSize( dimension );
4554 // All dependencies checked, calculate the size and set negotiated flag
4555 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4557 SetNegotiatedDimension( newSize, dimension );
4558 SetLayoutNegotiated( true, dimension );
4560 // For deriving classes
4561 OnLayoutNegotiated( newSize, dimension );
4563 // This actor has been successfully processed, pop it off the recursion stack
4564 recursionStack.pop_back();
4568 // TODO: Break infinite loop
4569 SetLayoutNegotiated( true, dimension );
4574 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4576 // Negotiate all dimensions that require it
4577 ActorDimensionStack recursionStack;
4579 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4581 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4584 NegotiateDimension( dimension, allocatedSize, recursionStack );
4588 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4590 switch( mRelayoutData->sizeSetPolicy )
4592 case SizeScalePolicy::USE_SIZE_SET:
4597 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4599 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4600 const Vector3 naturalSize = GetNaturalSize();
4601 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4603 const float sizeRatio = size.width / size.height;
4604 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4606 if( naturalSizeRatio < sizeRatio )
4608 return Vector2( naturalSizeRatio * size.height, size.height );
4610 else if( naturalSizeRatio > sizeRatio )
4612 return Vector2( size.width, size.width / naturalSizeRatio );
4623 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4625 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4626 const Vector3 naturalSize = GetNaturalSize();
4627 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4629 const float sizeRatio = size.width / size.height;
4630 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4632 if( naturalSizeRatio < sizeRatio )
4634 return Vector2( size.width, size.width / naturalSizeRatio );
4636 else if( naturalSizeRatio > sizeRatio )
4638 return Vector2( naturalSizeRatio * size.height, size.height );
4657 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4659 // Do the set actor size
4660 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4662 // Adjust for size set policy
4663 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4665 // Lock the flag to stop recursive relayouts on set size
4666 mRelayoutData->insideRelayout = true;
4667 SetSize( negotiatedSize );
4668 mRelayoutData->insideRelayout = false;
4670 // Clear flags for all dimensions
4671 SetLayoutDirty( false );
4673 // Give deriving classes a chance to respond
4674 OnRelayout( negotiatedSize, container );
4676 if( !mOnRelayoutSignal.Empty() )
4678 Dali::Actor handle( this );
4679 mOnRelayoutSignal.Emit( handle );
4683 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4685 // Force a size negotiation for actors that has assigned size during relayout
4686 // This is required as otherwise the flags that force a relayout will not
4687 // necessarilly be set. This will occur if the actor has already been laid out.
4688 // The dirty flags are then cleared. Then if the actor is added back into the
4689 // relayout container afterwards, the dirty flags would still be clear...
4690 // causing a relayout to be skipped. Here we force any actors added to the
4691 // container to be relayed out.
4692 DALI_LOG_TIMER_START( NegSizeTimer1 );
4694 if( GetUseAssignedSize(Dimension::WIDTH ) )
4696 SetLayoutNegotiated( false, Dimension::WIDTH );
4698 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4700 SetLayoutNegotiated( false, Dimension::HEIGHT );
4703 // Do the negotiation
4704 NegotiateDimensions( allocatedSize );
4706 // Set the actor size
4707 SetNegotiatedSize( container );
4709 // Negotiate down to children
4710 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4712 ActorPtr child = GetChildAt( i );
4714 // Forces children that have already been laid out to be relayed out
4715 // if they have assigned size during relayout.
4716 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4718 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4719 child->SetLayoutDirty(true, Dimension::WIDTH);
4722 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4724 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4725 child->SetLayoutDirty(true, Dimension::HEIGHT);
4728 // Only relayout if required
4729 if( child->RelayoutRequired() )
4731 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4734 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4737 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4741 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4743 if( dimension & ( 1 << i ) )
4745 mRelayoutData->useAssignedSize[ i ] = use;
4751 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4753 if ( mRelayoutData )
4755 // If more than one dimension is requested, just return the first one found
4756 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4758 if( dimension & ( 1 << i ) )
4760 return mRelayoutData->useAssignedSize[ i ];
4768 void Actor::RelayoutRequest( Dimension::Type dimension )
4770 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4771 if( relayoutController )
4773 Dali::Actor self( this );
4774 relayoutController->RequestRelayout( self, dimension );
4778 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4782 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4786 void Actor::SetPreferredSize( const Vector2& size )
4788 EnsureRelayoutData();
4790 // If valid width or height, then set the resize policy to FIXED
4791 // 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,
4792 // then change to FIXED as well
4794 if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4796 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4799 if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4801 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4804 mRelayoutData->preferredSize = size;
4806 mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4811 Vector2 Actor::GetPreferredSize() const
4813 if ( mRelayoutData )
4815 return Vector2( mRelayoutData->preferredSize );
4818 return GetDefaultPreferredSize();
4821 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4823 EnsureRelayoutData();
4825 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4827 if( dimension & ( 1 << i ) )
4829 mRelayoutData->minimumSize[ i ] = size;
4836 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4838 if ( mRelayoutData )
4840 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4842 if( dimension & ( 1 << i ) )
4844 return mRelayoutData->minimumSize[ i ];
4849 return 0.0f; // Default
4852 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4854 EnsureRelayoutData();
4856 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4858 if( dimension & ( 1 << i ) )
4860 mRelayoutData->maximumSize[ i ] = size;
4867 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4869 if ( mRelayoutData )
4871 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4873 if( dimension & ( 1 << i ) )
4875 return mRelayoutData->maximumSize[ i ];
4880 return FLT_MAX; // Default
4883 Object* Actor::GetParentObject() const
4888 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4890 if( mVisible != visible )
4892 if( sendMessage == SendMessage::TRUE )
4894 // node is being used in a separate thread; queue a message to set the value & base value
4895 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4900 // Emit the signal on this actor and all its children
4901 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4905 void Actor::SetSiblingOrder( uint32_t order )
4909 ActorContainer& siblings = *(mParent->mChildren);
4910 uint32_t currentOrder = GetSiblingOrder();
4912 if( order != currentOrder )
4918 else if( order < siblings.size() -1 )
4920 if( order > currentOrder )
4922 RaiseAbove( *siblings[order] );
4926 LowerBelow( *siblings[order] );
4937 uint32_t Actor::GetSiblingOrder() const
4943 ActorContainer& siblings = *(mParent->mChildren);
4944 for( std::size_t i = 0; i < siblings.size(); ++i )
4946 if( siblings[i] == this )
4948 order = static_cast<uint32_t>( i );
4957 void Actor::RequestRebuildDepthTree()
4963 mScene->RequestRebuildDepthTree();
4972 ActorContainer& siblings = *(mParent->mChildren);
4973 if( siblings.back() != this ) // If not already at end
4975 for( std::size_t i=0; i<siblings.size(); ++i )
4977 if( siblings[i] == this )
4980 ActorPtr next = siblings[i+1];
4981 siblings[i+1] = this;
4988 Dali::Actor handle( this );
4989 mParent->mChildOrderChangedSignal.Emit( handle );
4991 RequestRebuildDepthTree();
4995 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5003 ActorContainer& siblings = *(mParent->mChildren);
5004 if( siblings.front() != this ) // If not already at beginning
5006 for( std::size_t i=1; i<siblings.size(); ++i )
5008 if( siblings[i] == this )
5010 // Swap with previous
5011 ActorPtr previous = siblings[i-1];
5012 siblings[i-1] = this;
5013 siblings[i] = previous;
5019 Dali::Actor handle( this );
5020 mParent->mChildOrderChangedSignal.Emit( handle );
5022 RequestRebuildDepthTree();
5026 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5030 void Actor::RaiseToTop()
5034 ActorContainer& siblings = *(mParent->mChildren);
5035 if( siblings.back() != this ) // If not already at end
5037 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5038 if( iter != siblings.end() )
5040 siblings.erase(iter);
5041 siblings.push_back(ActorPtr(this));
5045 Dali::Actor handle( this );
5046 mParent->mChildOrderChangedSignal.Emit( handle );
5048 RequestRebuildDepthTree();
5052 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5056 void Actor::LowerToBottom()
5060 ActorContainer& siblings = *(mParent->mChildren);
5061 if( siblings.front() != this ) // If not already at bottom,
5063 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5065 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5066 if( iter != siblings.end() )
5068 siblings.erase(iter);
5069 siblings.insert(siblings.begin(), thisPtr);
5073 Dali::Actor handle( this );
5074 mParent->mChildOrderChangedSignal.Emit( handle );
5076 RequestRebuildDepthTree();
5080 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5084 void Actor::RaiseAbove( Internal::Actor& target )
5088 ActorContainer& siblings = *(mParent->mChildren);
5089 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5091 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5093 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5094 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5095 if( thisIter < targetIter )
5097 siblings.erase(thisIter);
5098 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5099 // invalidate thisIter)
5100 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5102 siblings.insert(targetIter, thisPtr);
5105 Dali::Actor handle( this );
5106 mParent->mChildOrderChangedSignal.Emit( handle );
5108 RequestRebuildDepthTree();
5113 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5117 void Actor::LowerBelow( Internal::Actor& target )
5121 ActorContainer& siblings = *(mParent->mChildren);
5122 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5124 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5126 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5127 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5129 if( thisIter > targetIter )
5131 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5132 siblings.insert(targetIter, thisPtr);
5135 Dali::Actor handle( this );
5136 mParent->mChildOrderChangedSignal.Emit( handle );
5138 RequestRebuildDepthTree();
5143 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5147 void Actor::SetScene( Scene& scene )
5152 Scene& Actor::GetScene() const
5157 void Actor::SetInheritLayoutDirection( bool inherit )
5159 if( mInheritLayoutDirection != inherit )
5161 mInheritLayoutDirection = inherit;
5163 if( inherit && mParent )
5165 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5170 bool Actor::IsLayoutDirectionInherited() const
5172 return mInheritLayoutDirection;
5175 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5177 if( actor && ( actor->mInheritLayoutDirection || set ) )
5179 if( actor->mLayoutDirection != direction )
5181 actor->mLayoutDirection = direction;
5182 actor->EmitLayoutDirectionChangedSignal( direction );
5183 actor->RelayoutRequest();
5186 if( actor->GetChildCount() > 0 )
5188 ActorContainer& children = actor->GetChildrenInternal();
5189 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5191 InheritLayoutDirectionRecursively( *iter, direction );
5197 void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint )
5199 // node is being used in a separate thread; queue a message to set the value & base value
5200 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) );
5203 Vector2 Actor::GetUpdateSizeHint() const
5205 // node is being used in a separate thread, the value from the previous update is the same, set by user
5206 Vector3 updateSizeHint = GetNode().GetUpdateSizeHint();
5207 return Vector2( updateSizeHint.width, updateSizeHint.height );
5210 } // namespace Internal