2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/common/scene-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/animation/constraint-impl.h>
48 #include <dali/internal/event/common/projection.h>
49 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
50 #include <dali/internal/update/common/animatable-property.h>
51 #include <dali/internal/update/nodes/node-messages.h>
52 #include <dali/internal/update/nodes/node-declarations.h>
53 #include <dali/internal/update/animation/scene-graph-constraint.h>
54 #include <dali/internal/event/events/actor-gesture-data.h>
55 #include <dali/internal/common/message.h>
56 #include <dali/integration-api/debug.h>
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::PropertyBase;
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
64 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
75 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
76 inline const Vector3& GetDefaultSizeModeFactor()
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultPreferredSize()
87 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
88 inline const Vector2& GetDefaultDimensionPadding()
93 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
95 } // unnamed namespace
98 * Struct to collect relayout variables
100 struct Actor::RelayoutData
103 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
105 // Set size negotiation defaults
106 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
108 resizePolicies[ i ] = ResizePolicy::DEFAULT;
109 useAssignedSize[ i ] = false;
110 negotiatedDimensions[ i ] = 0.0f;
111 dimensionNegotiated[ i ] = false;
112 dimensionDirty[ i ] = false;
113 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
114 dimensionPadding[ i ] = GetDefaultDimensionPadding();
115 minimumSize[ i ] = 0.0f;
116 maximumSize[ i ] = FLT_MAX;
120 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
121 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
123 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
125 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
127 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
129 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
130 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
132 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
133 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
135 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
137 Vector2 preferredSize; ///< The preferred size of the actor
139 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
141 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
142 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
145 namespace // unnamed namespace
151 * We want to discourage the use of property strings (minimize string comparisons),
152 * particularly for the default properties.
153 * Name Type writable animatable constraint-input enum for index-checking
155 DALI_PROPERTY_TABLE_BEGIN
156 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
157 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
158 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
159 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
160 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
161 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
162 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
163 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
164 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
165 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
166 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
167 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
168 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
169 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
170 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
171 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
172 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
173 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
174 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
175 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
176 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
177 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
178 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
179 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
180 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
181 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
182 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
183 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
184 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
185 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
186 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
187 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
188 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
189 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
190 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
191 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
192 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
193 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
194 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
195 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
196 DALI_PROPERTY( "colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE )
198 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
199 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
200 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
201 DALI_PROPERTY( "sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
202 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
203 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
204 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
205 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
206 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
207 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
208 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
209 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
210 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
211 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY )
212 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION )
213 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT )
214 DALI_PROPERTY( "culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED )
215 DALI_PROPERTY( "id", INTEGER, false, false, false, Dali::Actor::Property::ID )
216 DALI_PROPERTY( "hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH )
217 DALI_PROPERTY( "isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT )
218 DALI_PROPERTY( "isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER )
219 DALI_PROPERTY( "connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE )
220 DALI_PROPERTY( "keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE )
221 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
222 DALI_PROPERTY( "updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT )
223 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
227 const char* const SIGNAL_TOUCHED = "touched";
228 const char* const SIGNAL_HOVERED = "hovered";
229 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
230 const char* const SIGNAL_ON_STAGE = "onStage";
231 const char* const SIGNAL_OFF_STAGE = "offStage";
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 signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
256 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
257 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
258 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
259 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
260 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
261 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
263 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
264 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
269 const Vector3& value;
272 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
276 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
277 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
278 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
279 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
280 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
281 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
282 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
284 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
285 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
286 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
287 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
288 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
289 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
291 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
294 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
296 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
299 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
300 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
305 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
307 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
310 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
311 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
313 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
315 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
316 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
318 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
319 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
320 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
321 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
323 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
325 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
327 uint32_t sizeIgnored = 0;
328 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
330 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
337 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
339 // Values are the same so just use the same table as anchor-point
340 return GetAnchorPointConstant( value, parentOrigin );
344 * @brief Extract a given dimension from a Vector2
346 * @param[in] values The values to extract from
347 * @param[in] dimension The dimension to extract
348 * @return Return the value for the dimension
350 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
354 case Dimension::WIDTH:
358 case Dimension::HEIGHT:
360 return values.height;
371 * @brief Extract a given dimension from a Vector3
373 * @param[in] values The values to extract from
374 * @param[in] dimension The dimension to extract
375 * @return Return the value for the dimension
377 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
379 return GetDimensionValue( values.GetVectorXY(), dimension );
383 * @brief Recursively emits the visibility-changed-signal on the actor tree.
384 * @param[in] actor The actor to emit the signal on
385 * @param[in] visible The new visibility of the actor
386 * @param[in] type Whether the actor's visible property has changed or a parent's
388 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
392 actor->EmitVisibilityChangedSignal( visible, type );
394 if( actor->GetChildCount() > 0 )
396 ActorContainer& children = actor->GetChildrenInternal();
397 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
399 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
405 } // unnamed namespace
407 ActorPtr Actor::New()
409 // pass a reference to actor, actor does not own its node
410 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
412 // Second-phase construction
418 const SceneGraph::Node* Actor::CreateNode()
420 // create node. Nodes are owned by the update manager
421 SceneGraph::Node* node = SceneGraph::Node::New();
422 OwnerPointer< SceneGraph::Node > transferOwnership( node );
423 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
425 DALI_ASSERT_ALWAYS( tls && "ThreadLocalStorage is null" );
427 AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
432 const std::string& Actor::GetName() const
437 void Actor::SetName( const std::string& name )
441 // ATTENTION: string for debug purposes is not thread safe.
442 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
445 uint32_t Actor::GetId() const
447 return GetNode().GetId();
450 bool Actor::OnStage() const
455 Dali::Layer Actor::GetLayer()
459 // Short-circuit for Layer derived actors
462 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
465 // Find the immediate Layer parent
466 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
468 if( parent->IsLayer() )
470 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
477 void Actor::Add( Actor& child )
479 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
480 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
484 mChildren = new ActorContainer;
487 Actor* const oldParent( child.mParent );
489 // child might already be ours
490 if( this != oldParent )
492 // if we already have parent, unparent us first
495 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
497 // Old parent may need to readjust to missing child
498 if( oldParent->RelayoutDependentOnChildren() )
500 oldParent->RelayoutRequest();
504 // Guard against Add() during previous OnChildRemove callback
507 // Do this first, since user callbacks from within SetParent() may need to remove child
508 mChildren->push_back( ActorPtr( &child ) );
510 // SetParent asserts that child can be added
511 child.SetParent( this );
513 // Notification for derived classes
515 EmitChildAddedSignal( child );
517 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
519 // Only put in a relayout request if there is a suitable dependency
520 if( RelayoutDependentOnChildren() )
528 void Actor::Remove( Actor& child )
530 if( (this == &child) || (!mChildren) )
532 // no children or removing itself
538 // Find the child in mChildren, and unparent it
539 ActorIter end = mChildren->end();
540 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
542 ActorPtr actor = (*iter);
544 if( actor.Get() == &child )
546 // Keep handle for OnChildRemove notification
549 // Do this first, since user callbacks from within SetParent() may need to add the child
550 mChildren->erase( iter );
552 DALI_ASSERT_DEBUG( actor->GetParent() == this );
553 actor->SetParent( NULL );
561 // Only put in a relayout request if there is a suitable dependency
562 if( RelayoutDependentOnChildren() )
568 // Notification for derived classes
569 OnChildRemove( child );
570 EmitChildRemovedSignal( child );
573 void Actor::Unparent()
577 // Remove this actor from the parent. The remove will put a relayout request in for
578 // the parent if required
579 mParent->Remove( *this );
580 // mParent is now NULL!
584 uint32_t Actor::GetChildCount() const
586 return ( NULL != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
589 ActorPtr Actor::GetChildAt( uint32_t index ) const
591 DALI_ASSERT_ALWAYS( index < GetChildCount() );
593 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
596 ActorPtr Actor::FindChildByName( const std::string& actorName )
599 if( actorName == mName )
605 ActorIter end = mChildren->end();
606 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
608 child = (*iter)->FindChildByName( actorName );
619 ActorPtr Actor::FindChildById( const uint32_t id )
628 ActorIter end = mChildren->end();
629 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
631 child = (*iter)->FindChildById( id );
642 void Actor::SetParentOrigin( const Vector3& origin )
644 // node is being used in a separate thread; queue a message to set the value & base value
645 SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
647 // Cache for event-thread access
650 // not allocated, check if different from default
651 if( ParentOrigin::DEFAULT != origin )
653 mParentOrigin = new Vector3( origin );
658 // check if different from current costs more than just set
659 *mParentOrigin = origin;
663 void Actor::SetParentOriginX( float x )
665 const Vector3& current = GetCurrentParentOrigin();
667 SetParentOrigin( Vector3( x, current.y, current.z ) );
670 void Actor::SetParentOriginY( float y )
672 const Vector3& current = GetCurrentParentOrigin();
674 SetParentOrigin( Vector3( current.x, y, current.z ) );
677 void Actor::SetParentOriginZ( float z )
679 const Vector3& current = GetCurrentParentOrigin();
681 SetParentOrigin( Vector3( current.x, current.y, z ) );
684 const Vector3& Actor::GetCurrentParentOrigin() const
686 // Cached for event-thread access
687 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
690 void Actor::SetAnchorPoint( const Vector3& anchor )
692 // node is being used in a separate thread; queue a message to set the value & base value
693 SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
695 // Cache for event-thread access
698 // not allocated, check if different from default
699 if( AnchorPoint::DEFAULT != anchor )
701 mAnchorPoint = new Vector3( anchor );
706 // check if different from current costs more than just set
707 *mAnchorPoint = anchor;
711 void Actor::SetAnchorPointX( float x )
713 const Vector3& current = GetCurrentAnchorPoint();
715 SetAnchorPoint( Vector3( x, current.y, current.z ) );
718 void Actor::SetAnchorPointY( float y )
720 const Vector3& current = GetCurrentAnchorPoint();
722 SetAnchorPoint( Vector3( current.x, y, current.z ) );
725 void Actor::SetAnchorPointZ( float z )
727 const Vector3& current = GetCurrentAnchorPoint();
729 SetAnchorPoint( Vector3( current.x, current.y, z ) );
732 const Vector3& Actor::GetCurrentAnchorPoint() const
734 // Cached for event-thread access
735 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
738 void Actor::SetPosition( float x, float y )
740 SetPosition( Vector3( x, y, 0.0f ) );
743 void Actor::SetPosition( float x, float y, float z )
745 SetPosition( Vector3( x, y, z ) );
748 void Actor::SetPosition( const Vector3& position )
750 mTargetPosition = position;
752 // node is being used in a separate thread; queue a message to set the value & base value
753 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
756 void Actor::SetX( float x )
758 mTargetPosition.x = x;
760 // node is being used in a separate thread; queue a message to set the value & base value
761 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
764 void Actor::SetY( float y )
766 mTargetPosition.y = y;
768 // node is being used in a separate thread; queue a message to set the value & base value
769 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
772 void Actor::SetZ( float z )
774 mTargetPosition.z = z;
776 // node is being used in a separate thread; queue a message to set the value & base value
777 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
780 void Actor::TranslateBy( const Vector3& distance )
782 mTargetPosition += distance;
784 // node is being used in a separate thread; queue a message to set the value & base value
785 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
788 const Vector3& Actor::GetCurrentPosition() const
790 // node is being used in a separate thread; copy the value from the previous update
791 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
794 const Vector3& Actor::GetTargetPosition() const
796 return mTargetPosition;
799 const Vector3& Actor::GetCurrentWorldPosition() const
801 // node is being used in a separate thread; copy the value from the previous update
802 return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
805 const Vector2 Actor::GetCurrentScreenPosition() const
807 if( mScene && OnStage() )
809 Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
810 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
811 worldPosition -= cameraPosition;
813 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
814 Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
815 Vector3 halfActorSize( actorSize * 0.5f );
816 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
818 return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
819 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
822 return Vector2::ZERO;
825 void Actor::SetInheritPosition( bool inherit )
827 if( mInheritPosition != inherit )
829 // non animatable so keep local copy
830 mInheritPosition = inherit;
831 SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
835 bool Actor::IsPositionInherited() const
837 return mInheritPosition;
840 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
842 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
843 normalizedAxis.Normalize();
845 Quaternion orientation( angle, normalizedAxis );
847 SetOrientation( orientation );
850 void Actor::SetOrientation( const Quaternion& orientation )
852 mTargetOrientation = orientation;
854 // node is being used in a separate thread; queue a message to set the value & base value
855 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
858 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
860 RotateBy( Quaternion(angle, axis) );
863 void Actor::RotateBy( const Quaternion& relativeRotation )
865 mTargetOrientation *= Quaternion( relativeRotation );
867 // node is being used in a separate thread; queue a message to set the value & base value
868 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
871 const Quaternion& Actor::GetCurrentOrientation() const
873 // node is being used in a separate thread; copy the value from the previous update
874 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
877 const Quaternion& Actor::GetCurrentWorldOrientation() const
879 // node is being used in a separate thread; copy the value from the previous update
880 return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
883 void Actor::SetScale( float scale )
885 SetScale( Vector3( scale, scale, scale ) );
888 void Actor::SetScale( float x, float y, float z )
890 SetScale( Vector3( x, y, z ) );
893 void Actor::SetScale( const Vector3& scale )
895 mTargetScale = scale;
897 // node is being used in a separate thread; queue a message to set the value & base value
898 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
901 void Actor::SetScaleX( float x )
905 // node is being used in a separate thread; queue a message to set the value & base value
906 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
909 void Actor::SetScaleY( float y )
913 // node is being used in a separate thread; queue a message to set the value & base value
914 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
917 void Actor::SetScaleZ( float z )
921 // node is being used in a separate thread; queue a message to set the value & base value
922 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
925 void Actor::ScaleBy(const Vector3& relativeScale)
927 mTargetScale *= relativeScale;
929 // node is being used in a separate thread; queue a message to set the value & base value
930 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
933 const Vector3& Actor::GetCurrentScale() const
935 // node is being used in a separate thread; copy the value from the previous update
936 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
939 const Vector3& Actor::GetCurrentWorldScale() const
941 // node is being used in a separate thread; copy the value from the previous update
942 return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
945 void Actor::SetInheritScale( bool inherit )
947 if( mInheritScale != inherit )
949 // non animatable so keep local copy
950 mInheritScale = inherit;
951 // node is being used in a separate thread; queue a message to set the value
952 SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
956 bool Actor::IsScaleInherited() const
958 return mInheritScale;
961 Matrix Actor::GetCurrentWorldMatrix() const
963 return GetNode().GetWorldMatrix(0);
966 void Actor::SetVisible( bool visible )
968 SetVisibleInternal( visible, SendMessage::TRUE );
971 bool Actor::IsVisible() const
973 // node is being used in a separate thread; copy the value from the previous update
974 return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
977 void Actor::SetOpacity( float opacity )
979 mTargetColor.a = opacity;
981 // node is being used in a separate thread; queue a message to set the value & base value
982 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
985 float Actor::GetCurrentOpacity() const
987 // node is being used in a separate thread; copy the value from the previous update
988 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
991 ClippingMode::Type Actor::GetClippingMode() const
993 return mClippingMode;
996 uint32_t Actor::GetSortingDepth()
1001 const Vector4& Actor::GetCurrentWorldColor() const
1003 return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1006 void Actor::SetColor( const Vector4& color )
1008 mTargetColor = color;
1010 // node is being used in a separate thread; queue a message to set the value & base value
1011 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
1014 void Actor::SetColorRed( float red )
1016 mTargetColor.r = red;
1018 // node is being used in a separate thread; queue a message to set the value & base value
1019 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
1022 void Actor::SetColorGreen( float green )
1024 mTargetColor.g = green;
1026 // node is being used in a separate thread; queue a message to set the value & base value
1027 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green );
1030 void Actor::SetColorBlue( float blue )
1032 mTargetColor.b = blue;
1034 // node is being used in a separate thread; queue a message to set the value & base value
1035 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1038 const Vector4& Actor::GetCurrentColor() const
1040 // node is being used in a separate thread; copy the value from the previous update
1041 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
1044 void Actor::SetInheritOrientation( bool inherit )
1046 if( mInheritOrientation != inherit )
1048 // non animatable so keep local copy
1049 mInheritOrientation = inherit;
1050 // node is being used in a separate thread; queue a message to set the value
1051 SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
1055 bool Actor::IsOrientationInherited() const
1057 return mInheritOrientation;
1060 void Actor::SetSizeModeFactor( const Vector3& factor )
1062 EnsureRelayoutData();
1064 mRelayoutData->sizeModeFactor = factor;
1067 const Vector3& Actor::GetSizeModeFactor() const
1069 if ( mRelayoutData )
1071 return mRelayoutData->sizeModeFactor;
1074 return GetDefaultSizeModeFactor();
1077 void Actor::SetColorMode( ColorMode colorMode )
1079 // non animatable so keep local copy
1080 mColorMode = colorMode;
1081 // node is being used in a separate thread; queue a message to set the value
1082 SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
1085 ColorMode Actor::GetColorMode() const
1087 // we have cached copy
1091 void Actor::SetSize( float width, float height )
1093 SetSize( Vector2( width, height ) );
1096 void Actor::SetSize( float width, float height, float depth )
1098 SetSize( Vector3( width, height, depth ) );
1101 void Actor::SetSize( const Vector2& size )
1103 SetSize( Vector3( size.width, size.height, 0.f ) );
1106 void Actor::SetSizeInternal( const Vector2& size )
1108 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1111 void Actor::SetSize( const Vector3& size )
1113 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1115 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1116 SetPreferredSize( size.GetVectorXY() );
1120 SetSizeInternal( size );
1124 void Actor::SetSizeInternal( const Vector3& size )
1126 // dont allow recursive loop
1127 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1128 // 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
1129 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1130 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1131 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1135 // node is being used in a separate thread; queue a message to set the value & base value
1136 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1138 // Notification for derived classes
1139 mInsideOnSizeSet = true;
1140 OnSizeSet( mTargetSize );
1141 mInsideOnSizeSet = false;
1143 // Raise a relayout request if the flag is not locked
1144 if( mRelayoutData && !mRelayoutData->insideRelayout )
1151 void Actor::SetWidth( float width )
1153 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1155 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1156 mRelayoutData->preferredSize.width = width;
1160 mTargetSize.width = width;
1162 // node is being used in a separate thread; queue a message to set the value & base value
1163 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1166 mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
1171 void Actor::SetHeight( float height )
1173 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1175 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1176 mRelayoutData->preferredSize.height = height;
1180 mTargetSize.height = height;
1182 // node is being used in a separate thread; queue a message to set the value & base value
1183 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1186 mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
1191 void Actor::SetDepth( float depth )
1193 mTargetSize.depth = depth;
1195 mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
1197 // node is being used in a separate thread; queue a message to set the value & base value
1198 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1201 Vector3 Actor::GetTargetSize() const
1203 Vector3 size = mTargetSize;
1205 if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH )
1207 // Should return animated size if size is animated
1208 size.width = mAnimatedSize.width;
1212 // Should return preferred size if size is fixed as set by SetSize
1213 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1215 size.width = GetPreferredSize().width;
1219 if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT )
1221 size.height = mAnimatedSize.height;
1225 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1227 size.height = GetPreferredSize().height;
1231 if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH )
1233 size.depth = mAnimatedSize.depth;
1239 const Vector3& Actor::GetCurrentSize() const
1241 // node is being used in a separate thread; copy the value from the previous update
1242 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1245 Vector3 Actor::GetNaturalSize() const
1247 // It is up to deriving classes to return the appropriate natural size
1248 return Vector3( 0.0f, 0.0f, 0.0f );
1251 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1253 EnsureRelayoutData();
1255 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1256 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1258 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1260 if( dimension & ( 1 << i ) )
1262 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1264 mRelayoutData->useAssignedSize[ i ] = true;
1268 mRelayoutData->resizePolicies[ i ] = policy;
1269 mRelayoutData->useAssignedSize[ i ] = false;
1274 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1276 if( dimension & Dimension::WIDTH )
1278 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1281 if( dimension & Dimension::HEIGHT )
1283 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1287 // If calling SetResizePolicy, assume we want relayout enabled
1288 SetRelayoutEnabled( true );
1290 // If the resize policy is set to be FIXED, the preferred size
1291 // should be overrided by the target size. Otherwise the target
1292 // size should be overrided by the preferred size.
1294 if( dimension & Dimension::WIDTH )
1296 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1298 mRelayoutData->preferredSize.width = mTargetSize.width;
1300 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1302 mTargetSize.width = mRelayoutData->preferredSize.width;
1306 if( dimension & Dimension::HEIGHT )
1308 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1310 mRelayoutData->preferredSize.height = mTargetSize.height;
1312 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1314 mTargetSize.height = mRelayoutData->preferredSize.height;
1318 OnSetResizePolicy( policy, dimension );
1320 // Trigger relayout on this control
1324 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1326 if ( mRelayoutData )
1328 // If more than one dimension is requested, just return the first one found
1329 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1331 if( ( dimension & ( 1 << i ) ) )
1333 if( mRelayoutData->useAssignedSize[ i ] )
1335 return ResizePolicy::USE_ASSIGNED_SIZE;
1339 return mRelayoutData->resizePolicies[ i ];
1345 return ResizePolicy::DEFAULT;
1348 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1350 EnsureRelayoutData();
1352 mRelayoutData->sizeSetPolicy = policy;
1354 // Trigger relayout on this control
1358 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1360 if ( mRelayoutData )
1362 return mRelayoutData->sizeSetPolicy;
1365 return DEFAULT_SIZE_SCALE_POLICY;
1368 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1370 EnsureRelayoutData();
1372 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1374 if( dimension & ( 1 << i ) )
1376 mRelayoutData->dimensionDependencies[ i ] = dependency;
1381 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1383 if ( mRelayoutData )
1385 // If more than one dimension is requested, just return the first one found
1386 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1388 if( ( dimension & ( 1 << i ) ) )
1390 return mRelayoutData->dimensionDependencies[ i ];
1395 return Dimension::ALL_DIMENSIONS; // Default
1398 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1400 // If relayout data has not been allocated yet and the client is requesting
1401 // to disable it, do nothing
1402 if( mRelayoutData || relayoutEnabled )
1404 EnsureRelayoutData();
1406 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1408 mRelayoutData->relayoutEnabled = relayoutEnabled;
1412 bool Actor::IsRelayoutEnabled() const
1414 // Assume that if relayout data has not been allocated yet then
1415 // relayout is disabled
1416 return mRelayoutData && mRelayoutData->relayoutEnabled;
1419 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1421 EnsureRelayoutData();
1423 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1425 if( dimension & ( 1 << i ) )
1427 mRelayoutData->dimensionDirty[ i ] = dirty;
1432 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1434 if ( mRelayoutData )
1436 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1438 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1448 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1450 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1453 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1455 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1458 uint32_t Actor::AddRenderer( Renderer& renderer )
1462 mRenderers = new RendererContainer;
1465 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1466 RendererPtr rendererPtr = RendererPtr( &renderer );
1467 mRenderers->push_back( rendererPtr );
1468 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1472 uint32_t Actor::GetRendererCount() const
1474 uint32_t rendererCount(0);
1477 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1480 return rendererCount;
1483 RendererPtr Actor::GetRendererAt( uint32_t index )
1485 RendererPtr renderer;
1486 if( index < GetRendererCount() )
1488 renderer = ( *mRenderers )[ index ];
1494 void Actor::RemoveRenderer( Renderer& renderer )
1498 RendererIter end = mRenderers->end();
1499 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1501 if( (*iter).Get() == &renderer )
1503 mRenderers->erase( iter );
1504 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1511 void Actor::RemoveRenderer( uint32_t index )
1513 if( index < GetRendererCount() )
1515 RendererPtr renderer = ( *mRenderers )[ index ];
1516 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1517 mRenderers->erase( mRenderers->begin()+index );
1521 bool Actor::IsOverlay() const
1523 return ( DrawMode::OVERLAY_2D == mDrawMode );
1526 void Actor::SetDrawMode( DrawMode::Type drawMode )
1528 // this flag is not animatable so keep the value
1529 mDrawMode = drawMode;
1531 // node is being used in a separate thread; queue a message to set the value
1532 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1535 DrawMode::Type Actor::GetDrawMode() const
1540 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1542 // only valid when on-stage
1543 if( mScene && OnStage() )
1545 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1547 Vector2 converted( screenX, screenY );
1549 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1550 uint32_t taskCount = taskList.GetTaskCount();
1551 for( uint32_t i = taskCount; i > 0; --i )
1553 RenderTaskPtr task = taskList.GetTask( i - 1 );
1554 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1556 // found a task where this conversion was ok so return
1564 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1566 bool retval = false;
1567 // only valid when on-stage
1570 CameraActor* camera = renderTask.GetCameraActor();
1574 renderTask.GetViewport( viewport );
1576 // need to translate coordinates to render tasks coordinate space
1577 Vector2 converted( screenX, screenY );
1578 if( renderTask.TranslateCoordinates( converted ) )
1580 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1587 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1589 // Early-out if not on stage
1595 // Get the ModelView matrix
1597 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1599 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1600 Matrix invertedMvp( false/*don't init*/);
1601 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1602 bool success = invertedMvp.Invert();
1604 // Convert to GL coordinates
1605 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1610 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1617 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1623 if( XyPlaneIntersect( nearPos, farPos, local ) )
1625 Vector3 size = GetCurrentSize();
1626 localX = local.x + size.x * 0.5f;
1627 localY = local.y + size.y * 0.5f;
1638 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1641 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1643 Mathematical Formulation
1645 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1647 ( p - c ) dot ( p - c ) = r^2
1649 Given a ray with a point of origin 'o', and a direction vector 'd':
1651 ray(t) = o + td, t >= 0
1653 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1655 (o + td - c ) dot ( o + td - c ) = r^2
1657 To solve for t we first expand the above into a more recognisable quadratic equation form
1659 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1668 B = 2( o - c ) dot d
1669 C = ( o - c ) dot ( o - c ) - r^2
1671 which can be solved using a standard quadratic formula.
1673 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1675 Practical Simplification
1677 In a renderer, we often differentiate between world space and object space. In the object space
1678 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1679 into object space, the mathematical solution presented above can be simplified significantly.
1681 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1685 and we can find the t at which the (transformed) ray intersects the sphere by
1687 ( o + td ) dot ( o + td ) = r^2
1689 According to the reasoning above, we expand the above quadratic equation into the general form
1693 which now has coefficients:
1700 // Early-out if not on stage
1706 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1708 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1709 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1710 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1712 // Compute the radius is not needed, square radius it's enough.
1713 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1715 // Scale the sphere.
1716 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1718 const float width = size.width * scale.width;
1719 const float height = size.height * scale.height;
1721 float squareSphereRadius = 0.5f * ( width * width + height * height );
1723 float a = rayDir.Dot( rayDir ); // a
1724 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1725 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1727 return ( b2 * b2 - a * c ) >= 0.f;
1730 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1736 // Transforms the ray to the local reference system.
1737 // Calculate the inverse of Model matrix
1738 Matrix invModelMatrix( false/*don't init*/);
1740 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1741 invModelMatrix = GetNode().GetWorldMatrix(0);
1742 invModelMatrix.Invert();
1744 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1745 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1747 // Test with the actor's XY plane (Normal = 0 0 1 1).
1749 float a = -rayOriginLocal.z;
1750 float b = rayDirLocal.z;
1752 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1754 // Ray travels distance * rayDirLocal to intersect with plane.
1757 const Vector3& size = GetNode().GetSize( bufferIndex );
1759 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1760 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1762 // Test with the actor's geometry.
1763 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1770 void Actor::SetLeaveRequired( bool required )
1772 mLeaveRequired = required;
1775 bool Actor::GetLeaveRequired() const
1777 return mLeaveRequired;
1780 void Actor::SetKeyboardFocusable( bool focusable )
1782 mKeyboardFocusable = focusable;
1785 bool Actor::IsKeyboardFocusable() const
1787 return mKeyboardFocusable;
1790 bool Actor::GetTouchRequired() const
1792 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1795 bool Actor::GetHoverRequired() const
1797 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1800 bool Actor::GetWheelEventRequired() const
1802 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1805 bool Actor::IsHittable() const
1807 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1810 ActorGestureData& Actor::GetGestureData()
1812 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1813 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1814 if( NULL == mGestureData )
1816 mGestureData = new ActorGestureData;
1818 return *mGestureData;
1821 bool Actor::IsGestureRequred( DevelGesture::Type type ) const
1823 return mGestureData && mGestureData->IsGestureRequred( type );
1826 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1828 bool consumed = false;
1830 if( !mTouchSignal.Empty() )
1832 Dali::Actor handle( this );
1833 consumed = mTouchSignal.Emit( handle, touch );
1836 if( !mTouchedSignal.Empty() )
1838 Dali::Actor handle( this );
1839 consumed |= mTouchedSignal.Emit( handle, event );
1844 // Notification for derived classes
1845 consumed = OnTouchEvent( event ); // TODO
1851 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1853 bool consumed = false;
1855 if( !mHoveredSignal.Empty() )
1857 Dali::Actor handle( this );
1858 consumed = mHoveredSignal.Emit( handle, event );
1863 // Notification for derived classes
1864 consumed = OnHoverEvent( event );
1870 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1872 bool consumed = false;
1874 if( !mWheelEventSignal.Empty() )
1876 Dali::Actor handle( this );
1877 consumed = mWheelEventSignal.Emit( handle, event );
1882 // Notification for derived classes
1883 consumed = OnWheelEvent( event );
1889 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1891 if( ! mVisibilityChangedSignal.Empty() )
1893 Dali::Actor handle( this );
1894 mVisibilityChangedSignal.Emit( handle, visible, type );
1898 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1900 if( ! mLayoutDirectionChangedSignal.Empty() )
1902 Dali::Actor handle( this );
1903 mLayoutDirectionChangedSignal.Emit( handle, type );
1907 void Actor::EmitChildAddedSignal( Actor& child )
1909 if( ! mChildAddedSignal.Empty() )
1911 Dali::Actor handle( &child );
1912 mChildAddedSignal.Emit( handle );
1916 void Actor::EmitChildRemovedSignal( Actor& child )
1918 if( ! mChildRemovedSignal.Empty() )
1920 Dali::Actor handle( &child );
1921 mChildRemovedSignal.Emit( handle );
1925 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1927 return mTouchedSignal;
1930 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1932 return mTouchSignal;
1935 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1937 return mHoveredSignal;
1940 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1942 return mWheelEventSignal;
1945 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1947 return mOnStageSignal;
1950 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1952 return mOffStageSignal;
1955 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1957 return mOnRelayoutSignal;
1960 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1962 return mVisibilityChangedSignal;
1965 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1967 return mLayoutDirectionChangedSignal;
1970 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1972 return mChildAddedSignal;
1975 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1977 return mChildRemovedSignal;
1980 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1982 return mChildOrderChangedSignal;
1985 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1987 bool connected( true );
1988 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1990 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1992 actor->TouchedSignal().Connect( tracker, functor );
1994 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1996 actor->HoveredSignal().Connect( tracker, functor );
1998 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2000 actor->WheelEventSignal().Connect( tracker, functor );
2002 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2004 actor->OnStageSignal().Connect( tracker, functor );
2006 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2008 actor->OffStageSignal().Connect( tracker, functor );
2010 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2012 actor->OnRelayoutSignal().Connect( tracker, functor );
2014 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2016 actor->TouchSignal().Connect( tracker, functor );
2018 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
2020 actor->VisibilityChangedSignal().Connect( tracker, functor );
2022 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2024 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2026 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2028 actor->ChildAddedSignal().Connect( tracker, functor );
2030 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2032 actor->ChildRemovedSignal().Connect( tracker, functor );
2036 // signalName does not match any signal
2043 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2049 mParentOrigin( NULL ),
2050 mAnchorPoint( NULL ),
2051 mRelayoutData( NULL ),
2052 mGestureData( NULL ),
2056 mWheelEventSignal(),
2059 mOnRelayoutSignal(),
2060 mVisibilityChangedSignal(),
2061 mLayoutDirectionChangedSignal(),
2062 mChildAddedSignal(),
2063 mChildRemovedSignal(),
2064 mChildOrderChangedSignal(),
2065 mTargetOrientation( Quaternion::IDENTITY ),
2066 mTargetColor( Color::WHITE ),
2067 mTargetSize( Vector3::ZERO ),
2068 mTargetPosition( Vector3::ZERO ),
2069 mTargetScale( Vector3::ONE ),
2070 mAnimatedSize( Vector3::ZERO ),
2074 mUseAnimatedSize( AnimatedSizeFlag::CLEAR ),
2075 mIsRoot( ROOT_LAYER == derivedType ),
2076 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2077 mIsOnStage( false ),
2079 mLeaveRequired( false ),
2080 mKeyboardFocusable( false ),
2081 mDerivedRequiresTouch( false ),
2082 mDerivedRequiresHover( false ),
2083 mDerivedRequiresWheelEvent( false ),
2084 mOnStageSignalled( false ),
2085 mInsideOnSizeSet( false ),
2086 mInheritPosition( true ),
2087 mInheritOrientation( true ),
2088 mInheritScale( true ),
2089 mPositionUsesAnchorPoint( true ),
2091 mInheritLayoutDirection( true ),
2092 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2093 mDrawMode( DrawMode::NORMAL ),
2094 mColorMode( Node::DEFAULT_COLOR_MODE ),
2095 mClippingMode( ClippingMode::DISABLED )
2099 void Actor::Initialize()
2103 GetEventThreadServices().RegisterObject( this );
2108 // Remove mParent pointers from children even if we're destroying core,
2109 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2112 ActorConstIter endIter = mChildren->end();
2113 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2115 (*iter)->SetParent( NULL );
2121 // Guard to allow handle destruction after Core has been destroyed
2122 if( EventThreadServices::IsCoreRunning() )
2124 // Root layer will destroy its node in its own destructor
2127 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2129 GetEventThreadServices().UnregisterObject( this );
2133 // Cleanup optional gesture data
2134 delete mGestureData;
2136 // Cleanup optional parent origin and anchor
2137 delete mParentOrigin;
2138 delete mAnchorPoint;
2140 // Delete optional relayout data
2141 delete mRelayoutData;
2144 void Actor::ConnectToStage( uint32_t parentDepth )
2146 // This container is used instead of walking the Actor hierarchy.
2147 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2148 ActorContainer connectionList;
2152 mScene->RequestRebuildDepthTree();
2155 // This stage is atomic i.e. not interrupted by user callbacks.
2156 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2158 // Notify applications about the newly connected actors.
2159 const ActorIter endIter = connectionList.end();
2160 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2162 (*iter)->NotifyStageConnection();
2168 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2170 DALI_ASSERT_ALWAYS( !OnStage() );
2173 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2175 ConnectToSceneGraph();
2177 // Notification for internal derived classes
2178 OnStageConnectionInternal();
2180 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2181 connectionList.push_back( ActorPtr( this ) );
2183 // Recursively connect children
2186 ActorConstIter endIter = mChildren->end();
2187 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2189 (*iter)->SetScene( *mScene );
2190 (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2196 * This method is called when the Actor is connected to the Stage.
2197 * The parent must have added its Node to the scene-graph.
2198 * The child must connect its Node to the parent's Node.
2199 * This is recursive; the child calls ConnectToStage() for its children.
2201 void Actor::ConnectToSceneGraph()
2203 DALI_ASSERT_DEBUG( mParent != NULL);
2205 // Reparent Node in next Update
2206 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2208 // Request relayout on all actors that are added to the scenegraph
2211 // Notification for Object::Observers
2215 void Actor::NotifyStageConnection()
2217 // Actors can be removed (in a callback), before the on-stage stage is reported.
2218 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2219 if( OnStage() && !mOnStageSignalled )
2221 // Notification for external (CustomActor) derived classes
2222 OnStageConnectionExternal( mDepth );
2224 if( !mOnStageSignal.Empty() )
2226 Dali::Actor handle( this );
2227 mOnStageSignal.Emit( handle );
2230 // Guard against Remove during callbacks
2233 mOnStageSignalled = true; // signal required next time Actor is removed
2238 void Actor::DisconnectFromStage()
2240 // This container is used instead of walking the Actor hierachy.
2241 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2242 ActorContainer disconnectionList;
2246 mScene->RequestRebuildDepthTree();
2249 // This stage is atomic i.e. not interrupted by user callbacks
2250 RecursiveDisconnectFromStage( disconnectionList );
2252 // Notify applications about the newly disconnected actors.
2253 const ActorIter endIter = disconnectionList.end();
2254 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2256 (*iter)->NotifyStageDisconnection();
2260 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2262 // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2265 // Recursively disconnect children
2268 ActorConstIter endIter = mChildren->end();
2269 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2271 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2275 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2276 disconnectionList.push_back( ActorPtr( this ) );
2278 // Notification for internal derived classes
2279 OnStageDisconnectionInternal();
2281 DisconnectFromSceneGraph();
2285 * This method is called by an actor or its parent, before a node removal message is sent.
2286 * This is recursive; the child calls DisconnectFromStage() for its children.
2288 void Actor::DisconnectFromSceneGraph()
2290 // Notification for Object::Observers
2291 OnSceneObjectRemove();
2294 void Actor::NotifyStageDisconnection()
2296 // Actors can be added (in a callback), before the off-stage state is reported.
2297 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2298 // only do this step if there is a stage, i.e. Core is not being shut down
2299 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2301 // Notification for external (CustomeActor) derived classes
2302 OnStageDisconnectionExternal();
2304 if( !mOffStageSignal.Empty() )
2306 Dali::Actor handle( this );
2307 mOffStageSignal.Emit( handle );
2310 // Guard against Add during callbacks
2313 mOnStageSignalled = false; // signal required next time Actor is added
2318 bool Actor::IsNodeConnected() const
2320 bool connected( false );
2324 if( IsRoot() || GetNode().GetParent() )
2333 // This method initiates traversal of the actor tree using depth-first
2334 // traversal to set a depth index based on traversal order. It sends a
2335 // single message to update manager to update all the actor's nodes in
2336 // this tree with the depth index. The sceneGraphNodeDepths vector's
2337 // elements are ordered by depth, and could be used to reduce sorting
2338 // in the update thread.
2339 void Actor::RebuildDepthTree()
2341 DALI_LOG_TIMER_START(depthTimer);
2343 // Vector of scene-graph nodes and their depths to send to UpdateManager
2344 // in a single message
2345 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2347 int32_t depthIndex = 1;
2348 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2350 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2351 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2354 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2356 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2357 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2359 // Create/add to children of this node
2362 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2364 Actor* childActor = (*it).Get();
2366 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2371 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2375 case Dali::Actor::Property::PARENT_ORIGIN:
2377 Property::Type type = property.GetType();
2378 if( type == Property::VECTOR3 )
2380 SetParentOrigin( property.Get< Vector3 >() );
2382 else if ( type == Property::STRING )
2384 std::string parentOriginString;
2385 property.Get( parentOriginString );
2386 Vector3 parentOrigin;
2387 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2389 SetParentOrigin( parentOrigin );
2395 case Dali::Actor::Property::PARENT_ORIGIN_X:
2397 SetParentOriginX( property.Get< float >() );
2401 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2403 SetParentOriginY( property.Get< float >() );
2407 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2409 SetParentOriginZ( property.Get< float >() );
2413 case Dali::Actor::Property::ANCHOR_POINT:
2415 Property::Type type = property.GetType();
2416 if( type == Property::VECTOR3 )
2418 SetAnchorPoint( property.Get< Vector3 >() );
2420 else if ( type == Property::STRING )
2422 std::string anchorPointString;
2423 property.Get( anchorPointString );
2425 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2427 SetAnchorPoint( anchor );
2433 case Dali::Actor::Property::ANCHOR_POINT_X:
2435 SetAnchorPointX( property.Get< float >() );
2439 case Dali::Actor::Property::ANCHOR_POINT_Y:
2441 SetAnchorPointY( property.Get< float >() );
2445 case Dali::Actor::Property::ANCHOR_POINT_Z:
2447 SetAnchorPointZ( property.Get< float >() );
2451 case Dali::Actor::Property::SIZE:
2453 Property::Type type = property.GetType();
2454 if( type == Property::VECTOR2 )
2456 SetSize( property.Get< Vector2 >() );
2458 else if ( type == Property::VECTOR3 )
2460 SetSize( property.Get< Vector3 >() );
2465 case Dali::Actor::Property::SIZE_WIDTH:
2467 SetWidth( property.Get< float >() );
2471 case Dali::Actor::Property::SIZE_HEIGHT:
2473 SetHeight( property.Get< float >() );
2477 case Dali::Actor::Property::SIZE_DEPTH:
2479 SetDepth( property.Get< float >() );
2483 case Dali::Actor::Property::POSITION:
2485 Property::Type type = property.GetType();
2486 if( type == Property::VECTOR2 )
2488 Vector2 position = property.Get< Vector2 >();
2489 SetPosition( Vector3( position.x, position.y, 0.0f ) );
2491 else if ( type == Property::VECTOR3 )
2493 SetPosition( property.Get< Vector3 >() );
2498 case Dali::Actor::Property::POSITION_X:
2500 SetX( property.Get< float >() );
2504 case Dali::Actor::Property::POSITION_Y:
2506 SetY( property.Get< float >() );
2510 case Dali::Actor::Property::POSITION_Z:
2512 SetZ( property.Get< float >() );
2516 case Dali::Actor::Property::ORIENTATION:
2518 SetOrientation( property.Get< Quaternion >() );
2522 case Dali::Actor::Property::SCALE:
2524 Property::Type type = property.GetType();
2525 if( type == Property::FLOAT )
2527 float scale = property.Get< float >();
2528 SetScale( scale, scale, scale );
2530 else if ( type == Property::VECTOR3 )
2532 SetScale( property.Get< Vector3 >() );
2537 case Dali::Actor::Property::SCALE_X:
2539 SetScaleX( property.Get< float >() );
2543 case Dali::Actor::Property::SCALE_Y:
2545 SetScaleY( property.Get< float >() );
2549 case Dali::Actor::Property::SCALE_Z:
2551 SetScaleZ( property.Get< float >() );
2555 case Dali::Actor::Property::VISIBLE:
2557 SetVisible( property.Get< bool >() );
2561 case Dali::Actor::Property::COLOR:
2563 Property::Type type = property.GetType();
2564 if( type == Property::VECTOR3 )
2566 Vector3 color = property.Get< Vector3 >();
2567 SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2569 else if( type == Property::VECTOR4 )
2571 SetColor( property.Get< Vector4 >() );
2576 case Dali::Actor::Property::COLOR_RED:
2578 SetColorRed( property.Get< float >() );
2582 case Dali::Actor::Property::COLOR_GREEN:
2584 SetColorGreen( property.Get< float >() );
2588 case Dali::Actor::Property::COLOR_BLUE:
2590 SetColorBlue( property.Get< float >() );
2594 case Dali::Actor::Property::COLOR_ALPHA:
2595 case Dali::Actor::Property::OPACITY:
2598 if( property.Get( value ) )
2600 SetOpacity( value );
2605 case Dali::Actor::Property::NAME:
2607 SetName( property.Get< std::string >() );
2611 case Dali::Actor::Property::SENSITIVE:
2613 SetSensitive( property.Get< bool >() );
2617 case Dali::Actor::Property::LEAVE_REQUIRED:
2619 SetLeaveRequired( property.Get< bool >() );
2623 case Dali::Actor::Property::INHERIT_POSITION:
2625 SetInheritPosition( property.Get< bool >() );
2629 case Dali::Actor::Property::INHERIT_ORIENTATION:
2631 SetInheritOrientation( property.Get< bool >() );
2635 case Dali::Actor::Property::INHERIT_SCALE:
2637 SetInheritScale( property.Get< bool >() );
2641 case Dali::Actor::Property::COLOR_MODE:
2643 ColorMode mode = mColorMode;
2644 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2646 SetColorMode( mode );
2651 case Dali::Actor::Property::DRAW_MODE:
2653 DrawMode::Type mode = mDrawMode;
2654 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2656 SetDrawMode( mode );
2661 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2663 SetSizeModeFactor( property.Get< Vector3 >() );
2667 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2669 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2670 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2672 SetResizePolicy( type, Dimension::WIDTH );
2677 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2679 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2680 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2682 SetResizePolicy( type, Dimension::HEIGHT );
2687 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2689 SizeScalePolicy::Type type = GetSizeScalePolicy();
2690 if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2692 SetSizeScalePolicy( type );
2697 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2699 if( property.Get< bool >() )
2701 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2706 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2708 if( property.Get< bool >() )
2710 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2715 case Dali::Actor::Property::PADDING:
2717 Vector4 padding = property.Get< Vector4 >();
2718 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2719 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2723 case Dali::Actor::Property::MINIMUM_SIZE:
2725 Vector2 size = property.Get< Vector2 >();
2726 SetMinimumSize( size.x, Dimension::WIDTH );
2727 SetMinimumSize( size.y, Dimension::HEIGHT );
2731 case Dali::Actor::Property::MAXIMUM_SIZE:
2733 Vector2 size = property.Get< Vector2 >();
2734 SetMaximumSize( size.x, Dimension::WIDTH );
2735 SetMaximumSize( size.y, Dimension::HEIGHT );
2739 case Dali::DevelActor::Property::SIBLING_ORDER:
2743 if( property.Get( value ) )
2745 SetSiblingOrder( value );
2750 case Dali::Actor::Property::CLIPPING_MODE:
2752 ClippingMode::Type convertedValue = mClippingMode;
2753 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2755 mClippingMode = convertedValue;
2756 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2761 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
2764 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2766 mPositionUsesAnchorPoint = value;
2767 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2772 case Dali::Actor::Property::LAYOUT_DIRECTION:
2774 Dali::LayoutDirection::Type direction = mLayoutDirection;
2775 mInheritLayoutDirection = false;
2777 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2779 InheritLayoutDirectionRecursively( this, direction, true );
2784 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2787 if( property.Get( value ) )
2789 SetInheritLayoutDirection( value );
2794 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
2797 if( property.Get( value ) )
2799 SetKeyboardFocusable( value );
2804 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
2806 SetUpdateSizeHint( property.Get< Vector2 >() );
2812 // this can happen in the case of a non-animatable default property so just do nothing
2818 // TODO: This method needs to be removed
2819 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2821 switch( entry.GetType() )
2823 case Property::BOOLEAN:
2825 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2826 DALI_ASSERT_DEBUG( NULL != property );
2828 // property is being used in a separate thread; queue a message to set the property
2829 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2834 case Property::INTEGER:
2836 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2837 DALI_ASSERT_DEBUG( NULL != property );
2839 // property is being used in a separate thread; queue a message to set the property
2840 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2845 case Property::FLOAT:
2847 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2848 DALI_ASSERT_DEBUG( NULL != property );
2850 // property is being used in a separate thread; queue a message to set the property
2851 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2856 case Property::VECTOR2:
2858 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2859 DALI_ASSERT_DEBUG( NULL != property );
2861 // property is being used in a separate thread; queue a message to set the property
2862 if(entry.componentIndex == 0)
2864 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2866 else if(entry.componentIndex == 1)
2868 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2872 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2878 case Property::VECTOR3:
2880 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2881 DALI_ASSERT_DEBUG( NULL != property );
2883 // property is being used in a separate thread; queue a message to set the property
2884 if(entry.componentIndex == 0)
2886 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2888 else if(entry.componentIndex == 1)
2890 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2892 else if(entry.componentIndex == 2)
2894 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2898 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2904 case Property::VECTOR4:
2906 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2907 DALI_ASSERT_DEBUG( NULL != property );
2909 // property is being used in a separate thread; queue a message to set the property
2910 if(entry.componentIndex == 0)
2912 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2914 else if(entry.componentIndex == 1)
2916 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2918 else if(entry.componentIndex == 2)
2920 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2922 else if(entry.componentIndex == 3)
2924 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2928 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2934 case Property::ROTATION:
2936 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2937 DALI_ASSERT_DEBUG( NULL != property );
2939 // property is being used in a separate thread; queue a message to set the property
2940 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2945 case Property::MATRIX:
2947 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2948 DALI_ASSERT_DEBUG( NULL != property );
2950 // property is being used in a separate thread; queue a message to set the property
2951 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2956 case Property::MATRIX3:
2958 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2959 DALI_ASSERT_DEBUG( NULL != property );
2961 // property is being used in a separate thread; queue a message to set the property
2962 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2969 // nothing to do for other types
2974 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2976 Property::Value value;
2978 if( ! GetCachedPropertyValue( index, value ) )
2980 // If property value is not stored in the event-side, then it must be a scene-graph only property
2981 GetCurrentPropertyValue( index, value );
2987 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2989 Property::Value value;
2991 if( ! GetCurrentPropertyValue( index, value ) )
2993 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2994 GetCachedPropertyValue( index, value );
3000 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3002 switch( animationType )
3005 case Animation::BETWEEN:
3009 case Dali::Actor::Property::SIZE:
3011 if( value.Get( mTargetSize ) )
3013 mAnimatedSize = mTargetSize;
3014 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3016 // Notify deriving classes
3017 OnSizeAnimation( animation, mTargetSize );
3022 case Dali::Actor::Property::SIZE_WIDTH:
3024 if( value.Get( mTargetSize.width ) )
3026 mAnimatedSize.width = mTargetSize.width;
3027 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3029 // Notify deriving classes
3030 OnSizeAnimation( animation, mTargetSize );
3035 case Dali::Actor::Property::SIZE_HEIGHT:
3037 if( value.Get( mTargetSize.height ) )
3039 mAnimatedSize.height = mTargetSize.height;
3040 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3042 // Notify deriving classes
3043 OnSizeAnimation( animation, mTargetSize );
3048 case Dali::Actor::Property::SIZE_DEPTH:
3050 if( value.Get( mTargetSize.depth ) )
3052 mAnimatedSize.depth = mTargetSize.depth;
3053 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3055 // Notify deriving classes
3056 OnSizeAnimation( animation, mTargetSize );
3061 case Dali::Actor::Property::POSITION:
3063 value.Get( mTargetPosition );
3067 case Dali::Actor::Property::POSITION_X:
3069 value.Get( mTargetPosition.x );
3073 case Dali::Actor::Property::POSITION_Y:
3075 value.Get( mTargetPosition.y );
3079 case Dali::Actor::Property::POSITION_Z:
3081 value.Get( mTargetPosition.z );
3085 case Dali::Actor::Property::ORIENTATION:
3087 value.Get( mTargetOrientation );
3091 case Dali::Actor::Property::SCALE:
3093 value.Get( mTargetScale );
3097 case Dali::Actor::Property::SCALE_X:
3099 value.Get( mTargetScale.x );
3103 case Dali::Actor::Property::SCALE_Y:
3105 value.Get( mTargetScale.y );
3109 case Dali::Actor::Property::SCALE_Z:
3111 value.Get( mTargetScale.z );
3115 case Dali::Actor::Property::VISIBLE:
3117 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3121 case Dali::Actor::Property::COLOR:
3123 value.Get( mTargetColor );
3127 case Dali::Actor::Property::COLOR_RED:
3129 value.Get( mTargetColor.r );
3133 case Dali::Actor::Property::COLOR_GREEN:
3135 value.Get( mTargetColor.g );
3139 case Dali::Actor::Property::COLOR_BLUE:
3141 value.Get( mTargetColor.b );
3145 case Dali::Actor::Property::COLOR_ALPHA:
3146 case Dali::Actor::Property::OPACITY:
3148 value.Get( mTargetColor.a );
3154 // Not an animatable property. Do nothing.
3165 case Dali::Actor::Property::SIZE:
3167 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3169 mAnimatedSize = mTargetSize;
3170 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3172 // Notify deriving classes
3173 OnSizeAnimation( animation, mTargetSize );
3178 case Dali::Actor::Property::SIZE_WIDTH:
3180 if( AdjustValue< float >( mTargetSize.width, value ) )
3182 mAnimatedSize.width = mTargetSize.width;
3183 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3185 // Notify deriving classes
3186 OnSizeAnimation( animation, mTargetSize );
3191 case Dali::Actor::Property::SIZE_HEIGHT:
3193 if( AdjustValue< float >( mTargetSize.height, value ) )
3195 mAnimatedSize.height = mTargetSize.height;
3196 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3198 // Notify deriving classes
3199 OnSizeAnimation( animation, mTargetSize );
3204 case Dali::Actor::Property::SIZE_DEPTH:
3206 if( AdjustValue< float >( mTargetSize.depth, value ) )
3208 mAnimatedSize.depth = mTargetSize.depth;
3209 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3211 // Notify deriving classes
3212 OnSizeAnimation( animation, mTargetSize );
3217 case Dali::Actor::Property::POSITION:
3219 AdjustValue< Vector3 >( mTargetPosition, value );
3223 case Dali::Actor::Property::POSITION_X:
3225 AdjustValue< float >( mTargetPosition.x, value );
3229 case Dali::Actor::Property::POSITION_Y:
3231 AdjustValue< float >( mTargetPosition.y, value );
3235 case Dali::Actor::Property::POSITION_Z:
3237 AdjustValue< float >( mTargetPosition.z, value );
3241 case Dali::Actor::Property::ORIENTATION:
3243 Quaternion relativeValue;
3244 if( value.Get( relativeValue ) )
3246 mTargetOrientation *= relativeValue;
3251 case Dali::Actor::Property::SCALE:
3253 AdjustValue< Vector3 >( mTargetScale, value );
3257 case Dali::Actor::Property::SCALE_X:
3259 AdjustValue< float >( mTargetScale.x, value );
3263 case Dali::Actor::Property::SCALE_Y:
3265 AdjustValue< float >( mTargetScale.y, value );
3269 case Dali::Actor::Property::SCALE_Z:
3271 AdjustValue< float >( mTargetScale.z, value );
3275 case Dali::Actor::Property::VISIBLE:
3277 bool relativeValue = false;
3278 if( value.Get( relativeValue ) )
3280 bool visible = mVisible || relativeValue;
3281 SetVisibleInternal( visible, SendMessage::FALSE );
3286 case Dali::Actor::Property::COLOR:
3288 AdjustValue< Vector4 >( mTargetColor, value );
3292 case Dali::Actor::Property::COLOR_RED:
3294 AdjustValue< float >( mTargetColor.r, value );
3298 case Dali::Actor::Property::COLOR_GREEN:
3300 AdjustValue< float >( mTargetColor.g, value );
3304 case Dali::Actor::Property::COLOR_BLUE:
3306 AdjustValue< float >( mTargetColor.b, value );
3310 case Dali::Actor::Property::COLOR_ALPHA:
3311 case Dali::Actor::Property::OPACITY:
3313 AdjustValue< float >( mTargetColor.a, value );
3319 // Not an animatable property. Do nothing.
3328 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3330 const PropertyBase* property( NULL );
3334 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3335 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3336 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3337 case Dali::Actor::Property::SIZE_DEPTH:
3339 property = &GetNode().mSize;
3342 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3343 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3344 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3345 case Dali::Actor::Property::POSITION_Z:
3347 property = &GetNode().mPosition;
3350 case Dali::Actor::Property::ORIENTATION:
3352 property = &GetNode().mOrientation;
3355 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3356 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3357 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3358 case Dali::Actor::Property::SCALE_Z:
3360 property = &GetNode().mScale;
3363 case Dali::Actor::Property::VISIBLE:
3365 property = &GetNode().mVisible;
3368 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3369 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3370 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3371 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3372 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3373 case Dali::Actor::Property::OPACITY:
3375 property = &GetNode().mColor;
3385 // not our property, ask base
3386 property = Object::GetSceneObjectAnimatableProperty( index );
3392 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3394 const PropertyInputImpl* property( NULL );
3398 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3399 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3400 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3401 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3403 property = &GetNode().mParentOrigin;
3406 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3407 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3408 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3409 case Dali::Actor::Property::ANCHOR_POINT_Z:
3411 property = &GetNode().mAnchorPoint;
3414 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3415 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3416 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3417 case Dali::Actor::Property::WORLD_POSITION_Z:
3419 property = &GetNode().mWorldPosition;
3422 case Dali::Actor::Property::WORLD_ORIENTATION:
3424 property = &GetNode().mWorldOrientation;
3427 case Dali::Actor::Property::WORLD_SCALE:
3429 property = &GetNode().mWorldScale;
3432 case Dali::Actor::Property::WORLD_COLOR:
3434 property = &GetNode().mWorldColor;
3437 case Dali::Actor::Property::WORLD_MATRIX:
3439 property = &GetNode().mWorldMatrix;
3442 case Dali::Actor::Property::CULLED:
3444 property = &GetNode().mCulled;
3454 // reuse animatable property getter as animatable properties are inputs as well
3455 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3456 property = GetSceneObjectAnimatableProperty( index );
3462 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3464 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3468 case Dali::Actor::Property::PARENT_ORIGIN_X:
3469 case Dali::Actor::Property::ANCHOR_POINT_X:
3470 case Dali::Actor::Property::SIZE_WIDTH:
3471 case Dali::Actor::Property::POSITION_X:
3472 case Dali::Actor::Property::WORLD_POSITION_X:
3473 case Dali::Actor::Property::SCALE_X:
3474 case Dali::Actor::Property::COLOR_RED:
3480 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3481 case Dali::Actor::Property::ANCHOR_POINT_Y:
3482 case Dali::Actor::Property::SIZE_HEIGHT:
3483 case Dali::Actor::Property::POSITION_Y:
3484 case Dali::Actor::Property::WORLD_POSITION_Y:
3485 case Dali::Actor::Property::SCALE_Y:
3486 case Dali::Actor::Property::COLOR_GREEN:
3492 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3493 case Dali::Actor::Property::ANCHOR_POINT_Z:
3494 case Dali::Actor::Property::SIZE_DEPTH:
3495 case Dali::Actor::Property::POSITION_Z:
3496 case Dali::Actor::Property::WORLD_POSITION_Z:
3497 case Dali::Actor::Property::SCALE_Z:
3498 case Dali::Actor::Property::COLOR_BLUE:
3504 case Dali::Actor::Property::COLOR_ALPHA:
3505 case Dali::Actor::Property::OPACITY:
3517 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3520 componentIndex = Object::GetPropertyComponentIndex( index );
3523 return componentIndex;
3526 void Actor::SetParent( Actor* parent )
3530 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3534 mScene = parent->mScene;
3536 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3539 // Instruct each actor to create a corresponding node in the scene graph
3540 ConnectToStage( parent->GetHierarchyDepth() );
3543 // Resolve the name and index for the child properties if any
3544 ResolveChildProperties();
3546 else // parent being set to NULL
3548 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3552 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3555 // Disconnect the Node & its children from the scene-graph.
3556 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3558 // Instruct each actor to discard pointers to the scene-graph
3559 DisconnectFromStage();
3566 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3569 Actor* actor = dynamic_cast< Actor* >( object );
3573 if( 0 == actionName.compare( ACTION_SHOW ) )
3575 actor->SetVisible( true );
3578 else if( 0 == actionName.compare( ACTION_HIDE ) )
3580 actor->SetVisible( false );
3588 Rect<> Actor::CalculateScreenExtents( ) const
3590 auto screenPosition = GetCurrentScreenPosition();
3591 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3592 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3593 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3594 return { position.x, position.y, size.x, size.y };
3597 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3599 bool valueSet = true;
3603 case Dali::Actor::Property::PARENT_ORIGIN:
3605 value = GetCurrentParentOrigin();
3609 case Dali::Actor::Property::PARENT_ORIGIN_X:
3611 value = GetCurrentParentOrigin().x;
3615 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3617 value = GetCurrentParentOrigin().y;
3621 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3623 value = GetCurrentParentOrigin().z;
3627 case Dali::Actor::Property::ANCHOR_POINT:
3629 value = GetCurrentAnchorPoint();
3633 case Dali::Actor::Property::ANCHOR_POINT_X:
3635 value = GetCurrentAnchorPoint().x;
3639 case Dali::Actor::Property::ANCHOR_POINT_Y:
3641 value = GetCurrentAnchorPoint().y;
3645 case Dali::Actor::Property::ANCHOR_POINT_Z:
3647 value = GetCurrentAnchorPoint().z;
3651 case Dali::Actor::Property::SIZE:
3653 value = GetTargetSize();
3657 case Dali::Actor::Property::SIZE_WIDTH:
3659 value = GetTargetSize().width;
3663 case Dali::Actor::Property::SIZE_HEIGHT:
3665 value = GetTargetSize().height;
3669 case Dali::Actor::Property::SIZE_DEPTH:
3671 value = GetTargetSize().depth;
3675 case Dali::Actor::Property::POSITION:
3677 value = GetTargetPosition();
3681 case Dali::Actor::Property::POSITION_X:
3683 value = GetTargetPosition().x;
3687 case Dali::Actor::Property::POSITION_Y:
3689 value = GetTargetPosition().y;
3693 case Dali::Actor::Property::POSITION_Z:
3695 value = GetTargetPosition().z;
3699 case Dali::Actor::Property::ORIENTATION:
3701 value = mTargetOrientation;
3705 case Dali::Actor::Property::SCALE:
3707 value = mTargetScale;
3711 case Dali::Actor::Property::SCALE_X:
3713 value = mTargetScale.x;
3717 case Dali::Actor::Property::SCALE_Y:
3719 value = mTargetScale.y;
3723 case Dali::Actor::Property::SCALE_Z:
3725 value = mTargetScale.z;
3729 case Dali::Actor::Property::VISIBLE:
3735 case Dali::Actor::Property::COLOR:
3737 value = mTargetColor;
3741 case Dali::Actor::Property::COLOR_RED:
3743 value = mTargetColor.r;
3747 case Dali::Actor::Property::COLOR_GREEN:
3749 value = mTargetColor.g;
3753 case Dali::Actor::Property::COLOR_BLUE:
3755 value = mTargetColor.b;
3759 case Dali::Actor::Property::COLOR_ALPHA:
3760 case Dali::Actor::Property::OPACITY:
3762 value = mTargetColor.a;
3766 case Dali::Actor::Property::NAME:
3772 case Dali::Actor::Property::SENSITIVE:
3774 value = IsSensitive();
3778 case Dali::Actor::Property::LEAVE_REQUIRED:
3780 value = GetLeaveRequired();
3784 case Dali::Actor::Property::INHERIT_POSITION:
3786 value = IsPositionInherited();
3790 case Dali::Actor::Property::INHERIT_ORIENTATION:
3792 value = IsOrientationInherited();
3796 case Dali::Actor::Property::INHERIT_SCALE:
3798 value = IsScaleInherited();
3802 case Dali::Actor::Property::COLOR_MODE:
3804 value = GetColorMode();
3808 case Dali::Actor::Property::DRAW_MODE:
3810 value = GetDrawMode();
3814 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3816 value = GetSizeModeFactor();
3820 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3822 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3826 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3828 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3832 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3834 value = GetSizeScalePolicy();
3838 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3840 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3844 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3846 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3850 case Dali::Actor::Property::PADDING:
3852 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3853 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3854 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3858 case Dali::Actor::Property::MINIMUM_SIZE:
3860 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3864 case Dali::Actor::Property::MAXIMUM_SIZE:
3866 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3870 case Dali::Actor::Property::CLIPPING_MODE:
3872 value = mClippingMode;
3876 case Dali::DevelActor::Property::SIBLING_ORDER:
3878 value = static_cast<int>( GetSiblingOrder() );
3882 case Dali::Actor::Property::SCREEN_POSITION:
3884 value = GetCurrentScreenPosition();
3888 case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT:
3890 value = mPositionUsesAnchorPoint;
3894 case Dali::Actor::Property::LAYOUT_DIRECTION:
3896 value = mLayoutDirection;
3900 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3902 value = IsLayoutDirectionInherited();
3906 case Dali::Actor::Property::ID:
3908 value = static_cast<int>( GetId() );
3912 case Dali::Actor::Property::HIERARCHY_DEPTH:
3914 value = GetHierarchyDepth();
3918 case Dali::Actor::Property::IS_ROOT:
3924 case Dali::Actor::Property::IS_LAYER:
3930 case Dali::Actor::Property::CONNECTED_TO_SCENE:
3936 case Dali::Actor::Property::KEYBOARD_FOCUSABLE:
3938 value = IsKeyboardFocusable();
3944 // Must be a scene-graph only property
3953 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3955 bool valueSet = true;
3959 case Dali::Actor::Property::SIZE:
3961 value = GetCurrentSize();
3965 case Dali::Actor::Property::SIZE_WIDTH:
3967 value = GetCurrentSize().width;
3971 case Dali::Actor::Property::SIZE_HEIGHT:
3973 value = GetCurrentSize().height;
3977 case Dali::Actor::Property::SIZE_DEPTH:
3979 value = GetCurrentSize().depth;
3983 case Dali::Actor::Property::POSITION:
3985 value = GetCurrentPosition();
3989 case Dali::Actor::Property::POSITION_X:
3991 value = GetCurrentPosition().x;
3995 case Dali::Actor::Property::POSITION_Y:
3997 value = GetCurrentPosition().y;
4001 case Dali::Actor::Property::POSITION_Z:
4003 value = GetCurrentPosition().z;
4007 case Dali::Actor::Property::WORLD_POSITION:
4009 value = GetCurrentWorldPosition();
4013 case Dali::Actor::Property::WORLD_POSITION_X:
4015 value = GetCurrentWorldPosition().x;
4019 case Dali::Actor::Property::WORLD_POSITION_Y:
4021 value = GetCurrentWorldPosition().y;
4025 case Dali::Actor::Property::WORLD_POSITION_Z:
4027 value = GetCurrentWorldPosition().z;
4031 case Dali::Actor::Property::ORIENTATION:
4033 value = GetCurrentOrientation();
4037 case Dali::Actor::Property::WORLD_ORIENTATION:
4039 value = GetCurrentWorldOrientation();
4043 case Dali::Actor::Property::SCALE:
4045 value = GetCurrentScale();
4049 case Dali::Actor::Property::SCALE_X:
4051 value = GetCurrentScale().x;
4055 case Dali::Actor::Property::SCALE_Y:
4057 value = GetCurrentScale().y;
4061 case Dali::Actor::Property::SCALE_Z:
4063 value = GetCurrentScale().z;
4067 case Dali::Actor::Property::WORLD_SCALE:
4069 value = GetCurrentWorldScale();
4073 case Dali::Actor::Property::COLOR:
4075 value = GetCurrentColor();
4079 case Dali::Actor::Property::COLOR_RED:
4081 value = GetCurrentColor().r;
4085 case Dali::Actor::Property::COLOR_GREEN:
4087 value = GetCurrentColor().g;
4091 case Dali::Actor::Property::COLOR_BLUE:
4093 value = GetCurrentColor().b;
4097 case Dali::Actor::Property::COLOR_ALPHA:
4098 case Dali::Actor::Property::OPACITY:
4100 value = GetCurrentColor().a;
4104 case Dali::Actor::Property::WORLD_COLOR:
4106 value = GetCurrentWorldColor();
4110 case Dali::Actor::Property::WORLD_MATRIX:
4112 value = GetCurrentWorldMatrix();
4116 case Dali::Actor::Property::VISIBLE:
4118 value = IsVisible();
4122 case Dali::Actor::Property::CULLED:
4124 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4128 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
4130 value = GetUpdateSizeHint();
4136 // Must be an event-side only property
4145 void Actor::EnsureRelayoutData()
4147 // Assign relayout data.
4148 if( !mRelayoutData )
4150 mRelayoutData = new RelayoutData();
4154 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4156 // Check if actor is dependent on parent
4157 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4159 if( ( dimension & ( 1 << i ) ) )
4161 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4162 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4172 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4174 // Check if actor is dependent on children
4175 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4177 if( ( dimension & ( 1 << i ) ) )
4179 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4180 switch( resizePolicy )
4182 case ResizePolicy::FIT_TO_CHILDREN:
4183 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4199 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4201 return Actor::RelayoutDependentOnChildren( dimension );
4204 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4206 // Check each possible dimension and see if it is dependent on the input one
4207 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4209 if( dimension & ( 1 << i ) )
4211 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4218 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4220 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4222 if( dimension & ( 1 << i ) )
4224 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4229 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4231 // If more than one dimension is requested, just return the first one found
4232 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4234 if( ( dimension & ( 1 << i ) ) )
4236 return mRelayoutData->negotiatedDimensions[ i ];
4240 return 0.0f; // Default
4243 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4245 EnsureRelayoutData();
4247 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4249 if( dimension & ( 1 << i ) )
4251 mRelayoutData->dimensionPadding[ i ] = padding;
4256 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4258 if ( mRelayoutData )
4260 // If more than one dimension is requested, just return the first one found
4261 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4263 if( ( dimension & ( 1 << i ) ) )
4265 return mRelayoutData->dimensionPadding[ i ];
4270 return GetDefaultDimensionPadding();
4273 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4275 EnsureRelayoutData();
4277 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4279 if( dimension & ( 1 << i ) )
4281 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4286 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4288 if ( mRelayoutData )
4290 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4292 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4302 float Actor::GetHeightForWidthBase( float width )
4304 float height = 0.0f;
4306 const Vector3 naturalSize = GetNaturalSize();
4307 if( naturalSize.width > 0.0f )
4309 height = naturalSize.height * width / naturalSize.width;
4311 else // we treat 0 as 1:1 aspect ratio
4319 float Actor::GetWidthForHeightBase( float height )
4323 const Vector3 naturalSize = GetNaturalSize();
4324 if( naturalSize.height > 0.0f )
4326 width = naturalSize.width * height / naturalSize.height;
4328 else // we treat 0 as 1:1 aspect ratio
4336 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4338 // Fill to parent, taking size mode factor into account
4339 switch( child.GetResizePolicy( dimension ) )
4341 case ResizePolicy::FILL_TO_PARENT:
4343 return GetLatestSize( dimension );
4346 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4348 return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4351 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4353 return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4358 return GetLatestSize( dimension );
4363 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4365 // Can be overridden in derived class
4366 return CalculateChildSizeBase( child, dimension );
4369 float Actor::GetHeightForWidth( float width )
4371 // Can be overridden in derived class
4372 return GetHeightForWidthBase( width );
4375 float Actor::GetWidthForHeight( float height )
4377 // Can be overridden in derived class
4378 return GetWidthForHeightBase( height );
4381 float Actor::GetLatestSize( Dimension::Type dimension ) const
4383 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4386 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4388 Vector2 padding = GetPadding( dimension );
4390 return GetLatestSize( dimension ) + padding.x + padding.y;
4393 float Actor::NegotiateFromParent( Dimension::Type dimension )
4395 Actor* parent = GetParent();
4398 Vector2 padding( GetPadding( dimension ) );
4399 Vector2 parentPadding( parent->GetPadding( dimension ) );
4400 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4406 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4408 float maxDimensionPoint = 0.0f;
4410 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4412 ActorPtr child = GetChildAt( i );
4414 if( !child->RelayoutDependentOnParent( dimension ) )
4416 // Calculate the min and max points that the children range across
4417 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4418 float dimensionSize = child->GetRelayoutSize( dimension );
4419 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4423 return maxDimensionPoint;
4426 float Actor::GetSize( Dimension::Type dimension ) const
4428 return GetDimensionValue( mTargetSize, dimension );
4431 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4433 return GetDimensionValue( GetNaturalSize(), dimension );
4436 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4438 switch( GetResizePolicy( dimension ) )
4440 case ResizePolicy::USE_NATURAL_SIZE:
4442 return GetNaturalSize( dimension );
4445 case ResizePolicy::FIXED:
4447 return GetDimensionValue( GetPreferredSize(), dimension );
4450 case ResizePolicy::USE_ASSIGNED_SIZE:
4452 return GetDimensionValue( maximumSize, dimension );
4455 case ResizePolicy::FILL_TO_PARENT:
4456 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4457 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4459 return NegotiateFromParent( dimension );
4462 case ResizePolicy::FIT_TO_CHILDREN:
4464 return NegotiateFromChildren( dimension );
4467 case ResizePolicy::DIMENSION_DEPENDENCY:
4469 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4472 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4474 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4477 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4479 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4491 return 0.0f; // Default
4494 float Actor::ClampDimension( float size, Dimension::Type dimension )
4496 const float minSize = GetMinimumSize( dimension );
4497 const float maxSize = GetMaximumSize( dimension );
4499 return std::max( minSize, std::min( size, maxSize ) );
4502 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4504 // Check if it needs to be negotiated
4505 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4507 // Check that we havn't gotten into an infinite loop
4508 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4509 bool recursionFound = false;
4510 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4512 if( *it == searchActor )
4514 recursionFound = true;
4519 if( !recursionFound )
4521 // Record the path that we have taken
4522 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4524 // Dimension dependency check
4525 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4527 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4529 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4531 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4535 // Parent dependency check
4536 Actor* parent = GetParent();
4537 if( parent && RelayoutDependentOnParent( dimension ) )
4539 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4542 // Children dependency check
4543 if( RelayoutDependentOnChildren( dimension ) )
4545 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4547 ActorPtr child = GetChildAt( i );
4549 // Only relayout child first if it is not dependent on this actor
4550 if( !child->RelayoutDependentOnParent( dimension ) )
4552 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4557 // For deriving classes
4558 OnCalculateRelayoutSize( dimension );
4560 // All dependencies checked, calculate the size and set negotiated flag
4561 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4563 SetNegotiatedDimension( newSize, dimension );
4564 SetLayoutNegotiated( true, dimension );
4566 // For deriving classes
4567 OnLayoutNegotiated( newSize, dimension );
4569 // This actor has been successfully processed, pop it off the recursion stack
4570 recursionStack.pop_back();
4574 // TODO: Break infinite loop
4575 SetLayoutNegotiated( true, dimension );
4580 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4582 // Negotiate all dimensions that require it
4583 ActorDimensionStack recursionStack;
4585 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4587 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4590 NegotiateDimension( dimension, allocatedSize, recursionStack );
4594 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4596 switch( mRelayoutData->sizeSetPolicy )
4598 case SizeScalePolicy::USE_SIZE_SET:
4603 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4605 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4606 const Vector3 naturalSize = GetNaturalSize();
4607 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4609 const float sizeRatio = size.width / size.height;
4610 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4612 if( naturalSizeRatio < sizeRatio )
4614 return Vector2( naturalSizeRatio * size.height, size.height );
4616 else if( naturalSizeRatio > sizeRatio )
4618 return Vector2( size.width, size.width / naturalSizeRatio );
4629 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4631 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4632 const Vector3 naturalSize = GetNaturalSize();
4633 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4635 const float sizeRatio = size.width / size.height;
4636 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4638 if( naturalSizeRatio < sizeRatio )
4640 return Vector2( size.width, size.width / naturalSizeRatio );
4642 else if( naturalSizeRatio > sizeRatio )
4644 return Vector2( naturalSizeRatio * size.height, size.height );
4663 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4665 // Do the set actor size
4666 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4668 // Adjust for size set policy
4669 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4671 // Lock the flag to stop recursive relayouts on set size
4672 mRelayoutData->insideRelayout = true;
4673 SetSize( negotiatedSize );
4674 mRelayoutData->insideRelayout = false;
4676 // Clear flags for all dimensions
4677 SetLayoutDirty( false );
4679 // Give deriving classes a chance to respond
4680 OnRelayout( negotiatedSize, container );
4682 if( !mOnRelayoutSignal.Empty() )
4684 Dali::Actor handle( this );
4685 mOnRelayoutSignal.Emit( handle );
4689 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4691 // Force a size negotiation for actors that has assigned size during relayout
4692 // This is required as otherwise the flags that force a relayout will not
4693 // necessarilly be set. This will occur if the actor has already been laid out.
4694 // The dirty flags are then cleared. Then if the actor is added back into the
4695 // relayout container afterwards, the dirty flags would still be clear...
4696 // causing a relayout to be skipped. Here we force any actors added to the
4697 // container to be relayed out.
4698 DALI_LOG_TIMER_START( NegSizeTimer1 );
4700 if( GetUseAssignedSize(Dimension::WIDTH ) )
4702 SetLayoutNegotiated( false, Dimension::WIDTH );
4704 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4706 SetLayoutNegotiated( false, Dimension::HEIGHT );
4709 // Do the negotiation
4710 NegotiateDimensions( allocatedSize );
4712 // Set the actor size
4713 SetNegotiatedSize( container );
4715 // Negotiate down to children
4716 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4718 ActorPtr child = GetChildAt( i );
4720 // Forces children that have already been laid out to be relayed out
4721 // if they have assigned size during relayout.
4722 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4724 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4725 child->SetLayoutDirty(true, Dimension::WIDTH);
4728 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4730 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4731 child->SetLayoutDirty(true, Dimension::HEIGHT);
4734 // Only relayout if required
4735 if( child->RelayoutRequired() )
4737 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4740 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4743 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4747 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4749 if( dimension & ( 1 << i ) )
4751 mRelayoutData->useAssignedSize[ i ] = use;
4757 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4759 if ( mRelayoutData )
4761 // If more than one dimension is requested, just return the first one found
4762 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4764 if( dimension & ( 1 << i ) )
4766 return mRelayoutData->useAssignedSize[ i ];
4774 void Actor::RelayoutRequest( Dimension::Type dimension )
4776 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4777 if( relayoutController )
4779 Dali::Actor self( this );
4780 relayoutController->RequestRelayout( self, dimension );
4784 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4788 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4792 void Actor::SetPreferredSize( const Vector2& size )
4794 EnsureRelayoutData();
4796 // If valid width or height, then set the resize policy to FIXED
4797 // 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,
4798 // then change to FIXED as well
4800 if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4802 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4805 if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4807 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4810 mRelayoutData->preferredSize = size;
4812 mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4817 Vector2 Actor::GetPreferredSize() const
4819 if ( mRelayoutData )
4821 return Vector2( mRelayoutData->preferredSize );
4824 return GetDefaultPreferredSize();
4827 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4829 EnsureRelayoutData();
4831 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4833 if( dimension & ( 1 << i ) )
4835 mRelayoutData->minimumSize[ i ] = size;
4842 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4844 if ( mRelayoutData )
4846 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4848 if( dimension & ( 1 << i ) )
4850 return mRelayoutData->minimumSize[ i ];
4855 return 0.0f; // Default
4858 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4860 EnsureRelayoutData();
4862 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4864 if( dimension & ( 1 << i ) )
4866 mRelayoutData->maximumSize[ i ] = size;
4873 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4875 if ( mRelayoutData )
4877 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4879 if( dimension & ( 1 << i ) )
4881 return mRelayoutData->maximumSize[ i ];
4886 return FLT_MAX; // Default
4889 Object* Actor::GetParentObject() const
4894 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4896 if( mVisible != visible )
4898 if( sendMessage == SendMessage::TRUE )
4900 // node is being used in a separate thread; queue a message to set the value & base value
4901 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4906 // Emit the signal on this actor and all its children
4907 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4911 void Actor::SetSiblingOrder( uint32_t order )
4915 ActorContainer& siblings = *(mParent->mChildren);
4916 uint32_t currentOrder = GetSiblingOrder();
4918 if( order != currentOrder )
4924 else if( order < siblings.size() -1 )
4926 if( order > currentOrder )
4928 RaiseAbove( *siblings[order] );
4932 LowerBelow( *siblings[order] );
4943 uint32_t Actor::GetSiblingOrder() const
4949 ActorContainer& siblings = *(mParent->mChildren);
4950 for( std::size_t i = 0; i < siblings.size(); ++i )
4952 if( siblings[i] == this )
4954 order = static_cast<uint32_t>( i );
4963 void Actor::RequestRebuildDepthTree()
4969 mScene->RequestRebuildDepthTree();
4978 ActorContainer& siblings = *(mParent->mChildren);
4979 if( siblings.back() != this ) // If not already at end
4981 for( std::size_t i=0; i<siblings.size(); ++i )
4983 if( siblings[i] == this )
4986 ActorPtr next = siblings[i+1];
4987 siblings[i+1] = this;
4994 Dali::Actor handle( this );
4995 mParent->mChildOrderChangedSignal.Emit( handle );
4997 RequestRebuildDepthTree();
5001 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5009 ActorContainer& siblings = *(mParent->mChildren);
5010 if( siblings.front() != this ) // If not already at beginning
5012 for( std::size_t i=1; i<siblings.size(); ++i )
5014 if( siblings[i] == this )
5016 // Swap with previous
5017 ActorPtr previous = siblings[i-1];
5018 siblings[i-1] = this;
5019 siblings[i] = previous;
5025 Dali::Actor handle( this );
5026 mParent->mChildOrderChangedSignal.Emit( handle );
5028 RequestRebuildDepthTree();
5032 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5036 void Actor::RaiseToTop()
5040 ActorContainer& siblings = *(mParent->mChildren);
5041 if( siblings.back() != this ) // If not already at end
5043 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5044 if( iter != siblings.end() )
5046 siblings.erase(iter);
5047 siblings.push_back(ActorPtr(this));
5051 Dali::Actor handle( this );
5052 mParent->mChildOrderChangedSignal.Emit( handle );
5054 RequestRebuildDepthTree();
5058 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5062 void Actor::LowerToBottom()
5066 ActorContainer& siblings = *(mParent->mChildren);
5067 if( siblings.front() != this ) // If not already at bottom,
5069 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5071 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5072 if( iter != siblings.end() )
5074 siblings.erase(iter);
5075 siblings.insert(siblings.begin(), thisPtr);
5079 Dali::Actor handle( this );
5080 mParent->mChildOrderChangedSignal.Emit( handle );
5082 RequestRebuildDepthTree();
5086 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5090 void Actor::RaiseAbove( Internal::Actor& target )
5094 ActorContainer& siblings = *(mParent->mChildren);
5095 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5097 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5099 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5100 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5101 if( thisIter < targetIter )
5103 siblings.erase(thisIter);
5104 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5105 // invalidate thisIter)
5106 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5108 siblings.insert(targetIter, thisPtr);
5111 Dali::Actor handle( this );
5112 mParent->mChildOrderChangedSignal.Emit( handle );
5114 RequestRebuildDepthTree();
5119 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5123 void Actor::LowerBelow( Internal::Actor& target )
5127 ActorContainer& siblings = *(mParent->mChildren);
5128 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5130 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5132 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5133 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5135 if( thisIter > targetIter )
5137 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5138 siblings.insert(targetIter, thisPtr);
5141 Dali::Actor handle( this );
5142 mParent->mChildOrderChangedSignal.Emit( handle );
5144 RequestRebuildDepthTree();
5149 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5153 void Actor::SetScene( Scene& scene )
5158 Scene& Actor::GetScene() const
5163 void Actor::SetInheritLayoutDirection( bool inherit )
5165 if( mInheritLayoutDirection != inherit )
5167 mInheritLayoutDirection = inherit;
5169 if( inherit && mParent )
5171 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5176 bool Actor::IsLayoutDirectionInherited() const
5178 return mInheritLayoutDirection;
5181 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5183 if( actor && ( actor->mInheritLayoutDirection || set ) )
5185 if( actor->mLayoutDirection != direction )
5187 actor->mLayoutDirection = direction;
5188 actor->EmitLayoutDirectionChangedSignal( direction );
5189 actor->RelayoutRequest();
5192 if( actor->GetChildCount() > 0 )
5194 ActorContainer& children = actor->GetChildrenInternal();
5195 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5197 InheritLayoutDirectionRecursively( *iter, direction );
5203 void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint )
5205 // node is being used in a separate thread; queue a message to set the value & base value
5206 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) );
5209 Vector2 Actor::GetUpdateSizeHint() const
5211 // node is being used in a separate thread, the value from the previous update is the same, set by user
5212 Vector3 updateSizeHint = GetNode().GetUpdateSizeHint();
5213 return Vector2( updateSizeHint.width, updateSizeHint.height );
5216 } // namespace Internal