2 * Copyright (c) 2019 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", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "reservedProperty01", STRING, true, false, false, Dali::Actor::Property::RESERVED_PROPERTY_01 ) // This property was removed, but to keep binary compatibility and TypeRegister test app, remain it here.
198 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
199 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
200 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
201 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
202 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
203 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
204 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
205 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
206 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
207 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
208 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
209 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
210 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
211 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
212 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
213 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
214 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
215 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
216 DALI_PROPERTY( "culled", BOOLEAN, false, false, true, Dali::DevelActor::Property::CULLED )
217 DALI_PROPERTY( "updateSizeHint", VECTOR2, true, false, true, Dali::DevelActor::Property::UPDATE_SIZE_HINT )
218 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
222 const char* const SIGNAL_TOUCHED = "touched";
223 const char* const SIGNAL_HOVERED = "hovered";
224 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
225 const char* const SIGNAL_ON_STAGE = "onStage";
226 const char* const SIGNAL_OFF_STAGE = "offStage";
227 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
228 const char* const SIGNAL_TOUCH = "touch";
229 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
230 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
231 const char* const SIGNAL_CHILD_ADDED = "childAdded";
232 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
236 const char* const ACTION_SHOW = "show";
237 const char* const ACTION_HIDE = "hide";
239 BaseHandle CreateActor()
241 return Dali::Actor::New();
244 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
246 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
247 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
248 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
249 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
250 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
251 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
256 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
258 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
259 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
264 const Vector3& value;
267 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
268 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
269 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
270 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
276 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
277 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
279 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
280 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
281 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
282 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
283 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
284 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
286 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
287 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
288 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
289 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
291 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
299 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
300 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
302 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
305 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
306 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
308 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
310 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
311 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
313 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
315 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
316 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
318 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
320 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
322 uint32_t sizeIgnored = 0;
323 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
325 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
332 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
334 // Values are the same so just use the same table as anchor-point
335 return GetAnchorPointConstant( value, parentOrigin );
339 * @brief Extract a given dimension from a Vector2
341 * @param[in] values The values to extract from
342 * @param[in] dimension The dimension to extract
343 * @return Return the value for the dimension
345 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
349 case Dimension::WIDTH:
353 case Dimension::HEIGHT:
355 return values.height;
366 * @brief Extract a given dimension from a Vector3
368 * @param[in] values The values to extract from
369 * @param[in] dimension The dimension to extract
370 * @return Return the value for the dimension
372 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
374 return GetDimensionValue( values.GetVectorXY(), dimension );
378 * @brief Recursively emits the visibility-changed-signal on the actor tree.
379 * @param[in] actor The actor to emit the signal on
380 * @param[in] visible The new visibility of the actor
381 * @param[in] type Whether the actor's visible property has changed or a parent's
383 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
387 actor->EmitVisibilityChangedSignal( visible, type );
389 if( actor->GetChildCount() > 0 )
391 ActorContainer& children = actor->GetChildrenInternal();
392 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
394 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
400 } // unnamed namespace
402 ActorPtr Actor::New()
404 // pass a reference to actor, actor does not own its node
405 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
407 // Second-phase construction
413 const SceneGraph::Node* Actor::CreateNode()
415 // create node. Nodes are owned by the update manager
416 SceneGraph::Node* node = SceneGraph::Node::New();
417 OwnerPointer< SceneGraph::Node > transferOwnership( node );
418 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
419 AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
424 const std::string& Actor::GetName() const
429 void Actor::SetName( const std::string& name )
433 // ATTENTION: string for debug purposes is not thread safe.
434 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
437 uint32_t Actor::GetId() const
439 return GetNode().GetId();
442 bool Actor::OnStage() const
447 Dali::Layer Actor::GetLayer()
451 // Short-circuit for Layer derived actors
454 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
457 // Find the immediate Layer parent
458 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
460 if( parent->IsLayer() )
462 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
469 void Actor::Add( Actor& child )
471 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
472 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
476 mChildren = new ActorContainer;
479 Actor* const oldParent( child.mParent );
481 // child might already be ours
482 if( this != oldParent )
484 // if we already have parent, unparent us first
487 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
489 // Old parent may need to readjust to missing child
490 if( oldParent->RelayoutDependentOnChildren() )
492 oldParent->RelayoutRequest();
496 // Guard against Add() during previous OnChildRemove callback
499 // Do this first, since user callbacks from within SetParent() may need to remove child
500 mChildren->push_back( ActorPtr( &child ) );
502 // SetParent asserts that child can be added
503 child.SetParent( this );
505 // Notification for derived classes
507 EmitChildAddedSignal( child );
509 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
511 // Only put in a relayout request if there is a suitable dependency
512 if( RelayoutDependentOnChildren() )
520 void Actor::Remove( Actor& child )
522 if( (this == &child) || (!mChildren) )
524 // no children or removing itself
530 // Find the child in mChildren, and unparent it
531 ActorIter end = mChildren->end();
532 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
534 ActorPtr actor = (*iter);
536 if( actor.Get() == &child )
538 // Keep handle for OnChildRemove notification
541 // Do this first, since user callbacks from within SetParent() may need to add the child
542 mChildren->erase( iter );
544 DALI_ASSERT_DEBUG( actor->GetParent() == this );
545 actor->SetParent( NULL );
553 // Only put in a relayout request if there is a suitable dependency
554 if( RelayoutDependentOnChildren() )
560 // Notification for derived classes
561 OnChildRemove( child );
562 EmitChildRemovedSignal( child );
565 void Actor::Unparent()
569 // Remove this actor from the parent. The remove will put a relayout request in for
570 // the parent if required
571 mParent->Remove( *this );
572 // mParent is now NULL!
576 uint32_t Actor::GetChildCount() const
578 return ( NULL != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
581 ActorPtr Actor::GetChildAt( uint32_t index ) const
583 DALI_ASSERT_ALWAYS( index < GetChildCount() );
585 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
588 ActorPtr Actor::FindChildByName( const std::string& actorName )
591 if( actorName == mName )
597 ActorIter end = mChildren->end();
598 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
600 child = (*iter)->FindChildByName( actorName );
611 ActorPtr Actor::FindChildById( const uint32_t id )
620 ActorIter end = mChildren->end();
621 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
623 child = (*iter)->FindChildById( id );
634 void Actor::SetParentOrigin( const Vector3& origin )
636 // node is being used in a separate thread; queue a message to set the value & base value
637 SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
639 // Cache for event-thread access
642 // not allocated, check if different from default
643 if( ParentOrigin::DEFAULT != origin )
645 mParentOrigin = new Vector3( origin );
650 // check if different from current costs more than just set
651 *mParentOrigin = origin;
655 void Actor::SetParentOriginX( float x )
657 const Vector3& current = GetCurrentParentOrigin();
659 SetParentOrigin( Vector3( x, current.y, current.z ) );
662 void Actor::SetParentOriginY( float y )
664 const Vector3& current = GetCurrentParentOrigin();
666 SetParentOrigin( Vector3( current.x, y, current.z ) );
669 void Actor::SetParentOriginZ( float z )
671 const Vector3& current = GetCurrentParentOrigin();
673 SetParentOrigin( Vector3( current.x, current.y, z ) );
676 const Vector3& Actor::GetCurrentParentOrigin() const
678 // Cached for event-thread access
679 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
682 void Actor::SetAnchorPoint( const Vector3& anchor )
684 // node is being used in a separate thread; queue a message to set the value & base value
685 SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
687 // Cache for event-thread access
690 // not allocated, check if different from default
691 if( AnchorPoint::DEFAULT != anchor )
693 mAnchorPoint = new Vector3( anchor );
698 // check if different from current costs more than just set
699 *mAnchorPoint = anchor;
703 void Actor::SetAnchorPointX( float x )
705 const Vector3& current = GetCurrentAnchorPoint();
707 SetAnchorPoint( Vector3( x, current.y, current.z ) );
710 void Actor::SetAnchorPointY( float y )
712 const Vector3& current = GetCurrentAnchorPoint();
714 SetAnchorPoint( Vector3( current.x, y, current.z ) );
717 void Actor::SetAnchorPointZ( float z )
719 const Vector3& current = GetCurrentAnchorPoint();
721 SetAnchorPoint( Vector3( current.x, current.y, z ) );
724 const Vector3& Actor::GetCurrentAnchorPoint() const
726 // Cached for event-thread access
727 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
730 void Actor::SetPosition( float x, float y )
732 SetPosition( Vector3( x, y, 0.0f ) );
735 void Actor::SetPosition( float x, float y, float z )
737 SetPosition( Vector3( x, y, z ) );
740 void Actor::SetPosition( const Vector3& position )
742 mTargetPosition = position;
744 // node is being used in a separate thread; queue a message to set the value & base value
745 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
748 void Actor::SetX( float x )
750 mTargetPosition.x = x;
752 // node is being used in a separate thread; queue a message to set the value & base value
753 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
756 void Actor::SetY( float y )
758 mTargetPosition.y = y;
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>::BakeY, y );
764 void Actor::SetZ( float z )
766 mTargetPosition.z = z;
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>::BakeZ, z );
772 void Actor::TranslateBy( const Vector3& distance )
774 mTargetPosition += distance;
776 // node is being used in a separate thread; queue a message to set the value & base value
777 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
780 const Vector3& Actor::GetCurrentPosition() const
782 // node is being used in a separate thread; copy the value from the previous update
783 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
786 const Vector3& Actor::GetTargetPosition() const
788 return mTargetPosition;
791 const Vector3& Actor::GetCurrentWorldPosition() const
793 // node is being used in a separate thread; copy the value from the previous update
794 return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
797 const Vector2 Actor::GetCurrentScreenPosition() const
799 if( mScene && OnStage() )
801 Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
802 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
803 worldPosition -= cameraPosition;
805 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
806 Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
807 Vector3 halfActorSize( actorSize * 0.5f );
808 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
810 return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
811 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
814 return Vector2::ZERO;
817 void Actor::SetInheritPosition( bool inherit )
819 if( mInheritPosition != inherit )
821 // non animatable so keep local copy
822 mInheritPosition = inherit;
823 SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
827 bool Actor::IsPositionInherited() const
829 return mInheritPosition;
832 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
834 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
835 normalizedAxis.Normalize();
837 Quaternion orientation( angle, normalizedAxis );
839 SetOrientation( orientation );
842 void Actor::SetOrientation( const Quaternion& orientation )
844 mTargetOrientation = orientation;
846 // node is being used in a separate thread; queue a message to set the value & base value
847 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
850 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
852 RotateBy( Quaternion(angle, axis) );
855 void Actor::RotateBy( const Quaternion& relativeRotation )
857 mTargetOrientation *= Quaternion( relativeRotation );
859 // node is being used in a separate thread; queue a message to set the value & base value
860 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
863 const Quaternion& Actor::GetCurrentOrientation() const
865 // node is being used in a separate thread; copy the value from the previous update
866 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
869 const Quaternion& Actor::GetCurrentWorldOrientation() const
871 // node is being used in a separate thread; copy the value from the previous update
872 return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
875 void Actor::SetScale( float scale )
877 SetScale( Vector3( scale, scale, scale ) );
880 void Actor::SetScale( float x, float y, float z )
882 SetScale( Vector3( x, y, z ) );
885 void Actor::SetScale( const Vector3& scale )
887 mTargetScale = scale;
889 // node is being used in a separate thread; queue a message to set the value & base value
890 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
893 void Actor::SetScaleX( float x )
897 // node is being used in a separate thread; queue a message to set the value & base value
898 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
901 void Actor::SetScaleY( float y )
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>::BakeY, y );
909 void Actor::SetScaleZ( float z )
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>::BakeZ, z );
917 void Actor::ScaleBy(const Vector3& relativeScale)
919 mTargetScale *= relativeScale;
921 // node is being used in a separate thread; queue a message to set the value & base value
922 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
925 const Vector3& Actor::GetCurrentScale() const
927 // node is being used in a separate thread; copy the value from the previous update
928 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
931 const Vector3& Actor::GetCurrentWorldScale() const
933 // node is being used in a separate thread; copy the value from the previous update
934 return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
937 void Actor::SetInheritScale( bool inherit )
939 if( mInheritScale != inherit )
941 // non animatable so keep local copy
942 mInheritScale = inherit;
943 // node is being used in a separate thread; queue a message to set the value
944 SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
948 bool Actor::IsScaleInherited() const
950 return mInheritScale;
953 Matrix Actor::GetCurrentWorldMatrix() const
955 return GetNode().GetWorldMatrix(0);
958 void Actor::SetVisible( bool visible )
960 SetVisibleInternal( visible, SendMessage::TRUE );
963 bool Actor::IsVisible() const
965 // node is being used in a separate thread; copy the value from the previous update
966 return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
969 void Actor::SetOpacity( float opacity )
971 mTargetColor.a = opacity;
973 // node is being used in a separate thread; queue a message to set the value & base value
974 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
977 float Actor::GetCurrentOpacity() const
979 // node is being used in a separate thread; copy the value from the previous update
980 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
983 ClippingMode::Type Actor::GetClippingMode() const
985 return mClippingMode;
988 uint32_t Actor::GetSortingDepth()
993 const Vector4& Actor::GetCurrentWorldColor() const
995 return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
998 void Actor::SetColor( const Vector4& color )
1000 mTargetColor = color;
1002 // node is being used in a separate thread; queue a message to set the value & base value
1003 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
1006 void Actor::SetColorRed( float red )
1008 mTargetColor.r = red;
1010 // node is being used in a separate thread; queue a message to set the value & base value
1011 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
1014 void Actor::SetColorGreen( float green )
1016 mTargetColor.g = green;
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>::BakeY, green );
1022 void Actor::SetColorBlue( float blue )
1024 mTargetColor.b = blue;
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>::BakeZ, blue );
1030 const Vector4& Actor::GetCurrentColor() const
1032 // node is being used in a separate thread; copy the value from the previous update
1033 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
1036 void Actor::SetInheritOrientation( bool inherit )
1038 if( mInheritOrientation != inherit )
1040 // non animatable so keep local copy
1041 mInheritOrientation = inherit;
1042 // node is being used in a separate thread; queue a message to set the value
1043 SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
1047 bool Actor::IsOrientationInherited() const
1049 return mInheritOrientation;
1052 void Actor::SetSizeModeFactor( const Vector3& factor )
1054 EnsureRelayoutData();
1056 mRelayoutData->sizeModeFactor = factor;
1059 const Vector3& Actor::GetSizeModeFactor() const
1061 if ( mRelayoutData )
1063 return mRelayoutData->sizeModeFactor;
1066 return GetDefaultSizeModeFactor();
1069 void Actor::SetColorMode( ColorMode colorMode )
1071 // non animatable so keep local copy
1072 mColorMode = colorMode;
1073 // node is being used in a separate thread; queue a message to set the value
1074 SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
1077 ColorMode Actor::GetColorMode() const
1079 // we have cached copy
1083 void Actor::SetSize( float width, float height )
1085 SetSize( Vector2( width, height ) );
1088 void Actor::SetSize( float width, float height, float depth )
1090 SetSize( Vector3( width, height, depth ) );
1093 void Actor::SetSize( const Vector2& size )
1095 SetSize( Vector3( size.width, size.height, 0.f ) );
1098 void Actor::SetSizeInternal( const Vector2& size )
1100 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1103 void Actor::SetSize( const Vector3& size )
1105 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1107 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1108 SetPreferredSize( size.GetVectorXY() );
1112 SetSizeInternal( size );
1116 void Actor::SetSizeInternal( const Vector3& size )
1118 // dont allow recursive loop
1119 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1120 // 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
1121 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1122 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1123 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1127 // node is being used in a separate thread; queue a message to set the value & base value
1128 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1130 // Notification for derived classes
1131 mInsideOnSizeSet = true;
1132 OnSizeSet( mTargetSize );
1133 mInsideOnSizeSet = false;
1135 // Raise a relayout request if the flag is not locked
1136 if( mRelayoutData && !mRelayoutData->insideRelayout )
1143 void Actor::SetWidth( float width )
1145 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1147 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1148 mRelayoutData->preferredSize.width = width;
1152 mTargetSize.width = width;
1154 // node is being used in a separate thread; queue a message to set the value & base value
1155 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1161 void Actor::SetHeight( float height )
1163 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1165 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1166 mRelayoutData->preferredSize.height = height;
1170 mTargetSize.height = height;
1172 // node is being used in a separate thread; queue a message to set the value & base value
1173 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1179 void Actor::SetDepth( float depth )
1181 mTargetSize.depth = depth;
1183 // node is being used in a separate thread; queue a message to set the value & base value
1184 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1187 Vector3 Actor::GetTargetSize() const
1189 Vector3 size = mTargetSize;
1191 // Should return preferred size if size is fixed as set by SetSize
1192 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1194 size.width = GetPreferredSize().width;
1196 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1198 size.height = GetPreferredSize().height;
1204 const Vector3& Actor::GetCurrentSize() const
1206 // node is being used in a separate thread; copy the value from the previous update
1207 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1210 Vector3 Actor::GetNaturalSize() const
1212 // It is up to deriving classes to return the appropriate natural size
1213 return Vector3( 0.0f, 0.0f, 0.0f );
1216 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1218 EnsureRelayoutData();
1220 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1221 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1223 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1225 if( dimension & ( 1 << i ) )
1227 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1229 mRelayoutData->useAssignedSize[ i ] = true;
1233 mRelayoutData->resizePolicies[ i ] = policy;
1234 mRelayoutData->useAssignedSize[ i ] = false;
1239 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1241 if( dimension & Dimension::WIDTH )
1243 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1246 if( dimension & Dimension::HEIGHT )
1248 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1252 // If calling SetResizePolicy, assume we want relayout enabled
1253 SetRelayoutEnabled( true );
1255 // If the resize policy is set to be FIXED, the preferred size
1256 // should be overrided by the target size. Otherwise the target
1257 // size should be overrided by the preferred size.
1259 if( dimension & Dimension::WIDTH )
1261 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1263 mRelayoutData->preferredSize.width = mTargetSize.width;
1265 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1267 mTargetSize.width = mRelayoutData->preferredSize.width;
1271 if( dimension & Dimension::HEIGHT )
1273 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1275 mRelayoutData->preferredSize.height = mTargetSize.height;
1277 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1279 mTargetSize.height = mRelayoutData->preferredSize.height;
1283 OnSetResizePolicy( policy, dimension );
1285 // Trigger relayout on this control
1289 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1291 if ( mRelayoutData )
1293 // If more than one dimension is requested, just return the first one found
1294 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1296 if( ( dimension & ( 1 << i ) ) )
1298 if( mRelayoutData->useAssignedSize[ i ] )
1300 return ResizePolicy::USE_ASSIGNED_SIZE;
1304 return mRelayoutData->resizePolicies[ i ];
1310 return ResizePolicy::DEFAULT;
1313 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1315 EnsureRelayoutData();
1317 mRelayoutData->sizeSetPolicy = policy;
1319 // Trigger relayout on this control
1323 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1325 if ( mRelayoutData )
1327 return mRelayoutData->sizeSetPolicy;
1330 return DEFAULT_SIZE_SCALE_POLICY;
1333 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1335 EnsureRelayoutData();
1337 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1339 if( dimension & ( 1 << i ) )
1341 mRelayoutData->dimensionDependencies[ i ] = dependency;
1346 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1348 if ( mRelayoutData )
1350 // If more than one dimension is requested, just return the first one found
1351 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1353 if( ( dimension & ( 1 << i ) ) )
1355 return mRelayoutData->dimensionDependencies[ i ];
1360 return Dimension::ALL_DIMENSIONS; // Default
1363 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1365 // If relayout data has not been allocated yet and the client is requesting
1366 // to disable it, do nothing
1367 if( mRelayoutData || relayoutEnabled )
1369 EnsureRelayoutData();
1371 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1373 mRelayoutData->relayoutEnabled = relayoutEnabled;
1377 bool Actor::IsRelayoutEnabled() const
1379 // Assume that if relayout data has not been allocated yet then
1380 // relayout is disabled
1381 return mRelayoutData && mRelayoutData->relayoutEnabled;
1384 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1386 EnsureRelayoutData();
1388 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1390 if( dimension & ( 1 << i ) )
1392 mRelayoutData->dimensionDirty[ i ] = dirty;
1397 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1399 if ( mRelayoutData )
1401 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1403 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1413 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1415 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1418 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1420 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1423 uint32_t Actor::AddRenderer( Renderer& renderer )
1427 mRenderers = new RendererContainer;
1430 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1431 RendererPtr rendererPtr = RendererPtr( &renderer );
1432 mRenderers->push_back( rendererPtr );
1433 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1437 uint32_t Actor::GetRendererCount() const
1439 uint32_t rendererCount(0);
1442 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1445 return rendererCount;
1448 RendererPtr Actor::GetRendererAt( uint32_t index )
1450 RendererPtr renderer;
1451 if( index < GetRendererCount() )
1453 renderer = ( *mRenderers )[ index ];
1459 void Actor::RemoveRenderer( Renderer& renderer )
1463 RendererIter end = mRenderers->end();
1464 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1466 if( (*iter).Get() == &renderer )
1468 mRenderers->erase( iter );
1469 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1476 void Actor::RemoveRenderer( uint32_t index )
1478 if( index < GetRendererCount() )
1480 RendererPtr renderer = ( *mRenderers )[ index ];
1481 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1482 mRenderers->erase( mRenderers->begin()+index );
1486 bool Actor::IsOverlay() const
1488 return ( DrawMode::OVERLAY_2D == mDrawMode );
1491 void Actor::SetDrawMode( DrawMode::Type drawMode )
1493 // this flag is not animatable so keep the value
1494 mDrawMode = drawMode;
1496 // node is being used in a separate thread; queue a message to set the value
1497 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1500 DrawMode::Type Actor::GetDrawMode() const
1505 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1507 // only valid when on-stage
1508 if( mScene && OnStage() )
1510 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1512 Vector2 converted( screenX, screenY );
1514 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1515 uint32_t taskCount = taskList.GetTaskCount();
1516 for( uint32_t i = taskCount; i > 0; --i )
1518 RenderTaskPtr task = taskList.GetTask( i - 1 );
1519 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1521 // found a task where this conversion was ok so return
1529 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1531 bool retval = false;
1532 // only valid when on-stage
1535 CameraActor* camera = renderTask.GetCameraActor();
1539 renderTask.GetViewport( viewport );
1541 // need to translate coordinates to render tasks coordinate space
1542 Vector2 converted( screenX, screenY );
1543 if( renderTask.TranslateCoordinates( converted ) )
1545 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1552 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1554 // Early-out if not on stage
1560 // Get the ModelView matrix
1562 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1564 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1565 Matrix invertedMvp( false/*don't init*/);
1566 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1567 bool success = invertedMvp.Invert();
1569 // Convert to GL coordinates
1570 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1575 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1582 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1588 if( XyPlaneIntersect( nearPos, farPos, local ) )
1590 Vector3 size = GetCurrentSize();
1591 localX = local.x + size.x * 0.5f;
1592 localY = local.y + size.y * 0.5f;
1603 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1606 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1608 Mathematical Formulation
1610 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1612 ( p - c ) dot ( p - c ) = r^2
1614 Given a ray with a point of origin 'o', and a direction vector 'd':
1616 ray(t) = o + td, t >= 0
1618 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1620 (o + td - c ) dot ( o + td - c ) = r^2
1622 To solve for t we first expand the above into a more recognisable quadratic equation form
1624 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1633 B = 2( o - c ) dot d
1634 C = ( o - c ) dot ( o - c ) - r^2
1636 which can be solved using a standard quadratic formula.
1638 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1640 Practical Simplification
1642 In a renderer, we often differentiate between world space and object space. In the object space
1643 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1644 into object space, the mathematical solution presented above can be simplified significantly.
1646 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1650 and we can find the t at which the (transformed) ray intersects the sphere by
1652 ( o + td ) dot ( o + td ) = r^2
1654 According to the reasoning above, we expand the above quadratic equation into the general form
1658 which now has coefficients:
1665 // Early-out if not on stage
1671 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1673 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1674 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1675 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1677 // Compute the radius is not needed, square radius it's enough.
1678 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1680 // Scale the sphere.
1681 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1683 const float width = size.width * scale.width;
1684 const float height = size.height * scale.height;
1686 float squareSphereRadius = 0.5f * ( width * width + height * height );
1688 float a = rayDir.Dot( rayDir ); // a
1689 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1690 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1692 return ( b2 * b2 - a * c ) >= 0.f;
1695 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1701 // Transforms the ray to the local reference system.
1702 // Calculate the inverse of Model matrix
1703 Matrix invModelMatrix( false/*don't init*/);
1705 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1706 invModelMatrix = GetNode().GetWorldMatrix(0);
1707 invModelMatrix.Invert();
1709 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1710 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1712 // Test with the actor's XY plane (Normal = 0 0 1 1).
1714 float a = -rayOriginLocal.z;
1715 float b = rayDirLocal.z;
1717 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1719 // Ray travels distance * rayDirLocal to intersect with plane.
1722 const Vector3& size = GetNode().GetSize( bufferIndex );
1724 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1725 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1727 // Test with the actor's geometry.
1728 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1735 void Actor::SetLeaveRequired( bool required )
1737 mLeaveRequired = required;
1740 bool Actor::GetLeaveRequired() const
1742 return mLeaveRequired;
1745 void Actor::SetKeyboardFocusable( bool focusable )
1747 mKeyboardFocusable = focusable;
1750 bool Actor::IsKeyboardFocusable() const
1752 return mKeyboardFocusable;
1755 bool Actor::GetTouchRequired() const
1757 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1760 bool Actor::GetHoverRequired() const
1762 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1765 bool Actor::GetWheelEventRequired() const
1767 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1770 bool Actor::IsHittable() const
1772 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1775 ActorGestureData& Actor::GetGestureData()
1777 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1778 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1779 if( NULL == mGestureData )
1781 mGestureData = new ActorGestureData;
1783 return *mGestureData;
1786 bool Actor::IsGestureRequred( DevelGesture::Type type ) const
1788 return mGestureData && mGestureData->IsGestureRequred( type );
1791 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1793 bool consumed = false;
1795 if( !mTouchSignal.Empty() )
1797 Dali::Actor handle( this );
1798 consumed = mTouchSignal.Emit( handle, touch );
1801 if( !mTouchedSignal.Empty() )
1803 Dali::Actor handle( this );
1804 consumed |= mTouchedSignal.Emit( handle, event );
1809 // Notification for derived classes
1810 consumed = OnTouchEvent( event ); // TODO
1816 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1818 bool consumed = false;
1820 if( !mHoveredSignal.Empty() )
1822 Dali::Actor handle( this );
1823 consumed = mHoveredSignal.Emit( handle, event );
1828 // Notification for derived classes
1829 consumed = OnHoverEvent( event );
1835 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1837 bool consumed = false;
1839 if( !mWheelEventSignal.Empty() )
1841 Dali::Actor handle( this );
1842 consumed = mWheelEventSignal.Emit( handle, event );
1847 // Notification for derived classes
1848 consumed = OnWheelEvent( event );
1854 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1856 if( ! mVisibilityChangedSignal.Empty() )
1858 Dali::Actor handle( this );
1859 mVisibilityChangedSignal.Emit( handle, visible, type );
1863 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1865 if( ! mLayoutDirectionChangedSignal.Empty() )
1867 Dali::Actor handle( this );
1868 mLayoutDirectionChangedSignal.Emit( handle, type );
1872 void Actor::EmitChildAddedSignal( Actor& child )
1874 if( ! mChildAddedSignal.Empty() )
1876 Dali::Actor handle( &child );
1877 mChildAddedSignal.Emit( handle );
1881 void Actor::EmitChildRemovedSignal( Actor& child )
1883 if( ! mChildRemovedSignal.Empty() )
1885 Dali::Actor handle( &child );
1886 mChildRemovedSignal.Emit( handle );
1890 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1892 return mTouchedSignal;
1895 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1897 return mTouchSignal;
1900 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1902 return mHoveredSignal;
1905 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1907 return mWheelEventSignal;
1910 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1912 return mOnStageSignal;
1915 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1917 return mOffStageSignal;
1920 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1922 return mOnRelayoutSignal;
1925 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1927 return mVisibilityChangedSignal;
1930 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1932 return mLayoutDirectionChangedSignal;
1935 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1937 return mChildAddedSignal;
1940 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1942 return mChildRemovedSignal;
1945 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1947 return mChildOrderChangedSignal;
1950 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1952 bool connected( true );
1953 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1955 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1957 actor->TouchedSignal().Connect( tracker, functor );
1959 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1961 actor->HoveredSignal().Connect( tracker, functor );
1963 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1965 actor->WheelEventSignal().Connect( tracker, functor );
1967 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1969 actor->OnStageSignal().Connect( tracker, functor );
1971 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1973 actor->OffStageSignal().Connect( tracker, functor );
1975 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1977 actor->OnRelayoutSignal().Connect( tracker, functor );
1979 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1981 actor->TouchSignal().Connect( tracker, functor );
1983 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
1985 actor->VisibilityChangedSignal().Connect( tracker, functor );
1987 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
1989 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
1991 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
1993 actor->ChildAddedSignal().Connect( tracker, functor );
1995 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
1997 actor->ChildRemovedSignal().Connect( tracker, functor );
2001 // signalName does not match any signal
2008 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2014 mParentOrigin( NULL ),
2015 mAnchorPoint( NULL ),
2016 mRelayoutData( NULL ),
2017 mGestureData( NULL ),
2021 mWheelEventSignal(),
2024 mOnRelayoutSignal(),
2025 mVisibilityChangedSignal(),
2026 mLayoutDirectionChangedSignal(),
2027 mChildAddedSignal(),
2028 mChildRemovedSignal(),
2029 mChildOrderChangedSignal(),
2030 mTargetOrientation( Quaternion::IDENTITY ),
2031 mTargetColor( Color::WHITE ),
2032 mTargetSize( Vector3::ZERO ),
2033 mTargetPosition( Vector3::ZERO ),
2034 mTargetScale( Vector3::ONE ),
2038 mIsRoot( ROOT_LAYER == derivedType ),
2039 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2040 mIsOnStage( false ),
2042 mLeaveRequired( false ),
2043 mKeyboardFocusable( false ),
2044 mDerivedRequiresTouch( false ),
2045 mDerivedRequiresHover( false ),
2046 mDerivedRequiresWheelEvent( false ),
2047 mOnStageSignalled( false ),
2048 mInsideOnSizeSet( false ),
2049 mInheritPosition( true ),
2050 mInheritOrientation( true ),
2051 mInheritScale( true ),
2052 mPositionUsesAnchorPoint( true ),
2054 mInheritLayoutDirection( true ),
2055 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2056 mDrawMode( DrawMode::NORMAL ),
2057 mColorMode( Node::DEFAULT_COLOR_MODE ),
2058 mClippingMode( ClippingMode::DISABLED )
2062 void Actor::Initialize()
2066 GetEventThreadServices().RegisterObject( this );
2071 // Remove mParent pointers from children even if we're destroying core,
2072 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2075 ActorConstIter endIter = mChildren->end();
2076 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2078 (*iter)->SetParent( NULL );
2084 // Guard to allow handle destruction after Core has been destroyed
2085 if( EventThreadServices::IsCoreRunning() )
2087 // Root layer will destroy its node in its own destructor
2090 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2092 GetEventThreadServices().UnregisterObject( this );
2096 // Cleanup optional gesture data
2097 delete mGestureData;
2099 // Cleanup optional parent origin and anchor
2100 delete mParentOrigin;
2101 delete mAnchorPoint;
2103 // Delete optional relayout data
2104 delete mRelayoutData;
2107 void Actor::ConnectToStage( uint32_t parentDepth )
2109 // This container is used instead of walking the Actor hierarchy.
2110 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2111 ActorContainer connectionList;
2115 mScene->RequestRebuildDepthTree();
2118 // This stage is atomic i.e. not interrupted by user callbacks.
2119 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2121 // Notify applications about the newly connected actors.
2122 const ActorIter endIter = connectionList.end();
2123 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2125 (*iter)->NotifyStageConnection();
2131 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2133 DALI_ASSERT_ALWAYS( !OnStage() );
2136 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2138 ConnectToSceneGraph();
2140 // Notification for internal derived classes
2141 OnStageConnectionInternal();
2143 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2144 connectionList.push_back( ActorPtr( this ) );
2146 // Recursively connect children
2149 ActorConstIter endIter = mChildren->end();
2150 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2152 (*iter)->SetScene( *mScene );
2153 (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2159 * This method is called when the Actor is connected to the Stage.
2160 * The parent must have added its Node to the scene-graph.
2161 * The child must connect its Node to the parent's Node.
2162 * This is recursive; the child calls ConnectToStage() for its children.
2164 void Actor::ConnectToSceneGraph()
2166 DALI_ASSERT_DEBUG( mParent != NULL);
2168 // Reparent Node in next Update
2169 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2171 // Request relayout on all actors that are added to the scenegraph
2174 // Notification for Object::Observers
2178 void Actor::NotifyStageConnection()
2180 // Actors can be removed (in a callback), before the on-stage stage is reported.
2181 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2182 if( OnStage() && !mOnStageSignalled )
2184 // Notification for external (CustomActor) derived classes
2185 OnStageConnectionExternal( mDepth );
2187 if( !mOnStageSignal.Empty() )
2189 Dali::Actor handle( this );
2190 mOnStageSignal.Emit( handle );
2193 // Guard against Remove during callbacks
2196 mOnStageSignalled = true; // signal required next time Actor is removed
2201 void Actor::DisconnectFromStage()
2203 // This container is used instead of walking the Actor hierachy.
2204 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2205 ActorContainer disconnectionList;
2209 mScene->RequestRebuildDepthTree();
2212 // This stage is atomic i.e. not interrupted by user callbacks
2213 RecursiveDisconnectFromStage( disconnectionList );
2215 // Notify applications about the newly disconnected actors.
2216 const ActorIter endIter = disconnectionList.end();
2217 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2219 (*iter)->NotifyStageDisconnection();
2223 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2225 // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2228 // Recursively disconnect children
2231 ActorConstIter endIter = mChildren->end();
2232 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2234 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2238 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2239 disconnectionList.push_back( ActorPtr( this ) );
2241 // Notification for internal derived classes
2242 OnStageDisconnectionInternal();
2244 DisconnectFromSceneGraph();
2248 * This method is called by an actor or its parent, before a node removal message is sent.
2249 * This is recursive; the child calls DisconnectFromStage() for its children.
2251 void Actor::DisconnectFromSceneGraph()
2253 // Notification for Object::Observers
2254 OnSceneObjectRemove();
2257 void Actor::NotifyStageDisconnection()
2259 // Actors can be added (in a callback), before the off-stage state is reported.
2260 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2261 // only do this step if there is a stage, i.e. Core is not being shut down
2262 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2264 // Notification for external (CustomeActor) derived classes
2265 OnStageDisconnectionExternal();
2267 if( !mOffStageSignal.Empty() )
2269 Dali::Actor handle( this );
2270 mOffStageSignal.Emit( handle );
2273 // Guard against Add during callbacks
2276 mOnStageSignalled = false; // signal required next time Actor is added
2281 bool Actor::IsNodeConnected() const
2283 bool connected( false );
2287 if( IsRoot() || GetNode().GetParent() )
2296 // This method initiates traversal of the actor tree using depth-first
2297 // traversal to set a depth index based on traversal order. It sends a
2298 // single message to update manager to update all the actor's nodes in
2299 // this tree with the depth index. The sceneGraphNodeDepths vector's
2300 // elements are ordered by depth, and could be used to reduce sorting
2301 // in the update thread.
2302 void Actor::RebuildDepthTree()
2304 DALI_LOG_TIMER_START(depthTimer);
2306 // Vector of scene-graph nodes and their depths to send to UpdateManager
2307 // in a single message
2308 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2310 int32_t depthIndex = 1;
2311 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2313 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2314 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2317 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2319 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2320 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2322 // Create/add to children of this node
2325 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2327 Actor* childActor = (*it).Get();
2329 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2334 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2338 case Dali::Actor::Property::PARENT_ORIGIN:
2340 Property::Type type = property.GetType();
2341 if( type == Property::VECTOR3 )
2343 SetParentOrigin( property.Get< Vector3 >() );
2345 else if ( type == Property::STRING )
2347 std::string parentOriginString;
2348 property.Get( parentOriginString );
2349 Vector3 parentOrigin;
2350 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2352 SetParentOrigin( parentOrigin );
2358 case Dali::Actor::Property::PARENT_ORIGIN_X:
2360 SetParentOriginX( property.Get< float >() );
2364 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2366 SetParentOriginY( property.Get< float >() );
2370 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2372 SetParentOriginZ( property.Get< float >() );
2376 case Dali::Actor::Property::ANCHOR_POINT:
2378 Property::Type type = property.GetType();
2379 if( type == Property::VECTOR3 )
2381 SetAnchorPoint( property.Get< Vector3 >() );
2383 else if ( type == Property::STRING )
2385 std::string anchorPointString;
2386 property.Get( anchorPointString );
2388 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2390 SetAnchorPoint( anchor );
2396 case Dali::Actor::Property::ANCHOR_POINT_X:
2398 SetAnchorPointX( property.Get< float >() );
2402 case Dali::Actor::Property::ANCHOR_POINT_Y:
2404 SetAnchorPointY( property.Get< float >() );
2408 case Dali::Actor::Property::ANCHOR_POINT_Z:
2410 SetAnchorPointZ( property.Get< float >() );
2414 case Dali::Actor::Property::SIZE:
2416 SetSize( property.Get< Vector3 >() );
2420 case Dali::Actor::Property::SIZE_WIDTH:
2422 SetWidth( property.Get< float >() );
2426 case Dali::Actor::Property::SIZE_HEIGHT:
2428 SetHeight( property.Get< float >() );
2432 case Dali::Actor::Property::SIZE_DEPTH:
2434 SetDepth( property.Get< float >() );
2438 case Dali::Actor::Property::POSITION:
2440 SetPosition( property.Get< Vector3 >() );
2444 case Dali::Actor::Property::POSITION_X:
2446 SetX( property.Get< float >() );
2450 case Dali::Actor::Property::POSITION_Y:
2452 SetY( property.Get< float >() );
2456 case Dali::Actor::Property::POSITION_Z:
2458 SetZ( property.Get< float >() );
2462 case Dali::Actor::Property::ORIENTATION:
2464 SetOrientation( property.Get< Quaternion >() );
2468 case Dali::Actor::Property::SCALE:
2470 SetScale( property.Get< Vector3 >() );
2474 case Dali::Actor::Property::SCALE_X:
2476 SetScaleX( property.Get< float >() );
2480 case Dali::Actor::Property::SCALE_Y:
2482 SetScaleY( property.Get< float >() );
2486 case Dali::Actor::Property::SCALE_Z:
2488 SetScaleZ( property.Get< float >() );
2492 case Dali::Actor::Property::VISIBLE:
2494 SetVisible( property.Get< bool >() );
2498 case Dali::Actor::Property::COLOR:
2500 Property::Type type = property.GetType();
2501 if( type == Property::VECTOR3 )
2503 Vector3 color = property.Get< Vector3 >();
2504 SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2506 else if( type == Property::VECTOR4 )
2508 SetColor( property.Get< Vector4 >() );
2513 case Dali::Actor::Property::COLOR_RED:
2515 SetColorRed( property.Get< float >() );
2519 case Dali::Actor::Property::COLOR_GREEN:
2521 SetColorGreen( property.Get< float >() );
2525 case Dali::Actor::Property::COLOR_BLUE:
2527 SetColorBlue( property.Get< float >() );
2531 case Dali::Actor::Property::COLOR_ALPHA:
2532 case Dali::DevelActor::Property::OPACITY:
2535 if( property.Get( value ) )
2537 SetOpacity( value );
2542 case Dali::Actor::Property::NAME:
2544 SetName( property.Get< std::string >() );
2548 case Dali::Actor::Property::SENSITIVE:
2550 SetSensitive( property.Get< bool >() );
2554 case Dali::Actor::Property::LEAVE_REQUIRED:
2556 SetLeaveRequired( property.Get< bool >() );
2560 case Dali::Actor::Property::INHERIT_POSITION:
2562 SetInheritPosition( property.Get< bool >() );
2566 case Dali::Actor::Property::INHERIT_ORIENTATION:
2568 SetInheritOrientation( property.Get< bool >() );
2572 case Dali::Actor::Property::INHERIT_SCALE:
2574 SetInheritScale( property.Get< bool >() );
2578 case Dali::Actor::Property::COLOR_MODE:
2580 ColorMode mode = mColorMode;
2581 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2583 SetColorMode( mode );
2588 case Dali::Actor::Property::DRAW_MODE:
2590 DrawMode::Type mode = mDrawMode;
2591 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2593 SetDrawMode( mode );
2598 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2600 SetSizeModeFactor( property.Get< Vector3 >() );
2604 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2606 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2607 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2609 SetResizePolicy( type, Dimension::WIDTH );
2614 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2616 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2617 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2619 SetResizePolicy( type, Dimension::HEIGHT );
2624 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2626 SizeScalePolicy::Type type = GetSizeScalePolicy();
2627 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2629 SetSizeScalePolicy( type );
2634 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2636 if( property.Get< bool >() )
2638 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2643 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2645 if( property.Get< bool >() )
2647 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2652 case Dali::Actor::Property::PADDING:
2654 Vector4 padding = property.Get< Vector4 >();
2655 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2656 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2660 case Dali::Actor::Property::MINIMUM_SIZE:
2662 Vector2 size = property.Get< Vector2 >();
2663 SetMinimumSize( size.x, Dimension::WIDTH );
2664 SetMinimumSize( size.y, Dimension::HEIGHT );
2668 case Dali::Actor::Property::MAXIMUM_SIZE:
2670 Vector2 size = property.Get< Vector2 >();
2671 SetMaximumSize( size.x, Dimension::WIDTH );
2672 SetMaximumSize( size.y, Dimension::HEIGHT );
2676 case Dali::DevelActor::Property::SIBLING_ORDER:
2680 if( property.Get( value ) )
2682 SetSiblingOrder( value );
2687 case Dali::Actor::Property::CLIPPING_MODE:
2689 ClippingMode::Type convertedValue = mClippingMode;
2690 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2692 mClippingMode = convertedValue;
2693 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2698 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2701 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2703 mPositionUsesAnchorPoint = value;
2704 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2709 case Dali::Actor::Property::LAYOUT_DIRECTION:
2711 Dali::LayoutDirection::Type direction = mLayoutDirection;
2712 mInheritLayoutDirection = false;
2714 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2716 InheritLayoutDirectionRecursively( this, direction, true );
2721 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2724 if( property.Get( value ) )
2726 SetInheritLayoutDirection( value );
2731 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
2733 SetUpdateSizeHint( property.Get< Vector2 >() );
2739 // this can happen in the case of a non-animatable default property so just do nothing
2745 // TODO: This method needs to be removed
2746 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2748 switch( entry.GetType() )
2750 case Property::BOOLEAN:
2752 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2753 DALI_ASSERT_DEBUG( NULL != property );
2755 // property is being used in a separate thread; queue a message to set the property
2756 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2761 case Property::INTEGER:
2763 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2764 DALI_ASSERT_DEBUG( NULL != property );
2766 // property is being used in a separate thread; queue a message to set the property
2767 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2772 case Property::FLOAT:
2774 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2775 DALI_ASSERT_DEBUG( NULL != property );
2777 // property is being used in a separate thread; queue a message to set the property
2778 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2783 case Property::VECTOR2:
2785 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2786 DALI_ASSERT_DEBUG( NULL != property );
2788 // property is being used in a separate thread; queue a message to set the property
2789 if(entry.componentIndex == 0)
2791 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2793 else if(entry.componentIndex == 1)
2795 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2799 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2805 case Property::VECTOR3:
2807 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2808 DALI_ASSERT_DEBUG( NULL != property );
2810 // property is being used in a separate thread; queue a message to set the property
2811 if(entry.componentIndex == 0)
2813 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2815 else if(entry.componentIndex == 1)
2817 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2819 else if(entry.componentIndex == 2)
2821 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2825 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2831 case Property::VECTOR4:
2833 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2834 DALI_ASSERT_DEBUG( NULL != property );
2836 // property is being used in a separate thread; queue a message to set the property
2837 if(entry.componentIndex == 0)
2839 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2841 else if(entry.componentIndex == 1)
2843 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2845 else if(entry.componentIndex == 2)
2847 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2849 else if(entry.componentIndex == 3)
2851 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2855 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2861 case Property::ROTATION:
2863 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2864 DALI_ASSERT_DEBUG( NULL != property );
2866 // property is being used in a separate thread; queue a message to set the property
2867 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2872 case Property::MATRIX:
2874 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2875 DALI_ASSERT_DEBUG( NULL != property );
2877 // property is being used in a separate thread; queue a message to set the property
2878 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2883 case Property::MATRIX3:
2885 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2886 DALI_ASSERT_DEBUG( NULL != property );
2888 // property is being used in a separate thread; queue a message to set the property
2889 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2896 // nothing to do for other types
2901 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2903 Property::Value value;
2905 if( ! GetCachedPropertyValue( index, value ) )
2907 // If property value is not stored in the event-side, then it must be a scene-graph only property
2908 GetCurrentPropertyValue( index, value );
2914 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2916 Property::Value value;
2918 if( ! GetCurrentPropertyValue( index, value ) )
2920 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2921 GetCachedPropertyValue( index, value );
2927 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2929 switch( animationType )
2932 case Animation::BETWEEN:
2936 case Dali::Actor::Property::SIZE:
2938 if( value.Get( mTargetSize ) )
2940 // Notify deriving classes
2941 OnSizeAnimation( animation, mTargetSize );
2946 case Dali::Actor::Property::SIZE_WIDTH:
2948 if( value.Get( mTargetSize.width ) )
2950 // Notify deriving classes
2951 OnSizeAnimation( animation, mTargetSize );
2956 case Dali::Actor::Property::SIZE_HEIGHT:
2958 if( value.Get( mTargetSize.height ) )
2960 // Notify deriving classes
2961 OnSizeAnimation( animation, mTargetSize );
2966 case Dali::Actor::Property::SIZE_DEPTH:
2968 if( value.Get( mTargetSize.depth ) )
2970 // Notify deriving classes
2971 OnSizeAnimation( animation, mTargetSize );
2976 case Dali::Actor::Property::POSITION:
2978 value.Get( mTargetPosition );
2982 case Dali::Actor::Property::POSITION_X:
2984 value.Get( mTargetPosition.x );
2988 case Dali::Actor::Property::POSITION_Y:
2990 value.Get( mTargetPosition.y );
2994 case Dali::Actor::Property::POSITION_Z:
2996 value.Get( mTargetPosition.z );
3000 case Dali::Actor::Property::ORIENTATION:
3002 value.Get( mTargetOrientation );
3006 case Dali::Actor::Property::SCALE:
3008 value.Get( mTargetScale );
3012 case Dali::Actor::Property::SCALE_X:
3014 value.Get( mTargetScale.x );
3018 case Dali::Actor::Property::SCALE_Y:
3020 value.Get( mTargetScale.y );
3024 case Dali::Actor::Property::SCALE_Z:
3026 value.Get( mTargetScale.z );
3030 case Dali::Actor::Property::VISIBLE:
3032 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3036 case Dali::Actor::Property::COLOR:
3038 value.Get( mTargetColor );
3042 case Dali::Actor::Property::COLOR_RED:
3044 value.Get( mTargetColor.r );
3048 case Dali::Actor::Property::COLOR_GREEN:
3050 value.Get( mTargetColor.g );
3054 case Dali::Actor::Property::COLOR_BLUE:
3056 value.Get( mTargetColor.b );
3060 case Dali::Actor::Property::COLOR_ALPHA:
3061 case Dali::DevelActor::Property::OPACITY:
3063 value.Get( mTargetColor.a );
3069 // Not an animatable property. Do nothing.
3080 case Dali::Actor::Property::SIZE:
3082 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3084 // Notify deriving classes
3085 OnSizeAnimation( animation, mTargetSize );
3090 case Dali::Actor::Property::SIZE_WIDTH:
3092 if( AdjustValue< float >( mTargetSize.width, value ) )
3094 // Notify deriving classes
3095 OnSizeAnimation( animation, mTargetSize );
3100 case Dali::Actor::Property::SIZE_HEIGHT:
3102 if( AdjustValue< float >( mTargetSize.height, value ) )
3104 // Notify deriving classes
3105 OnSizeAnimation( animation, mTargetSize );
3110 case Dali::Actor::Property::SIZE_DEPTH:
3112 if( AdjustValue< float >( mTargetSize.depth, value ) )
3114 // Notify deriving classes
3115 OnSizeAnimation( animation, mTargetSize );
3120 case Dali::Actor::Property::POSITION:
3122 AdjustValue< Vector3 >( mTargetPosition, value );
3126 case Dali::Actor::Property::POSITION_X:
3128 AdjustValue< float >( mTargetPosition.x, value );
3132 case Dali::Actor::Property::POSITION_Y:
3134 AdjustValue< float >( mTargetPosition.y, value );
3138 case Dali::Actor::Property::POSITION_Z:
3140 AdjustValue< float >( mTargetPosition.z, value );
3144 case Dali::Actor::Property::ORIENTATION:
3146 Quaternion relativeValue;
3147 if( value.Get( relativeValue ) )
3149 mTargetOrientation *= relativeValue;
3154 case Dali::Actor::Property::SCALE:
3156 AdjustValue< Vector3 >( mTargetScale, value );
3160 case Dali::Actor::Property::SCALE_X:
3162 AdjustValue< float >( mTargetScale.x, value );
3166 case Dali::Actor::Property::SCALE_Y:
3168 AdjustValue< float >( mTargetScale.y, value );
3172 case Dali::Actor::Property::SCALE_Z:
3174 AdjustValue< float >( mTargetScale.z, value );
3178 case Dali::Actor::Property::VISIBLE:
3180 bool relativeValue = false;
3181 if( value.Get( relativeValue ) )
3183 bool visible = mVisible || relativeValue;
3184 SetVisibleInternal( visible, SendMessage::FALSE );
3189 case Dali::Actor::Property::COLOR:
3191 AdjustValue< Vector4 >( mTargetColor, value );
3195 case Dali::Actor::Property::COLOR_RED:
3197 AdjustValue< float >( mTargetColor.r, value );
3201 case Dali::Actor::Property::COLOR_GREEN:
3203 AdjustValue< float >( mTargetColor.g, value );
3207 case Dali::Actor::Property::COLOR_BLUE:
3209 AdjustValue< float >( mTargetColor.b, value );
3213 case Dali::Actor::Property::COLOR_ALPHA:
3214 case Dali::DevelActor::Property::OPACITY:
3216 AdjustValue< float >( mTargetColor.a, value );
3222 // Not an animatable property. Do nothing.
3231 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3233 const PropertyBase* property( NULL );
3237 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3238 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3239 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3240 case Dali::Actor::Property::SIZE_DEPTH:
3242 property = &GetNode().mSize;
3245 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3246 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3247 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3248 case Dali::Actor::Property::POSITION_Z:
3250 property = &GetNode().mPosition;
3253 case Dali::Actor::Property::ORIENTATION:
3255 property = &GetNode().mOrientation;
3258 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3259 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3260 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3261 case Dali::Actor::Property::SCALE_Z:
3263 property = &GetNode().mScale;
3266 case Dali::Actor::Property::VISIBLE:
3268 property = &GetNode().mVisible;
3271 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3272 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3273 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3274 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3275 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3276 case Dali::DevelActor::Property::OPACITY:
3278 property = &GetNode().mColor;
3288 // not our property, ask base
3289 property = Object::GetSceneObjectAnimatableProperty( index );
3295 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3297 const PropertyInputImpl* property( NULL );
3301 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3302 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3303 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3304 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3306 property = &GetNode().mParentOrigin;
3309 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3310 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3311 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3312 case Dali::Actor::Property::ANCHOR_POINT_Z:
3314 property = &GetNode().mAnchorPoint;
3317 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3318 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3319 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3320 case Dali::Actor::Property::WORLD_POSITION_Z:
3322 property = &GetNode().mWorldPosition;
3325 case Dali::Actor::Property::WORLD_ORIENTATION:
3327 property = &GetNode().mWorldOrientation;
3330 case Dali::Actor::Property::WORLD_SCALE:
3332 property = &GetNode().mWorldScale;
3335 case Dali::Actor::Property::WORLD_COLOR:
3337 property = &GetNode().mWorldColor;
3340 case Dali::Actor::Property::WORLD_MATRIX:
3342 property = &GetNode().mWorldMatrix;
3345 case Dali::DevelActor::Property::CULLED:
3347 property = &GetNode().mCulled;
3357 // reuse animatable property getter as animatable properties are inputs as well
3358 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3359 property = GetSceneObjectAnimatableProperty( index );
3365 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3367 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3371 case Dali::Actor::Property::PARENT_ORIGIN_X:
3372 case Dali::Actor::Property::ANCHOR_POINT_X:
3373 case Dali::Actor::Property::SIZE_WIDTH:
3374 case Dali::Actor::Property::POSITION_X:
3375 case Dali::Actor::Property::WORLD_POSITION_X:
3376 case Dali::Actor::Property::SCALE_X:
3377 case Dali::Actor::Property::COLOR_RED:
3383 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3384 case Dali::Actor::Property::ANCHOR_POINT_Y:
3385 case Dali::Actor::Property::SIZE_HEIGHT:
3386 case Dali::Actor::Property::POSITION_Y:
3387 case Dali::Actor::Property::WORLD_POSITION_Y:
3388 case Dali::Actor::Property::SCALE_Y:
3389 case Dali::Actor::Property::COLOR_GREEN:
3395 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3396 case Dali::Actor::Property::ANCHOR_POINT_Z:
3397 case Dali::Actor::Property::SIZE_DEPTH:
3398 case Dali::Actor::Property::POSITION_Z:
3399 case Dali::Actor::Property::WORLD_POSITION_Z:
3400 case Dali::Actor::Property::SCALE_Z:
3401 case Dali::Actor::Property::COLOR_BLUE:
3407 case Dali::Actor::Property::COLOR_ALPHA:
3408 case Dali::DevelActor::Property::OPACITY:
3420 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3423 componentIndex = Object::GetPropertyComponentIndex( index );
3426 return componentIndex;
3429 void Actor::SetParent( Actor* parent )
3433 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3437 mScene = parent->mScene;
3439 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3442 // Instruct each actor to create a corresponding node in the scene graph
3443 ConnectToStage( parent->GetHierarchyDepth() );
3446 // Resolve the name and index for the child properties if any
3447 ResolveChildProperties();
3449 else // parent being set to NULL
3451 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3455 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3458 // Disconnect the Node & its children from the scene-graph.
3459 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3461 // Instruct each actor to discard pointers to the scene-graph
3462 DisconnectFromStage();
3469 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3472 Actor* actor = dynamic_cast< Actor* >( object );
3476 if( 0 == actionName.compare( ACTION_SHOW ) )
3478 actor->SetVisible( true );
3481 else if( 0 == actionName.compare( ACTION_HIDE ) )
3483 actor->SetVisible( false );
3491 Rect<> Actor::CalculateScreenExtents( ) const
3493 auto screenPosition = GetCurrentScreenPosition();
3494 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3495 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3496 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3497 return { position.x, position.y, size.x, size.y };
3500 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3502 bool valueSet = true;
3506 case Dali::Actor::Property::PARENT_ORIGIN:
3508 value = GetCurrentParentOrigin();
3512 case Dali::Actor::Property::PARENT_ORIGIN_X:
3514 value = GetCurrentParentOrigin().x;
3518 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3520 value = GetCurrentParentOrigin().y;
3524 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3526 value = GetCurrentParentOrigin().z;
3530 case Dali::Actor::Property::ANCHOR_POINT:
3532 value = GetCurrentAnchorPoint();
3536 case Dali::Actor::Property::ANCHOR_POINT_X:
3538 value = GetCurrentAnchorPoint().x;
3542 case Dali::Actor::Property::ANCHOR_POINT_Y:
3544 value = GetCurrentAnchorPoint().y;
3548 case Dali::Actor::Property::ANCHOR_POINT_Z:
3550 value = GetCurrentAnchorPoint().z;
3554 case Dali::Actor::Property::SIZE:
3556 value = GetTargetSize();
3560 case Dali::Actor::Property::SIZE_WIDTH:
3562 value = GetTargetSize().width;
3566 case Dali::Actor::Property::SIZE_HEIGHT:
3568 value = GetTargetSize().height;
3572 case Dali::Actor::Property::SIZE_DEPTH:
3574 value = GetTargetSize().depth;
3578 case Dali::Actor::Property::POSITION:
3580 value = GetTargetPosition();
3584 case Dali::Actor::Property::POSITION_X:
3586 value = GetTargetPosition().x;
3590 case Dali::Actor::Property::POSITION_Y:
3592 value = GetTargetPosition().y;
3596 case Dali::Actor::Property::POSITION_Z:
3598 value = GetTargetPosition().z;
3602 case Dali::Actor::Property::ORIENTATION:
3604 value = mTargetOrientation;
3608 case Dali::Actor::Property::SCALE:
3610 value = mTargetScale;
3614 case Dali::Actor::Property::SCALE_X:
3616 value = mTargetScale.x;
3620 case Dali::Actor::Property::SCALE_Y:
3622 value = mTargetScale.y;
3626 case Dali::Actor::Property::SCALE_Z:
3628 value = mTargetScale.z;
3632 case Dali::Actor::Property::VISIBLE:
3638 case Dali::Actor::Property::COLOR:
3640 value = mTargetColor;
3644 case Dali::Actor::Property::COLOR_RED:
3646 value = mTargetColor.r;
3650 case Dali::Actor::Property::COLOR_GREEN:
3652 value = mTargetColor.g;
3656 case Dali::Actor::Property::COLOR_BLUE:
3658 value = mTargetColor.b;
3662 case Dali::Actor::Property::COLOR_ALPHA:
3663 case Dali::DevelActor::Property::OPACITY:
3665 value = mTargetColor.a;
3669 case Dali::Actor::Property::NAME:
3675 case Dali::Actor::Property::SENSITIVE:
3677 value = IsSensitive();
3681 case Dali::Actor::Property::LEAVE_REQUIRED:
3683 value = GetLeaveRequired();
3687 case Dali::Actor::Property::INHERIT_POSITION:
3689 value = IsPositionInherited();
3693 case Dali::Actor::Property::INHERIT_ORIENTATION:
3695 value = IsOrientationInherited();
3699 case Dali::Actor::Property::INHERIT_SCALE:
3701 value = IsScaleInherited();
3705 case Dali::Actor::Property::COLOR_MODE:
3707 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3711 case Dali::Actor::Property::DRAW_MODE:
3713 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3717 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3719 value = GetSizeModeFactor();
3723 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3725 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3729 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3731 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3735 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3737 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3741 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3743 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3747 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3749 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3753 case Dali::Actor::Property::PADDING:
3755 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3756 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3757 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3761 case Dali::Actor::Property::MINIMUM_SIZE:
3763 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3767 case Dali::Actor::Property::MAXIMUM_SIZE:
3769 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3773 case Dali::Actor::Property::CLIPPING_MODE:
3775 value = mClippingMode;
3779 case Dali::DevelActor::Property::SIBLING_ORDER:
3781 value = static_cast<int>( GetSiblingOrder() );
3785 case Dali::DevelActor::Property::SCREEN_POSITION:
3787 value = GetCurrentScreenPosition();
3791 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3793 value = mPositionUsesAnchorPoint;
3797 case Dali::Actor::Property::LAYOUT_DIRECTION:
3799 value = mLayoutDirection;
3803 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3805 value = IsLayoutDirectionInherited();
3811 // Must be a scene-graph only property
3820 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3822 bool valueSet = true;
3826 case Dali::Actor::Property::SIZE:
3828 value = GetCurrentSize();
3832 case Dali::Actor::Property::SIZE_WIDTH:
3834 value = GetCurrentSize().width;
3838 case Dali::Actor::Property::SIZE_HEIGHT:
3840 value = GetCurrentSize().height;
3844 case Dali::Actor::Property::SIZE_DEPTH:
3846 value = GetCurrentSize().depth;
3850 case Dali::Actor::Property::POSITION:
3852 value = GetCurrentPosition();
3856 case Dali::Actor::Property::POSITION_X:
3858 value = GetCurrentPosition().x;
3862 case Dali::Actor::Property::POSITION_Y:
3864 value = GetCurrentPosition().y;
3868 case Dali::Actor::Property::POSITION_Z:
3870 value = GetCurrentPosition().z;
3874 case Dali::Actor::Property::WORLD_POSITION:
3876 value = GetCurrentWorldPosition();
3880 case Dali::Actor::Property::WORLD_POSITION_X:
3882 value = GetCurrentWorldPosition().x;
3886 case Dali::Actor::Property::WORLD_POSITION_Y:
3888 value = GetCurrentWorldPosition().y;
3892 case Dali::Actor::Property::WORLD_POSITION_Z:
3894 value = GetCurrentWorldPosition().z;
3898 case Dali::Actor::Property::ORIENTATION:
3900 value = GetCurrentOrientation();
3904 case Dali::Actor::Property::WORLD_ORIENTATION:
3906 value = GetCurrentWorldOrientation();
3910 case Dali::Actor::Property::SCALE:
3912 value = GetCurrentScale();
3916 case Dali::Actor::Property::SCALE_X:
3918 value = GetCurrentScale().x;
3922 case Dali::Actor::Property::SCALE_Y:
3924 value = GetCurrentScale().y;
3928 case Dali::Actor::Property::SCALE_Z:
3930 value = GetCurrentScale().z;
3934 case Dali::Actor::Property::WORLD_SCALE:
3936 value = GetCurrentWorldScale();
3940 case Dali::Actor::Property::COLOR:
3942 value = GetCurrentColor();
3946 case Dali::Actor::Property::COLOR_RED:
3948 value = GetCurrentColor().r;
3952 case Dali::Actor::Property::COLOR_GREEN:
3954 value = GetCurrentColor().g;
3958 case Dali::Actor::Property::COLOR_BLUE:
3960 value = GetCurrentColor().b;
3964 case Dali::Actor::Property::COLOR_ALPHA:
3965 case Dali::DevelActor::Property::OPACITY:
3967 value = GetCurrentColor().a;
3971 case Dali::Actor::Property::WORLD_COLOR:
3973 value = GetCurrentWorldColor();
3977 case Dali::Actor::Property::WORLD_MATRIX:
3979 value = GetCurrentWorldMatrix();
3983 case Dali::Actor::Property::VISIBLE:
3985 value = IsVisible();
3989 case DevelActor::Property::CULLED:
3991 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
3995 case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
3997 value = GetUpdateSizeHint();
4003 // Must be an event-side only property
4012 void Actor::EnsureRelayoutData()
4014 // Assign relayout data.
4015 if( !mRelayoutData )
4017 mRelayoutData = new RelayoutData();
4021 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4023 // Check if actor is dependent on parent
4024 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4026 if( ( dimension & ( 1 << i ) ) )
4028 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4029 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4039 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4041 // Check if actor is dependent on children
4042 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4044 if( ( dimension & ( 1 << i ) ) )
4046 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4047 switch( resizePolicy )
4049 case ResizePolicy::FIT_TO_CHILDREN:
4050 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4066 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4068 return Actor::RelayoutDependentOnChildren( dimension );
4071 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4073 // Check each possible dimension and see if it is dependent on the input one
4074 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4076 if( dimension & ( 1 << i ) )
4078 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4085 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4087 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4089 if( dimension & ( 1 << i ) )
4091 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4096 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4098 // If more than one dimension is requested, just return the first one found
4099 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4101 if( ( dimension & ( 1 << i ) ) )
4103 return mRelayoutData->negotiatedDimensions[ i ];
4107 return 0.0f; // Default
4110 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4112 EnsureRelayoutData();
4114 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4116 if( dimension & ( 1 << i ) )
4118 mRelayoutData->dimensionPadding[ i ] = padding;
4123 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4125 if ( mRelayoutData )
4127 // If more than one dimension is requested, just return the first one found
4128 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4130 if( ( dimension & ( 1 << i ) ) )
4132 return mRelayoutData->dimensionPadding[ i ];
4137 return GetDefaultDimensionPadding();
4140 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4142 EnsureRelayoutData();
4144 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4146 if( dimension & ( 1 << i ) )
4148 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4153 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4155 if ( mRelayoutData )
4157 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4159 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4169 float Actor::GetHeightForWidthBase( float width )
4171 float height = 0.0f;
4173 const Vector3 naturalSize = GetNaturalSize();
4174 if( naturalSize.width > 0.0f )
4176 height = naturalSize.height * width / naturalSize.width;
4178 else // we treat 0 as 1:1 aspect ratio
4186 float Actor::GetWidthForHeightBase( float height )
4190 const Vector3 naturalSize = GetNaturalSize();
4191 if( naturalSize.height > 0.0f )
4193 width = naturalSize.width * height / naturalSize.height;
4195 else // we treat 0 as 1:1 aspect ratio
4203 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4205 // Fill to parent, taking size mode factor into account
4206 switch( child.GetResizePolicy( dimension ) )
4208 case ResizePolicy::FILL_TO_PARENT:
4210 return GetLatestSize( dimension );
4213 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4215 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4218 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4220 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4225 return GetLatestSize( dimension );
4230 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4232 // Can be overridden in derived class
4233 return CalculateChildSizeBase( child, dimension );
4236 float Actor::GetHeightForWidth( float width )
4238 // Can be overridden in derived class
4239 return GetHeightForWidthBase( width );
4242 float Actor::GetWidthForHeight( float height )
4244 // Can be overridden in derived class
4245 return GetWidthForHeightBase( height );
4248 float Actor::GetLatestSize( Dimension::Type dimension ) const
4250 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4253 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4255 Vector2 padding = GetPadding( dimension );
4257 return GetLatestSize( dimension ) + padding.x + padding.y;
4260 float Actor::NegotiateFromParent( Dimension::Type dimension )
4262 Actor* parent = GetParent();
4265 Vector2 padding( GetPadding( dimension ) );
4266 Vector2 parentPadding( parent->GetPadding( dimension ) );
4267 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4273 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4275 float maxDimensionPoint = 0.0f;
4277 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4279 ActorPtr child = GetChildAt( i );
4281 if( !child->RelayoutDependentOnParent( dimension ) )
4283 // Calculate the min and max points that the children range across
4284 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4285 float dimensionSize = child->GetRelayoutSize( dimension );
4286 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4290 return maxDimensionPoint;
4293 float Actor::GetSize( Dimension::Type dimension ) const
4295 return GetDimensionValue( mTargetSize, dimension );
4298 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4300 return GetDimensionValue( GetNaturalSize(), dimension );
4303 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4305 switch( GetResizePolicy( dimension ) )
4307 case ResizePolicy::USE_NATURAL_SIZE:
4309 return GetNaturalSize( dimension );
4312 case ResizePolicy::FIXED:
4314 return GetDimensionValue( GetPreferredSize(), dimension );
4317 case ResizePolicy::USE_ASSIGNED_SIZE:
4319 return GetDimensionValue( maximumSize, dimension );
4322 case ResizePolicy::FILL_TO_PARENT:
4323 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4324 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4326 return NegotiateFromParent( dimension );
4329 case ResizePolicy::FIT_TO_CHILDREN:
4331 return NegotiateFromChildren( dimension );
4334 case ResizePolicy::DIMENSION_DEPENDENCY:
4336 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4339 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4341 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4344 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4346 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4358 return 0.0f; // Default
4361 float Actor::ClampDimension( float size, Dimension::Type dimension )
4363 const float minSize = GetMinimumSize( dimension );
4364 const float maxSize = GetMaximumSize( dimension );
4366 return std::max( minSize, std::min( size, maxSize ) );
4369 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4371 // Check if it needs to be negotiated
4372 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4374 // Check that we havn't gotten into an infinite loop
4375 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4376 bool recursionFound = false;
4377 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4379 if( *it == searchActor )
4381 recursionFound = true;
4386 if( !recursionFound )
4388 // Record the path that we have taken
4389 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4391 // Dimension dependency check
4392 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4394 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4396 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4398 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4402 // Parent dependency check
4403 Actor* parent = GetParent();
4404 if( parent && RelayoutDependentOnParent( dimension ) )
4406 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4409 // Children dependency check
4410 if( RelayoutDependentOnChildren( dimension ) )
4412 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4414 ActorPtr child = GetChildAt( i );
4416 // Only relayout child first if it is not dependent on this actor
4417 if( !child->RelayoutDependentOnParent( dimension ) )
4419 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4424 // For deriving classes
4425 OnCalculateRelayoutSize( dimension );
4427 // All dependencies checked, calculate the size and set negotiated flag
4428 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4430 SetNegotiatedDimension( newSize, dimension );
4431 SetLayoutNegotiated( true, dimension );
4433 // For deriving classes
4434 OnLayoutNegotiated( newSize, dimension );
4436 // This actor has been successfully processed, pop it off the recursion stack
4437 recursionStack.pop_back();
4441 // TODO: Break infinite loop
4442 SetLayoutNegotiated( true, dimension );
4447 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4449 // Negotiate all dimensions that require it
4450 ActorDimensionStack recursionStack;
4452 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4454 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4457 NegotiateDimension( dimension, allocatedSize, recursionStack );
4461 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4463 switch( mRelayoutData->sizeSetPolicy )
4465 case SizeScalePolicy::USE_SIZE_SET:
4470 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4472 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4473 const Vector3 naturalSize = GetNaturalSize();
4474 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4476 const float sizeRatio = size.width / size.height;
4477 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4479 if( naturalSizeRatio < sizeRatio )
4481 return Vector2( naturalSizeRatio * size.height, size.height );
4483 else if( naturalSizeRatio > sizeRatio )
4485 return Vector2( size.width, size.width / naturalSizeRatio );
4496 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4498 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4499 const Vector3 naturalSize = GetNaturalSize();
4500 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4502 const float sizeRatio = size.width / size.height;
4503 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4505 if( naturalSizeRatio < sizeRatio )
4507 return Vector2( size.width, size.width / naturalSizeRatio );
4509 else if( naturalSizeRatio > sizeRatio )
4511 return Vector2( naturalSizeRatio * size.height, size.height );
4530 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4532 // Do the set actor size
4533 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4535 // Adjust for size set policy
4536 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4538 // Lock the flag to stop recursive relayouts on set size
4539 mRelayoutData->insideRelayout = true;
4540 SetSize( negotiatedSize );
4541 mRelayoutData->insideRelayout = false;
4543 // Clear flags for all dimensions
4544 SetLayoutDirty( false );
4546 // Give deriving classes a chance to respond
4547 OnRelayout( negotiatedSize, container );
4549 if( !mOnRelayoutSignal.Empty() )
4551 Dali::Actor handle( this );
4552 mOnRelayoutSignal.Emit( handle );
4556 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4558 // Force a size negotiation for actors that has assigned size during relayout
4559 // This is required as otherwise the flags that force a relayout will not
4560 // necessarilly be set. This will occur if the actor has already been laid out.
4561 // The dirty flags are then cleared. Then if the actor is added back into the
4562 // relayout container afterwards, the dirty flags would still be clear...
4563 // causing a relayout to be skipped. Here we force any actors added to the
4564 // container to be relayed out.
4565 DALI_LOG_TIMER_START( NegSizeTimer1 );
4567 if( GetUseAssignedSize(Dimension::WIDTH ) )
4569 SetLayoutNegotiated( false, Dimension::WIDTH );
4571 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4573 SetLayoutNegotiated( false, Dimension::HEIGHT );
4576 // Do the negotiation
4577 NegotiateDimensions( allocatedSize );
4579 // Set the actor size
4580 SetNegotiatedSize( container );
4582 // Negotiate down to children
4583 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4585 ActorPtr child = GetChildAt( i );
4587 // Forces children that have already been laid out to be relayed out
4588 // if they have assigned size during relayout.
4589 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4591 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4592 child->SetLayoutDirty(true, Dimension::WIDTH);
4595 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4597 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4598 child->SetLayoutDirty(true, Dimension::HEIGHT);
4601 // Only relayout if required
4602 if( child->RelayoutRequired() )
4604 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4607 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4610 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4614 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4616 if( dimension & ( 1 << i ) )
4618 mRelayoutData->useAssignedSize[ i ] = use;
4624 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4626 if ( mRelayoutData )
4628 // If more than one dimension is requested, just return the first one found
4629 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4631 if( dimension & ( 1 << i ) )
4633 return mRelayoutData->useAssignedSize[ i ];
4641 void Actor::RelayoutRequest( Dimension::Type dimension )
4643 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4644 if( relayoutController )
4646 Dali::Actor self( this );
4647 relayoutController->RequestRelayout( self, dimension );
4651 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4655 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4659 void Actor::SetPreferredSize( const Vector2& size )
4661 EnsureRelayoutData();
4663 if( size.width > 0.0f )
4665 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4668 if( size.height > 0.0f )
4670 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4673 mRelayoutData->preferredSize = size;
4678 Vector2 Actor::GetPreferredSize() const
4680 if ( mRelayoutData )
4682 return Vector2( mRelayoutData->preferredSize );
4685 return GetDefaultPreferredSize();
4688 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4690 EnsureRelayoutData();
4692 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4694 if( dimension & ( 1 << i ) )
4696 mRelayoutData->minimumSize[ i ] = size;
4703 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4705 if ( mRelayoutData )
4707 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4709 if( dimension & ( 1 << i ) )
4711 return mRelayoutData->minimumSize[ i ];
4716 return 0.0f; // Default
4719 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4721 EnsureRelayoutData();
4723 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4725 if( dimension & ( 1 << i ) )
4727 mRelayoutData->maximumSize[ i ] = size;
4734 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4736 if ( mRelayoutData )
4738 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4740 if( dimension & ( 1 << i ) )
4742 return mRelayoutData->maximumSize[ i ];
4747 return FLT_MAX; // Default
4750 void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint )
4752 // node is being used in a separate thread; queue a message to set the value & base value
4753 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) );
4756 Vector2 Actor::GetUpdateSizeHint() const
4758 // node is being used in a separate thread; copy the value from the previous update
4759 Vector3 updateSizeHint = Vector3::ZERO;
4760 GetNode().GetUpdateSizeHint( GetEventThreadServices().GetEventBufferIndex(), updateSizeHint );
4761 return Vector2( updateSizeHint.width, updateSizeHint.height );
4764 Object* Actor::GetParentObject() const
4769 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4771 if( mVisible != visible )
4773 if( sendMessage == SendMessage::TRUE )
4775 // node is being used in a separate thread; queue a message to set the value & base value
4776 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4781 // Emit the signal on this actor and all its children
4782 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4786 void Actor::SetSiblingOrder( uint32_t order )
4790 ActorContainer& siblings = *(mParent->mChildren);
4791 uint32_t currentOrder = GetSiblingOrder();
4793 if( order != currentOrder )
4799 else if( order < siblings.size() -1 )
4801 if( order > currentOrder )
4803 RaiseAbove( *siblings[order] );
4807 LowerBelow( *siblings[order] );
4818 uint32_t Actor::GetSiblingOrder() const
4824 ActorContainer& siblings = *(mParent->mChildren);
4825 for( std::size_t i = 0; i < siblings.size(); ++i )
4827 if( siblings[i] == this )
4829 order = static_cast<uint32_t>( i );
4838 void Actor::RequestRebuildDepthTree()
4844 mScene->RequestRebuildDepthTree();
4853 ActorContainer& siblings = *(mParent->mChildren);
4854 if( siblings.back() != this ) // If not already at end
4856 for( std::size_t i=0; i<siblings.size(); ++i )
4858 if( siblings[i] == this )
4861 ActorPtr next = siblings[i+1];
4862 siblings[i+1] = this;
4869 Dali::Actor handle( this );
4870 mParent->mChildOrderChangedSignal.Emit( handle );
4872 RequestRebuildDepthTree();
4876 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4884 ActorContainer& siblings = *(mParent->mChildren);
4885 if( siblings.front() != this ) // If not already at beginning
4887 for( std::size_t i=1; i<siblings.size(); ++i )
4889 if( siblings[i] == this )
4891 // Swap with previous
4892 ActorPtr previous = siblings[i-1];
4893 siblings[i-1] = this;
4894 siblings[i] = previous;
4900 Dali::Actor handle( this );
4901 mParent->mChildOrderChangedSignal.Emit( handle );
4903 RequestRebuildDepthTree();
4907 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4911 void Actor::RaiseToTop()
4915 ActorContainer& siblings = *(mParent->mChildren);
4916 if( siblings.back() != this ) // If not already at end
4918 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4919 if( iter != siblings.end() )
4921 siblings.erase(iter);
4922 siblings.push_back(ActorPtr(this));
4926 Dali::Actor handle( this );
4927 mParent->mChildOrderChangedSignal.Emit( handle );
4929 RequestRebuildDepthTree();
4933 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4937 void Actor::LowerToBottom()
4941 ActorContainer& siblings = *(mParent->mChildren);
4942 if( siblings.front() != this ) // If not already at bottom,
4944 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4946 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4947 if( iter != siblings.end() )
4949 siblings.erase(iter);
4950 siblings.insert(siblings.begin(), thisPtr);
4954 Dali::Actor handle( this );
4955 mParent->mChildOrderChangedSignal.Emit( handle );
4957 RequestRebuildDepthTree();
4961 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4965 void Actor::RaiseAbove( Internal::Actor& target )
4969 ActorContainer& siblings = *(mParent->mChildren);
4970 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
4972 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4974 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
4975 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
4976 if( thisIter < targetIter )
4978 siblings.erase(thisIter);
4979 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
4980 // invalidate thisIter)
4981 targetIter = std::find( siblings.begin(), siblings.end(), &target );
4983 siblings.insert(targetIter, thisPtr);
4986 Dali::Actor handle( this );
4987 mParent->mChildOrderChangedSignal.Emit( handle );
4989 RequestRebuildDepthTree();
4994 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4998 void Actor::LowerBelow( Internal::Actor& target )
5002 ActorContainer& siblings = *(mParent->mChildren);
5003 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5005 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5007 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5008 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5010 if( thisIter > targetIter )
5012 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5013 siblings.insert(targetIter, thisPtr);
5016 Dali::Actor handle( this );
5017 mParent->mChildOrderChangedSignal.Emit( handle );
5019 RequestRebuildDepthTree();
5024 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5028 void Actor::SetScene( Scene& scene )
5033 Scene& Actor::GetScene() const
5038 void Actor::SetInheritLayoutDirection( bool inherit )
5040 if( mInheritLayoutDirection != inherit )
5042 mInheritLayoutDirection = inherit;
5044 if( inherit && mParent )
5046 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5051 bool Actor::IsLayoutDirectionInherited() const
5053 return mInheritLayoutDirection;
5056 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5058 if( actor && ( actor->mInheritLayoutDirection || set ) )
5060 if( actor->mLayoutDirection != direction )
5062 actor->mLayoutDirection = direction;
5063 actor->EmitLayoutDirectionChangedSignal( direction );
5064 actor->RelayoutRequest();
5067 if( actor->GetChildCount() > 0 )
5069 ActorContainer& children = actor->GetChildrenInternal();
5070 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5072 InheritLayoutDirectionRecursively( *iter, direction );
5078 } // namespace Internal