2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/common/scene-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/animation/constraint-impl.h>
48 #include <dali/internal/event/common/projection.h>
49 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
50 #include <dali/internal/update/common/animatable-property.h>
51 #include <dali/internal/update/nodes/node-messages.h>
52 #include <dali/internal/update/nodes/node-declarations.h>
53 #include <dali/internal/update/animation/scene-graph-constraint.h>
54 #include <dali/internal/event/events/actor-gesture-data.h>
55 #include <dali/internal/common/message.h>
56 #include <dali/integration-api/debug.h>
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::PropertyBase;
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
64 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
75 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
76 inline const Vector3& GetDefaultSizeModeFactor()
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultPreferredSize()
87 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
88 inline const Vector2& GetDefaultDimensionPadding()
93 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
95 } // unnamed namespace
98 * Struct to collect relayout variables
100 struct Actor::RelayoutData
103 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
105 // Set size negotiation defaults
106 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
108 resizePolicies[ i ] = ResizePolicy::DEFAULT;
109 useAssignedSize[ i ] = false;
110 negotiatedDimensions[ i ] = 0.0f;
111 dimensionNegotiated[ i ] = false;
112 dimensionDirty[ i ] = false;
113 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
114 dimensionPadding[ i ] = GetDefaultDimensionPadding();
115 minimumSize[ i ] = 0.0f;
116 maximumSize[ i ] = FLT_MAX;
120 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
121 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
123 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
125 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
127 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
129 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
130 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
132 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
133 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
135 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
137 Vector2 preferredSize; ///< The preferred size of the actor
139 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
141 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
142 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
145 namespace // unnamed namespace
151 * We want to discourage the use of property strings (minimize string comparisons),
152 * particularly for the default properties.
153 * Name Type writable animatable constraint-input enum for index-checking
155 DALI_PROPERTY_TABLE_BEGIN
156 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
157 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
158 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
159 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
160 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
161 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
162 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
163 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
164 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
165 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
166 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
167 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
168 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
169 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
170 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
171 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
172 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
173 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
174 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
175 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
176 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
177 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
178 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
179 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
180 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
181 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
182 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
183 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
184 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
185 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
186 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
187 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
188 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
189 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
190 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
191 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
192 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
193 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
194 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
195 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
196 DALI_PROPERTY( "colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "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", INTEGER, 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", INTEGER, 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_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
221 const char* const SIGNAL_TOUCHED = "touched";
222 const char* const SIGNAL_HOVERED = "hovered";
223 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
224 const char* const SIGNAL_ON_STAGE = "onStage";
225 const char* const SIGNAL_OFF_STAGE = "offStage";
226 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
227 const char* const SIGNAL_TOUCH = "touch";
228 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
229 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
230 const char* const SIGNAL_CHILD_ADDED = "childAdded";
231 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
235 const char* const ACTION_SHOW = "show";
236 const char* const ACTION_HIDE = "hide";
238 BaseHandle CreateActor()
240 return Dali::Actor::New();
243 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
245 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
247 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
248 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
249 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
250 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
251 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
257 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
258 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
263 const Vector3& value;
266 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
267 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
268 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
269 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
270 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
276 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
278 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
279 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
280 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
281 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
282 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
283 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
285 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
287 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
288 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
290 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
299 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
301 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
305 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
307 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
310 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
312 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
315 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
317 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
319 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
321 uint32_t sizeIgnored = 0;
322 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
324 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
331 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
333 // Values are the same so just use the same table as anchor-point
334 return GetAnchorPointConstant( value, parentOrigin );
338 * @brief Extract a given dimension from a Vector2
340 * @param[in] values The values to extract from
341 * @param[in] dimension The dimension to extract
342 * @return Return the value for the dimension
344 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
348 case Dimension::WIDTH:
352 case Dimension::HEIGHT:
354 return values.height;
365 * @brief Extract a given dimension from a Vector3
367 * @param[in] values The values to extract from
368 * @param[in] dimension The dimension to extract
369 * @return Return the value for the dimension
371 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
373 return GetDimensionValue( values.GetVectorXY(), dimension );
377 * @brief Recursively emits the visibility-changed-signal on the actor tree.
378 * @param[in] actor The actor to emit the signal on
379 * @param[in] visible The new visibility of the actor
380 * @param[in] type Whether the actor's visible property has changed or a parent's
382 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
386 actor->EmitVisibilityChangedSignal( visible, type );
388 if( actor->GetChildCount() > 0 )
390 ActorContainer& children = actor->GetChildrenInternal();
391 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
393 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
399 } // unnamed namespace
401 ActorPtr Actor::New()
403 // pass a reference to actor, actor does not own its node
404 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
406 // Second-phase construction
412 const SceneGraph::Node* Actor::CreateNode()
414 // create node. Nodes are owned by the update manager
415 SceneGraph::Node* node = SceneGraph::Node::New();
416 OwnerPointer< SceneGraph::Node > transferOwnership( node );
417 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
419 DALI_ASSERT_ALWAYS( tls && "ThreadLocalStorage is null" );
421 AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
426 const std::string& Actor::GetName() const
431 void Actor::SetName( const std::string& name )
435 // ATTENTION: string for debug purposes is not thread safe.
436 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
439 uint32_t Actor::GetId() const
441 return GetNode().GetId();
444 bool Actor::OnStage() const
449 Dali::Layer Actor::GetLayer()
453 // Short-circuit for Layer derived actors
456 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
459 // Find the immediate Layer parent
460 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
462 if( parent->IsLayer() )
464 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
471 void Actor::Add( Actor& child )
473 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
474 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
478 mChildren = new ActorContainer;
481 Actor* const oldParent( child.mParent );
483 // child might already be ours
484 if( this != oldParent )
486 // if we already have parent, unparent us first
489 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
491 // Old parent may need to readjust to missing child
492 if( oldParent->RelayoutDependentOnChildren() )
494 oldParent->RelayoutRequest();
498 // Guard against Add() during previous OnChildRemove callback
501 // Do this first, since user callbacks from within SetParent() may need to remove child
502 mChildren->push_back( ActorPtr( &child ) );
504 // SetParent asserts that child can be added
505 child.SetParent( this );
507 // Notification for derived classes
509 EmitChildAddedSignal( child );
511 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
513 // Only put in a relayout request if there is a suitable dependency
514 if( RelayoutDependentOnChildren() )
522 void Actor::Remove( Actor& child )
524 if( (this == &child) || (!mChildren) )
526 // no children or removing itself
532 // Find the child in mChildren, and unparent it
533 ActorIter end = mChildren->end();
534 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
536 ActorPtr actor = (*iter);
538 if( actor.Get() == &child )
540 // Keep handle for OnChildRemove notification
543 // Do this first, since user callbacks from within SetParent() may need to add the child
544 mChildren->erase( iter );
546 DALI_ASSERT_DEBUG( actor->GetParent() == this );
547 actor->SetParent( NULL );
555 // Only put in a relayout request if there is a suitable dependency
556 if( RelayoutDependentOnChildren() )
562 // Notification for derived classes
563 OnChildRemove( child );
564 EmitChildRemovedSignal( child );
567 void Actor::Unparent()
571 // Remove this actor from the parent. The remove will put a relayout request in for
572 // the parent if required
573 mParent->Remove( *this );
574 // mParent is now NULL!
578 uint32_t Actor::GetChildCount() const
580 return ( NULL != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
583 ActorPtr Actor::GetChildAt( uint32_t index ) const
585 DALI_ASSERT_ALWAYS( index < GetChildCount() );
587 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
590 ActorPtr Actor::FindChildByName( const std::string& actorName )
593 if( actorName == mName )
599 ActorIter end = mChildren->end();
600 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
602 child = (*iter)->FindChildByName( actorName );
613 ActorPtr Actor::FindChildById( const uint32_t id )
622 ActorIter end = mChildren->end();
623 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
625 child = (*iter)->FindChildById( id );
636 void Actor::SetParentOrigin( const Vector3& origin )
638 // node is being used in a separate thread; queue a message to set the value & base value
639 SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
641 // Cache for event-thread access
644 // not allocated, check if different from default
645 if( ParentOrigin::DEFAULT != origin )
647 mParentOrigin = new Vector3( origin );
652 // check if different from current costs more than just set
653 *mParentOrigin = origin;
657 void Actor::SetParentOriginX( float x )
659 const Vector3& current = GetCurrentParentOrigin();
661 SetParentOrigin( Vector3( x, current.y, current.z ) );
664 void Actor::SetParentOriginY( float y )
666 const Vector3& current = GetCurrentParentOrigin();
668 SetParentOrigin( Vector3( current.x, y, current.z ) );
671 void Actor::SetParentOriginZ( float z )
673 const Vector3& current = GetCurrentParentOrigin();
675 SetParentOrigin( Vector3( current.x, current.y, z ) );
678 const Vector3& Actor::GetCurrentParentOrigin() const
680 // Cached for event-thread access
681 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
684 void Actor::SetAnchorPoint( const Vector3& anchor )
686 // node is being used in a separate thread; queue a message to set the value & base value
687 SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
689 // Cache for event-thread access
692 // not allocated, check if different from default
693 if( AnchorPoint::DEFAULT != anchor )
695 mAnchorPoint = new Vector3( anchor );
700 // check if different from current costs more than just set
701 *mAnchorPoint = anchor;
705 void Actor::SetAnchorPointX( float x )
707 const Vector3& current = GetCurrentAnchorPoint();
709 SetAnchorPoint( Vector3( x, current.y, current.z ) );
712 void Actor::SetAnchorPointY( float y )
714 const Vector3& current = GetCurrentAnchorPoint();
716 SetAnchorPoint( Vector3( current.x, y, current.z ) );
719 void Actor::SetAnchorPointZ( float z )
721 const Vector3& current = GetCurrentAnchorPoint();
723 SetAnchorPoint( Vector3( current.x, current.y, z ) );
726 const Vector3& Actor::GetCurrentAnchorPoint() const
728 // Cached for event-thread access
729 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
732 void Actor::SetPosition( float x, float y )
734 SetPosition( Vector3( x, y, 0.0f ) );
737 void Actor::SetPosition( float x, float y, float z )
739 SetPosition( Vector3( x, y, z ) );
742 void Actor::SetPosition( const Vector3& position )
744 mTargetPosition = position;
746 // node is being used in a separate thread; queue a message to set the value & base value
747 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
750 void Actor::SetX( float x )
752 mTargetPosition.x = x;
754 // node is being used in a separate thread; queue a message to set the value & base value
755 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
758 void Actor::SetY( float y )
760 mTargetPosition.y = y;
762 // node is being used in a separate thread; queue a message to set the value & base value
763 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
766 void Actor::SetZ( float z )
768 mTargetPosition.z = z;
770 // node is being used in a separate thread; queue a message to set the value & base value
771 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
774 void Actor::TranslateBy( const Vector3& distance )
776 mTargetPosition += distance;
778 // node is being used in a separate thread; queue a message to set the value & base value
779 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
782 const Vector3& Actor::GetCurrentPosition() const
784 // node is being used in a separate thread; copy the value from the previous update
785 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
788 const Vector3& Actor::GetTargetPosition() const
790 return mTargetPosition;
793 const Vector3& Actor::GetCurrentWorldPosition() const
795 // node is being used in a separate thread; copy the value from the previous update
796 return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
799 const Vector2 Actor::GetCurrentScreenPosition() const
801 if( mScene && OnStage() )
803 Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
804 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
805 worldPosition -= cameraPosition;
807 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
808 Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
809 Vector3 halfActorSize( actorSize * 0.5f );
810 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
812 return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
813 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
816 return Vector2::ZERO;
819 void Actor::SetInheritPosition( bool inherit )
821 if( mInheritPosition != inherit )
823 // non animatable so keep local copy
824 mInheritPosition = inherit;
825 SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
829 bool Actor::IsPositionInherited() const
831 return mInheritPosition;
834 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
836 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
837 normalizedAxis.Normalize();
839 Quaternion orientation( angle, normalizedAxis );
841 SetOrientation( orientation );
844 void Actor::SetOrientation( const Quaternion& orientation )
846 mTargetOrientation = orientation;
848 // node is being used in a separate thread; queue a message to set the value & base value
849 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
852 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
854 RotateBy( Quaternion(angle, axis) );
857 void Actor::RotateBy( const Quaternion& relativeRotation )
859 mTargetOrientation *= Quaternion( relativeRotation );
861 // node is being used in a separate thread; queue a message to set the value & base value
862 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
865 const Quaternion& Actor::GetCurrentOrientation() const
867 // node is being used in a separate thread; copy the value from the previous update
868 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
871 const Quaternion& Actor::GetCurrentWorldOrientation() const
873 // node is being used in a separate thread; copy the value from the previous update
874 return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
877 void Actor::SetScale( float scale )
879 SetScale( Vector3( scale, scale, scale ) );
882 void Actor::SetScale( float x, float y, float z )
884 SetScale( Vector3( x, y, z ) );
887 void Actor::SetScale( const Vector3& scale )
889 mTargetScale = scale;
891 // node is being used in a separate thread; queue a message to set the value & base value
892 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
895 void Actor::SetScaleX( float x )
899 // node is being used in a separate thread; queue a message to set the value & base value
900 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
903 void Actor::SetScaleY( float y )
907 // node is being used in a separate thread; queue a message to set the value & base value
908 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
911 void Actor::SetScaleZ( float z )
915 // node is being used in a separate thread; queue a message to set the value & base value
916 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
919 void Actor::ScaleBy(const Vector3& relativeScale)
921 mTargetScale *= relativeScale;
923 // node is being used in a separate thread; queue a message to set the value & base value
924 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
927 const Vector3& Actor::GetCurrentScale() const
929 // node is being used in a separate thread; copy the value from the previous update
930 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
933 const Vector3& Actor::GetCurrentWorldScale() const
935 // node is being used in a separate thread; copy the value from the previous update
936 return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
939 void Actor::SetInheritScale( bool inherit )
941 if( mInheritScale != inherit )
943 // non animatable so keep local copy
944 mInheritScale = inherit;
945 // node is being used in a separate thread; queue a message to set the value
946 SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
950 bool Actor::IsScaleInherited() const
952 return mInheritScale;
955 Matrix Actor::GetCurrentWorldMatrix() const
957 return GetNode().GetWorldMatrix(0);
960 void Actor::SetVisible( bool visible )
962 SetVisibleInternal( visible, SendMessage::TRUE );
965 bool Actor::IsVisible() const
967 // node is being used in a separate thread; copy the value from the previous update
968 return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
971 void Actor::SetOpacity( float opacity )
973 mTargetColor.a = opacity;
975 // node is being used in a separate thread; queue a message to set the value & base value
976 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
979 float Actor::GetCurrentOpacity() const
981 // node is being used in a separate thread; copy the value from the previous update
982 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
985 ClippingMode::Type Actor::GetClippingMode() const
987 return mClippingMode;
990 uint32_t Actor::GetSortingDepth()
995 const Vector4& Actor::GetCurrentWorldColor() const
997 return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1000 void Actor::SetColor( const Vector4& color )
1002 mTargetColor = color;
1004 // node is being used in a separate thread; queue a message to set the value & base value
1005 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
1008 void Actor::SetColorRed( float red )
1010 mTargetColor.r = red;
1012 // node is being used in a separate thread; queue a message to set the value & base value
1013 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
1016 void Actor::SetColorGreen( float green )
1018 mTargetColor.g = green;
1020 // node is being used in a separate thread; queue a message to set the value & base value
1021 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green );
1024 void Actor::SetColorBlue( float blue )
1026 mTargetColor.b = blue;
1028 // node is being used in a separate thread; queue a message to set the value & base value
1029 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1032 const Vector4& Actor::GetCurrentColor() const
1034 // node is being used in a separate thread; copy the value from the previous update
1035 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
1038 void Actor::SetInheritOrientation( bool inherit )
1040 if( mInheritOrientation != inherit )
1042 // non animatable so keep local copy
1043 mInheritOrientation = inherit;
1044 // node is being used in a separate thread; queue a message to set the value
1045 SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
1049 bool Actor::IsOrientationInherited() const
1051 return mInheritOrientation;
1054 void Actor::SetSizeModeFactor( const Vector3& factor )
1056 EnsureRelayoutData();
1058 mRelayoutData->sizeModeFactor = factor;
1061 const Vector3& Actor::GetSizeModeFactor() const
1063 if ( mRelayoutData )
1065 return mRelayoutData->sizeModeFactor;
1068 return GetDefaultSizeModeFactor();
1071 void Actor::SetColorMode( ColorMode colorMode )
1073 // non animatable so keep local copy
1074 mColorMode = colorMode;
1075 // node is being used in a separate thread; queue a message to set the value
1076 SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
1079 ColorMode Actor::GetColorMode() const
1081 // we have cached copy
1085 void Actor::SetSize( float width, float height )
1087 SetSize( Vector2( width, height ) );
1090 void Actor::SetSize( float width, float height, float depth )
1092 SetSize( Vector3( width, height, depth ) );
1095 void Actor::SetSize( const Vector2& size )
1097 SetSize( Vector3( size.width, size.height, 0.f ) );
1100 void Actor::SetSizeInternal( const Vector2& size )
1102 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1105 void Actor::SetSize( const Vector3& size )
1107 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1109 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1110 SetPreferredSize( size.GetVectorXY() );
1114 SetSizeInternal( size );
1118 void Actor::SetSizeInternal( const Vector3& size )
1120 // dont allow recursive loop
1121 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1122 // 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
1123 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1124 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1125 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1129 // node is being used in a separate thread; queue a message to set the value & base value
1130 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1132 // Notification for derived classes
1133 mInsideOnSizeSet = true;
1134 OnSizeSet( mTargetSize );
1135 mInsideOnSizeSet = false;
1137 // Raise a relayout request if the flag is not locked
1138 if( mRelayoutData && !mRelayoutData->insideRelayout )
1145 void Actor::SetWidth( float width )
1147 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1149 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1150 mRelayoutData->preferredSize.width = width;
1154 mTargetSize.width = width;
1156 // node is being used in a separate thread; queue a message to set the value & base value
1157 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1160 mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
1165 void Actor::SetHeight( float height )
1167 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1169 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1170 mRelayoutData->preferredSize.height = height;
1174 mTargetSize.height = height;
1176 // node is being used in a separate thread; queue a message to set the value & base value
1177 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1180 mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
1185 void Actor::SetDepth( float depth )
1187 mTargetSize.depth = depth;
1189 mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
1191 // node is being used in a separate thread; queue a message to set the value & base value
1192 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1195 Vector3 Actor::GetTargetSize() const
1197 Vector3 size = mTargetSize;
1199 if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH )
1201 // Should return animated size if size is animated
1202 size.width = mAnimatedSize.width;
1206 // Should return preferred size if size is fixed as set by SetSize
1207 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1209 size.width = GetPreferredSize().width;
1213 if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT )
1215 size.height = mAnimatedSize.height;
1219 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1221 size.height = GetPreferredSize().height;
1225 if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH )
1227 size.depth = mAnimatedSize.depth;
1233 const Vector3& Actor::GetCurrentSize() const
1235 // node is being used in a separate thread; copy the value from the previous update
1236 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1239 Vector3 Actor::GetNaturalSize() const
1241 // It is up to deriving classes to return the appropriate natural size
1242 return Vector3( 0.0f, 0.0f, 0.0f );
1245 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1247 EnsureRelayoutData();
1249 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1250 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1252 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1254 if( dimension & ( 1 << i ) )
1256 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1258 mRelayoutData->useAssignedSize[ i ] = true;
1262 mRelayoutData->resizePolicies[ i ] = policy;
1263 mRelayoutData->useAssignedSize[ i ] = false;
1268 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1270 if( dimension & Dimension::WIDTH )
1272 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1275 if( dimension & Dimension::HEIGHT )
1277 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1281 // If calling SetResizePolicy, assume we want relayout enabled
1282 SetRelayoutEnabled( true );
1284 // If the resize policy is set to be FIXED, the preferred size
1285 // should be overrided by the target size. Otherwise the target
1286 // size should be overrided by the preferred size.
1288 if( dimension & Dimension::WIDTH )
1290 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1292 mRelayoutData->preferredSize.width = mTargetSize.width;
1294 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1296 mTargetSize.width = mRelayoutData->preferredSize.width;
1300 if( dimension & Dimension::HEIGHT )
1302 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1304 mRelayoutData->preferredSize.height = mTargetSize.height;
1306 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1308 mTargetSize.height = mRelayoutData->preferredSize.height;
1312 OnSetResizePolicy( policy, dimension );
1314 // Trigger relayout on this control
1318 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1320 if ( mRelayoutData )
1322 // If more than one dimension is requested, just return the first one found
1323 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1325 if( ( dimension & ( 1 << i ) ) )
1327 if( mRelayoutData->useAssignedSize[ i ] )
1329 return ResizePolicy::USE_ASSIGNED_SIZE;
1333 return mRelayoutData->resizePolicies[ i ];
1339 return ResizePolicy::DEFAULT;
1342 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1344 EnsureRelayoutData();
1346 mRelayoutData->sizeSetPolicy = policy;
1348 // Trigger relayout on this control
1352 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1354 if ( mRelayoutData )
1356 return mRelayoutData->sizeSetPolicy;
1359 return DEFAULT_SIZE_SCALE_POLICY;
1362 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1364 EnsureRelayoutData();
1366 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1368 if( dimension & ( 1 << i ) )
1370 mRelayoutData->dimensionDependencies[ i ] = dependency;
1375 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1377 if ( mRelayoutData )
1379 // If more than one dimension is requested, just return the first one found
1380 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1382 if( ( dimension & ( 1 << i ) ) )
1384 return mRelayoutData->dimensionDependencies[ i ];
1389 return Dimension::ALL_DIMENSIONS; // Default
1392 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1394 // If relayout data has not been allocated yet and the client is requesting
1395 // to disable it, do nothing
1396 if( mRelayoutData || relayoutEnabled )
1398 EnsureRelayoutData();
1400 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1402 mRelayoutData->relayoutEnabled = relayoutEnabled;
1406 bool Actor::IsRelayoutEnabled() const
1408 // Assume that if relayout data has not been allocated yet then
1409 // relayout is disabled
1410 return mRelayoutData && mRelayoutData->relayoutEnabled;
1413 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1415 EnsureRelayoutData();
1417 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1419 if( dimension & ( 1 << i ) )
1421 mRelayoutData->dimensionDirty[ i ] = dirty;
1426 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1428 if ( mRelayoutData )
1430 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1432 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1442 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1444 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1447 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1449 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1452 uint32_t Actor::AddRenderer( Renderer& renderer )
1456 mRenderers = new RendererContainer;
1459 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1460 RendererPtr rendererPtr = RendererPtr( &renderer );
1461 mRenderers->push_back( rendererPtr );
1462 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1466 uint32_t Actor::GetRendererCount() const
1468 uint32_t rendererCount(0);
1471 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1474 return rendererCount;
1477 RendererPtr Actor::GetRendererAt( uint32_t index )
1479 RendererPtr renderer;
1480 if( index < GetRendererCount() )
1482 renderer = ( *mRenderers )[ index ];
1488 void Actor::RemoveRenderer( Renderer& renderer )
1492 RendererIter end = mRenderers->end();
1493 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1495 if( (*iter).Get() == &renderer )
1497 mRenderers->erase( iter );
1498 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1505 void Actor::RemoveRenderer( uint32_t index )
1507 if( index < GetRendererCount() )
1509 RendererPtr renderer = ( *mRenderers )[ index ];
1510 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1511 mRenderers->erase( mRenderers->begin()+index );
1515 bool Actor::IsOverlay() const
1517 return ( DrawMode::OVERLAY_2D == mDrawMode );
1520 void Actor::SetDrawMode( DrawMode::Type drawMode )
1522 // this flag is not animatable so keep the value
1523 mDrawMode = drawMode;
1525 // node is being used in a separate thread; queue a message to set the value
1526 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1529 DrawMode::Type Actor::GetDrawMode() const
1534 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1536 // only valid when on-stage
1537 if( mScene && OnStage() )
1539 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1541 Vector2 converted( screenX, screenY );
1543 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1544 uint32_t taskCount = taskList.GetTaskCount();
1545 for( uint32_t i = taskCount; i > 0; --i )
1547 RenderTaskPtr task = taskList.GetTask( i - 1 );
1548 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1550 // found a task where this conversion was ok so return
1558 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1560 bool retval = false;
1561 // only valid when on-stage
1564 CameraActor* camera = renderTask.GetCameraActor();
1568 renderTask.GetViewport( viewport );
1570 // need to translate coordinates to render tasks coordinate space
1571 Vector2 converted( screenX, screenY );
1572 if( renderTask.TranslateCoordinates( converted ) )
1574 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1581 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1583 // Early-out if not on stage
1589 // Get the ModelView matrix
1591 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1593 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1594 Matrix invertedMvp( false/*don't init*/);
1595 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1596 bool success = invertedMvp.Invert();
1598 // Convert to GL coordinates
1599 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1604 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1611 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1617 if( XyPlaneIntersect( nearPos, farPos, local ) )
1619 Vector3 size = GetCurrentSize();
1620 localX = local.x + size.x * 0.5f;
1621 localY = local.y + size.y * 0.5f;
1632 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1635 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1637 Mathematical Formulation
1639 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1641 ( p - c ) dot ( p - c ) = r^2
1643 Given a ray with a point of origin 'o', and a direction vector 'd':
1645 ray(t) = o + td, t >= 0
1647 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1649 (o + td - c ) dot ( o + td - c ) = r^2
1651 To solve for t we first expand the above into a more recognisable quadratic equation form
1653 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1662 B = 2( o - c ) dot d
1663 C = ( o - c ) dot ( o - c ) - r^2
1665 which can be solved using a standard quadratic formula.
1667 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1669 Practical Simplification
1671 In a renderer, we often differentiate between world space and object space. In the object space
1672 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1673 into object space, the mathematical solution presented above can be simplified significantly.
1675 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1679 and we can find the t at which the (transformed) ray intersects the sphere by
1681 ( o + td ) dot ( o + td ) = r^2
1683 According to the reasoning above, we expand the above quadratic equation into the general form
1687 which now has coefficients:
1694 // Early-out if not on stage
1700 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1702 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1703 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1704 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1706 // Compute the radius is not needed, square radius it's enough.
1707 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1709 // Scale the sphere.
1710 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1712 const float width = size.width * scale.width;
1713 const float height = size.height * scale.height;
1715 float squareSphereRadius = 0.5f * ( width * width + height * height );
1717 float a = rayDir.Dot( rayDir ); // a
1718 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1719 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1721 return ( b2 * b2 - a * c ) >= 0.f;
1724 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1730 // Transforms the ray to the local reference system.
1731 // Calculate the inverse of Model matrix
1732 Matrix invModelMatrix( false/*don't init*/);
1734 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1735 invModelMatrix = GetNode().GetWorldMatrix(0);
1736 invModelMatrix.Invert();
1738 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1739 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1741 // Test with the actor's XY plane (Normal = 0 0 1 1).
1743 float a = -rayOriginLocal.z;
1744 float b = rayDirLocal.z;
1746 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1748 // Ray travels distance * rayDirLocal to intersect with plane.
1751 const Vector3& size = GetNode().GetSize( bufferIndex );
1753 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1754 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1756 // Test with the actor's geometry.
1757 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1764 void Actor::SetLeaveRequired( bool required )
1766 mLeaveRequired = required;
1769 bool Actor::GetLeaveRequired() const
1771 return mLeaveRequired;
1774 void Actor::SetKeyboardFocusable( bool focusable )
1776 mKeyboardFocusable = focusable;
1779 bool Actor::IsKeyboardFocusable() const
1781 return mKeyboardFocusable;
1784 bool Actor::GetTouchRequired() const
1786 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1789 bool Actor::GetHoverRequired() const
1791 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1794 bool Actor::GetWheelEventRequired() const
1796 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1799 bool Actor::IsHittable() const
1801 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1804 ActorGestureData& Actor::GetGestureData()
1806 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1807 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1808 if( NULL == mGestureData )
1810 mGestureData = new ActorGestureData;
1812 return *mGestureData;
1815 bool Actor::IsGestureRequred( DevelGesture::Type type ) const
1817 return mGestureData && mGestureData->IsGestureRequred( type );
1820 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1822 bool consumed = false;
1824 if( !mTouchSignal.Empty() )
1826 Dali::Actor handle( this );
1827 consumed = mTouchSignal.Emit( handle, touch );
1830 if( !mTouchedSignal.Empty() )
1832 Dali::Actor handle( this );
1833 consumed |= mTouchedSignal.Emit( handle, event );
1838 // Notification for derived classes
1839 consumed = OnTouchEvent( event ); // TODO
1845 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1847 bool consumed = false;
1849 if( !mHoveredSignal.Empty() )
1851 Dali::Actor handle( this );
1852 consumed = mHoveredSignal.Emit( handle, event );
1857 // Notification for derived classes
1858 consumed = OnHoverEvent( event );
1864 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1866 bool consumed = false;
1868 if( !mWheelEventSignal.Empty() )
1870 Dali::Actor handle( this );
1871 consumed = mWheelEventSignal.Emit( handle, event );
1876 // Notification for derived classes
1877 consumed = OnWheelEvent( event );
1883 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1885 if( ! mVisibilityChangedSignal.Empty() )
1887 Dali::Actor handle( this );
1888 mVisibilityChangedSignal.Emit( handle, visible, type );
1892 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1894 if( ! mLayoutDirectionChangedSignal.Empty() )
1896 Dali::Actor handle( this );
1897 mLayoutDirectionChangedSignal.Emit( handle, type );
1901 void Actor::EmitChildAddedSignal( Actor& child )
1903 if( ! mChildAddedSignal.Empty() )
1905 Dali::Actor handle( &child );
1906 mChildAddedSignal.Emit( handle );
1910 void Actor::EmitChildRemovedSignal( Actor& child )
1912 if( ! mChildRemovedSignal.Empty() )
1914 Dali::Actor handle( &child );
1915 mChildRemovedSignal.Emit( handle );
1919 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1921 return mTouchedSignal;
1924 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1926 return mTouchSignal;
1929 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1931 return mHoveredSignal;
1934 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1936 return mWheelEventSignal;
1939 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1941 return mOnStageSignal;
1944 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1946 return mOffStageSignal;
1949 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1951 return mOnRelayoutSignal;
1954 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1956 return mVisibilityChangedSignal;
1959 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1961 return mLayoutDirectionChangedSignal;
1964 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1966 return mChildAddedSignal;
1969 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1971 return mChildRemovedSignal;
1974 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1976 return mChildOrderChangedSignal;
1979 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1981 bool connected( true );
1982 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1984 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1986 actor->TouchedSignal().Connect( tracker, functor );
1988 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1990 actor->HoveredSignal().Connect( tracker, functor );
1992 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1994 actor->WheelEventSignal().Connect( tracker, functor );
1996 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1998 actor->OnStageSignal().Connect( tracker, functor );
2000 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2002 actor->OffStageSignal().Connect( tracker, functor );
2004 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2006 actor->OnRelayoutSignal().Connect( tracker, functor );
2008 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2010 actor->TouchSignal().Connect( tracker, functor );
2012 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
2014 actor->VisibilityChangedSignal().Connect( tracker, functor );
2016 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2018 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2020 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2022 actor->ChildAddedSignal().Connect( tracker, functor );
2024 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2026 actor->ChildRemovedSignal().Connect( tracker, functor );
2030 // signalName does not match any signal
2037 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2043 mParentOrigin( NULL ),
2044 mAnchorPoint( NULL ),
2045 mRelayoutData( NULL ),
2046 mGestureData( NULL ),
2050 mWheelEventSignal(),
2053 mOnRelayoutSignal(),
2054 mVisibilityChangedSignal(),
2055 mLayoutDirectionChangedSignal(),
2056 mChildAddedSignal(),
2057 mChildRemovedSignal(),
2058 mChildOrderChangedSignal(),
2059 mTargetOrientation( Quaternion::IDENTITY ),
2060 mTargetColor( Color::WHITE ),
2061 mTargetSize( Vector3::ZERO ),
2062 mTargetPosition( Vector3::ZERO ),
2063 mTargetScale( Vector3::ONE ),
2064 mAnimatedSize( Vector3::ZERO ),
2068 mUseAnimatedSize( AnimatedSizeFlag::CLEAR ),
2069 mIsRoot( ROOT_LAYER == derivedType ),
2070 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2071 mIsOnStage( false ),
2073 mLeaveRequired( false ),
2074 mKeyboardFocusable( false ),
2075 mDerivedRequiresTouch( false ),
2076 mDerivedRequiresHover( false ),
2077 mDerivedRequiresWheelEvent( false ),
2078 mOnStageSignalled( false ),
2079 mInsideOnSizeSet( false ),
2080 mInheritPosition( true ),
2081 mInheritOrientation( true ),
2082 mInheritScale( true ),
2083 mPositionUsesAnchorPoint( true ),
2085 mInheritLayoutDirection( true ),
2086 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2087 mDrawMode( DrawMode::NORMAL ),
2088 mColorMode( Node::DEFAULT_COLOR_MODE ),
2089 mClippingMode( ClippingMode::DISABLED )
2093 void Actor::Initialize()
2097 GetEventThreadServices().RegisterObject( this );
2102 // Remove mParent pointers from children even if we're destroying core,
2103 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2106 ActorConstIter endIter = mChildren->end();
2107 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2109 (*iter)->SetParent( NULL );
2115 // Guard to allow handle destruction after Core has been destroyed
2116 if( EventThreadServices::IsCoreRunning() )
2118 // Root layer will destroy its node in its own destructor
2121 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2123 GetEventThreadServices().UnregisterObject( this );
2127 // Cleanup optional gesture data
2128 delete mGestureData;
2130 // Cleanup optional parent origin and anchor
2131 delete mParentOrigin;
2132 delete mAnchorPoint;
2134 // Delete optional relayout data
2135 delete mRelayoutData;
2138 void Actor::ConnectToStage( uint32_t parentDepth )
2140 // This container is used instead of walking the Actor hierarchy.
2141 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2142 ActorContainer connectionList;
2146 mScene->RequestRebuildDepthTree();
2149 // This stage is atomic i.e. not interrupted by user callbacks.
2150 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2152 // Notify applications about the newly connected actors.
2153 const ActorIter endIter = connectionList.end();
2154 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2156 (*iter)->NotifyStageConnection();
2162 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2164 DALI_ASSERT_ALWAYS( !OnStage() );
2167 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2169 ConnectToSceneGraph();
2171 // Notification for internal derived classes
2172 OnStageConnectionInternal();
2174 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2175 connectionList.push_back( ActorPtr( this ) );
2177 // Recursively connect children
2180 ActorConstIter endIter = mChildren->end();
2181 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2183 (*iter)->SetScene( *mScene );
2184 (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2190 * This method is called when the Actor is connected to the Stage.
2191 * The parent must have added its Node to the scene-graph.
2192 * The child must connect its Node to the parent's Node.
2193 * This is recursive; the child calls ConnectToStage() for its children.
2195 void Actor::ConnectToSceneGraph()
2197 DALI_ASSERT_DEBUG( mParent != NULL);
2199 // Reparent Node in next Update
2200 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2202 // Request relayout on all actors that are added to the scenegraph
2205 // Notification for Object::Observers
2209 void Actor::NotifyStageConnection()
2211 // Actors can be removed (in a callback), before the on-stage stage is reported.
2212 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2213 if( OnStage() && !mOnStageSignalled )
2215 // Notification for external (CustomActor) derived classes
2216 OnStageConnectionExternal( mDepth );
2218 if( !mOnStageSignal.Empty() )
2220 Dali::Actor handle( this );
2221 mOnStageSignal.Emit( handle );
2224 // Guard against Remove during callbacks
2227 mOnStageSignalled = true; // signal required next time Actor is removed
2232 void Actor::DisconnectFromStage()
2234 // This container is used instead of walking the Actor hierachy.
2235 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2236 ActorContainer disconnectionList;
2240 mScene->RequestRebuildDepthTree();
2243 // This stage is atomic i.e. not interrupted by user callbacks
2244 RecursiveDisconnectFromStage( disconnectionList );
2246 // Notify applications about the newly disconnected actors.
2247 const ActorIter endIter = disconnectionList.end();
2248 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2250 (*iter)->NotifyStageDisconnection();
2254 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2256 // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2259 // Recursively disconnect children
2262 ActorConstIter endIter = mChildren->end();
2263 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2265 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2269 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2270 disconnectionList.push_back( ActorPtr( this ) );
2272 // Notification for internal derived classes
2273 OnStageDisconnectionInternal();
2275 DisconnectFromSceneGraph();
2279 * This method is called by an actor or its parent, before a node removal message is sent.
2280 * This is recursive; the child calls DisconnectFromStage() for its children.
2282 void Actor::DisconnectFromSceneGraph()
2284 // Notification for Object::Observers
2285 OnSceneObjectRemove();
2288 void Actor::NotifyStageDisconnection()
2290 // Actors can be added (in a callback), before the off-stage state is reported.
2291 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2292 // only do this step if there is a stage, i.e. Core is not being shut down
2293 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2295 // Notification for external (CustomeActor) derived classes
2296 OnStageDisconnectionExternal();
2298 if( !mOffStageSignal.Empty() )
2300 Dali::Actor handle( this );
2301 mOffStageSignal.Emit( handle );
2304 // Guard against Add during callbacks
2307 mOnStageSignalled = false; // signal required next time Actor is added
2312 bool Actor::IsNodeConnected() const
2314 bool connected( false );
2318 if( IsRoot() || GetNode().GetParent() )
2327 // This method initiates traversal of the actor tree using depth-first
2328 // traversal to set a depth index based on traversal order. It sends a
2329 // single message to update manager to update all the actor's nodes in
2330 // this tree with the depth index. The sceneGraphNodeDepths vector's
2331 // elements are ordered by depth, and could be used to reduce sorting
2332 // in the update thread.
2333 void Actor::RebuildDepthTree()
2335 DALI_LOG_TIMER_START(depthTimer);
2337 // Vector of scene-graph nodes and their depths to send to UpdateManager
2338 // in a single message
2339 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2341 int32_t depthIndex = 1;
2342 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2344 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2345 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2348 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2350 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2351 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2353 // Create/add to children of this node
2356 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2358 Actor* childActor = (*it).Get();
2360 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2365 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2369 case Dali::Actor::Property::PARENT_ORIGIN:
2371 Property::Type type = property.GetType();
2372 if( type == Property::VECTOR3 )
2374 SetParentOrigin( property.Get< Vector3 >() );
2376 else if ( type == Property::STRING )
2378 std::string parentOriginString;
2379 property.Get( parentOriginString );
2380 Vector3 parentOrigin;
2381 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2383 SetParentOrigin( parentOrigin );
2389 case Dali::Actor::Property::PARENT_ORIGIN_X:
2391 SetParentOriginX( property.Get< float >() );
2395 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2397 SetParentOriginY( property.Get< float >() );
2401 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2403 SetParentOriginZ( property.Get< float >() );
2407 case Dali::Actor::Property::ANCHOR_POINT:
2409 Property::Type type = property.GetType();
2410 if( type == Property::VECTOR3 )
2412 SetAnchorPoint( property.Get< Vector3 >() );
2414 else if ( type == Property::STRING )
2416 std::string anchorPointString;
2417 property.Get( anchorPointString );
2419 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2421 SetAnchorPoint( anchor );
2427 case Dali::Actor::Property::ANCHOR_POINT_X:
2429 SetAnchorPointX( property.Get< float >() );
2433 case Dali::Actor::Property::ANCHOR_POINT_Y:
2435 SetAnchorPointY( property.Get< float >() );
2439 case Dali::Actor::Property::ANCHOR_POINT_Z:
2441 SetAnchorPointZ( property.Get< float >() );
2445 case Dali::Actor::Property::SIZE:
2447 Property::Type type = property.GetType();
2448 if( type == Property::VECTOR2 )
2450 SetSize( property.Get< Vector2 >() );
2452 else if ( type == Property::VECTOR3 )
2454 SetSize( property.Get< Vector3 >() );
2459 case Dali::Actor::Property::SIZE_WIDTH:
2461 SetWidth( property.Get< float >() );
2465 case Dali::Actor::Property::SIZE_HEIGHT:
2467 SetHeight( property.Get< float >() );
2471 case Dali::Actor::Property::SIZE_DEPTH:
2473 SetDepth( property.Get< float >() );
2477 case Dali::Actor::Property::POSITION:
2479 Property::Type type = property.GetType();
2480 if( type == Property::VECTOR2 )
2482 Vector2 position = property.Get< Vector2 >();
2483 SetPosition( Vector3( position.x, position.y, 0.0f ) );
2485 else if ( type == Property::VECTOR3 )
2487 SetPosition( property.Get< Vector3 >() );
2492 case Dali::Actor::Property::POSITION_X:
2494 SetX( property.Get< float >() );
2498 case Dali::Actor::Property::POSITION_Y:
2500 SetY( property.Get< float >() );
2504 case Dali::Actor::Property::POSITION_Z:
2506 SetZ( property.Get< float >() );
2510 case Dali::Actor::Property::ORIENTATION:
2512 SetOrientation( property.Get< Quaternion >() );
2516 case Dali::Actor::Property::SCALE:
2518 Property::Type type = property.GetType();
2519 if( type == Property::FLOAT )
2521 float scale = property.Get< float >();
2522 SetScale( scale, scale, scale );
2524 else if ( type == Property::VECTOR3 )
2526 SetScale( property.Get< Vector3 >() );
2531 case Dali::Actor::Property::SCALE_X:
2533 SetScaleX( property.Get< float >() );
2537 case Dali::Actor::Property::SCALE_Y:
2539 SetScaleY( property.Get< float >() );
2543 case Dali::Actor::Property::SCALE_Z:
2545 SetScaleZ( property.Get< float >() );
2549 case Dali::Actor::Property::VISIBLE:
2551 SetVisible( property.Get< bool >() );
2555 case Dali::Actor::Property::COLOR:
2557 Property::Type type = property.GetType();
2558 if( type == Property::VECTOR3 )
2560 Vector3 color = property.Get< Vector3 >();
2561 SetColor( Vector4( color.r, color.g, color.b, 1.0f ) );
2563 else if( type == Property::VECTOR4 )
2565 SetColor( property.Get< Vector4 >() );
2570 case Dali::Actor::Property::COLOR_RED:
2572 SetColorRed( property.Get< float >() );
2576 case Dali::Actor::Property::COLOR_GREEN:
2578 SetColorGreen( property.Get< float >() );
2582 case Dali::Actor::Property::COLOR_BLUE:
2584 SetColorBlue( property.Get< float >() );
2588 case Dali::Actor::Property::COLOR_ALPHA:
2589 case Dali::DevelActor::Property::OPACITY:
2592 if( property.Get( value ) )
2594 SetOpacity( value );
2599 case Dali::Actor::Property::NAME:
2601 SetName( property.Get< std::string >() );
2605 case Dali::Actor::Property::SENSITIVE:
2607 SetSensitive( property.Get< bool >() );
2611 case Dali::Actor::Property::LEAVE_REQUIRED:
2613 SetLeaveRequired( property.Get< bool >() );
2617 case Dali::Actor::Property::INHERIT_POSITION:
2619 SetInheritPosition( property.Get< bool >() );
2623 case Dali::Actor::Property::INHERIT_ORIENTATION:
2625 SetInheritOrientation( property.Get< bool >() );
2629 case Dali::Actor::Property::INHERIT_SCALE:
2631 SetInheritScale( property.Get< bool >() );
2635 case Dali::Actor::Property::COLOR_MODE:
2637 ColorMode mode = mColorMode;
2638 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2640 SetColorMode( mode );
2645 case Dali::Actor::Property::DRAW_MODE:
2647 DrawMode::Type mode = mDrawMode;
2648 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2650 SetDrawMode( mode );
2655 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2657 SetSizeModeFactor( property.Get< Vector3 >() );
2661 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2663 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2664 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2666 SetResizePolicy( type, Dimension::WIDTH );
2671 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2673 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2674 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2676 SetResizePolicy( type, Dimension::HEIGHT );
2681 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2683 SizeScalePolicy::Type type = GetSizeScalePolicy();
2684 if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2686 SetSizeScalePolicy( type );
2691 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2693 if( property.Get< bool >() )
2695 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2700 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2702 if( property.Get< bool >() )
2704 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2709 case Dali::Actor::Property::PADDING:
2711 Vector4 padding = property.Get< Vector4 >();
2712 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2713 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2717 case Dali::Actor::Property::MINIMUM_SIZE:
2719 Vector2 size = property.Get< Vector2 >();
2720 SetMinimumSize( size.x, Dimension::WIDTH );
2721 SetMinimumSize( size.y, Dimension::HEIGHT );
2725 case Dali::Actor::Property::MAXIMUM_SIZE:
2727 Vector2 size = property.Get< Vector2 >();
2728 SetMaximumSize( size.x, Dimension::WIDTH );
2729 SetMaximumSize( size.y, Dimension::HEIGHT );
2733 case Dali::DevelActor::Property::SIBLING_ORDER:
2737 if( property.Get( value ) )
2739 SetSiblingOrder( value );
2744 case Dali::Actor::Property::CLIPPING_MODE:
2746 ClippingMode::Type convertedValue = mClippingMode;
2747 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2749 mClippingMode = convertedValue;
2750 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2755 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2758 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2760 mPositionUsesAnchorPoint = value;
2761 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2766 case Dali::Actor::Property::LAYOUT_DIRECTION:
2768 Dali::LayoutDirection::Type direction = mLayoutDirection;
2769 mInheritLayoutDirection = false;
2771 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2773 InheritLayoutDirectionRecursively( this, direction, true );
2778 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2781 if( property.Get( value ) )
2783 SetInheritLayoutDirection( value );
2790 // this can happen in the case of a non-animatable default property so just do nothing
2796 // TODO: This method needs to be removed
2797 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2799 switch( entry.GetType() )
2801 case Property::BOOLEAN:
2803 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2804 DALI_ASSERT_DEBUG( NULL != property );
2806 // property is being used in a separate thread; queue a message to set the property
2807 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2812 case Property::INTEGER:
2814 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2815 DALI_ASSERT_DEBUG( NULL != property );
2817 // property is being used in a separate thread; queue a message to set the property
2818 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2823 case Property::FLOAT:
2825 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2826 DALI_ASSERT_DEBUG( NULL != property );
2828 // property is being used in a separate thread; queue a message to set the property
2829 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2834 case Property::VECTOR2:
2836 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2837 DALI_ASSERT_DEBUG( NULL != property );
2839 // property is being used in a separate thread; queue a message to set the property
2840 if(entry.componentIndex == 0)
2842 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2844 else if(entry.componentIndex == 1)
2846 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2850 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2856 case Property::VECTOR3:
2858 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2859 DALI_ASSERT_DEBUG( NULL != property );
2861 // property is being used in a separate thread; queue a message to set the property
2862 if(entry.componentIndex == 0)
2864 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2866 else if(entry.componentIndex == 1)
2868 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2870 else if(entry.componentIndex == 2)
2872 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2876 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2882 case Property::VECTOR4:
2884 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2885 DALI_ASSERT_DEBUG( NULL != property );
2887 // property is being used in a separate thread; queue a message to set the property
2888 if(entry.componentIndex == 0)
2890 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2892 else if(entry.componentIndex == 1)
2894 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2896 else if(entry.componentIndex == 2)
2898 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2900 else if(entry.componentIndex == 3)
2902 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2906 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2912 case Property::ROTATION:
2914 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2915 DALI_ASSERT_DEBUG( NULL != property );
2917 // property is being used in a separate thread; queue a message to set the property
2918 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2923 case Property::MATRIX:
2925 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2926 DALI_ASSERT_DEBUG( NULL != property );
2928 // property is being used in a separate thread; queue a message to set the property
2929 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2934 case Property::MATRIX3:
2936 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2937 DALI_ASSERT_DEBUG( NULL != property );
2939 // property is being used in a separate thread; queue a message to set the property
2940 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2947 // nothing to do for other types
2952 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2954 Property::Value value;
2956 if( ! GetCachedPropertyValue( index, value ) )
2958 // If property value is not stored in the event-side, then it must be a scene-graph only property
2959 GetCurrentPropertyValue( index, value );
2965 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2967 Property::Value value;
2969 if( ! GetCurrentPropertyValue( index, value ) )
2971 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2972 GetCachedPropertyValue( index, value );
2978 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2980 switch( animationType )
2983 case Animation::BETWEEN:
2987 case Dali::Actor::Property::SIZE:
2989 if( value.Get( mTargetSize ) )
2991 mAnimatedSize = mTargetSize;
2992 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
2994 // Notify deriving classes
2995 OnSizeAnimation( animation, mTargetSize );
3000 case Dali::Actor::Property::SIZE_WIDTH:
3002 if( value.Get( mTargetSize.width ) )
3004 mAnimatedSize.width = mTargetSize.width;
3005 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3007 // Notify deriving classes
3008 OnSizeAnimation( animation, mTargetSize );
3013 case Dali::Actor::Property::SIZE_HEIGHT:
3015 if( value.Get( mTargetSize.height ) )
3017 mAnimatedSize.height = mTargetSize.height;
3018 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3020 // Notify deriving classes
3021 OnSizeAnimation( animation, mTargetSize );
3026 case Dali::Actor::Property::SIZE_DEPTH:
3028 if( value.Get( mTargetSize.depth ) )
3030 mAnimatedSize.depth = mTargetSize.depth;
3031 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3033 // Notify deriving classes
3034 OnSizeAnimation( animation, mTargetSize );
3039 case Dali::Actor::Property::POSITION:
3041 value.Get( mTargetPosition );
3045 case Dali::Actor::Property::POSITION_X:
3047 value.Get( mTargetPosition.x );
3051 case Dali::Actor::Property::POSITION_Y:
3053 value.Get( mTargetPosition.y );
3057 case Dali::Actor::Property::POSITION_Z:
3059 value.Get( mTargetPosition.z );
3063 case Dali::Actor::Property::ORIENTATION:
3065 value.Get( mTargetOrientation );
3069 case Dali::Actor::Property::SCALE:
3071 value.Get( mTargetScale );
3075 case Dali::Actor::Property::SCALE_X:
3077 value.Get( mTargetScale.x );
3081 case Dali::Actor::Property::SCALE_Y:
3083 value.Get( mTargetScale.y );
3087 case Dali::Actor::Property::SCALE_Z:
3089 value.Get( mTargetScale.z );
3093 case Dali::Actor::Property::VISIBLE:
3095 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3099 case Dali::Actor::Property::COLOR:
3101 value.Get( mTargetColor );
3105 case Dali::Actor::Property::COLOR_RED:
3107 value.Get( mTargetColor.r );
3111 case Dali::Actor::Property::COLOR_GREEN:
3113 value.Get( mTargetColor.g );
3117 case Dali::Actor::Property::COLOR_BLUE:
3119 value.Get( mTargetColor.b );
3123 case Dali::Actor::Property::COLOR_ALPHA:
3124 case Dali::DevelActor::Property::OPACITY:
3126 value.Get( mTargetColor.a );
3132 // Not an animatable property. Do nothing.
3143 case Dali::Actor::Property::SIZE:
3145 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3147 mAnimatedSize = mTargetSize;
3148 mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
3150 // Notify deriving classes
3151 OnSizeAnimation( animation, mTargetSize );
3156 case Dali::Actor::Property::SIZE_WIDTH:
3158 if( AdjustValue< float >( mTargetSize.width, value ) )
3160 mAnimatedSize.width = mTargetSize.width;
3161 mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
3163 // Notify deriving classes
3164 OnSizeAnimation( animation, mTargetSize );
3169 case Dali::Actor::Property::SIZE_HEIGHT:
3171 if( AdjustValue< float >( mTargetSize.height, value ) )
3173 mAnimatedSize.height = mTargetSize.height;
3174 mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
3176 // Notify deriving classes
3177 OnSizeAnimation( animation, mTargetSize );
3182 case Dali::Actor::Property::SIZE_DEPTH:
3184 if( AdjustValue< float >( mTargetSize.depth, value ) )
3186 mAnimatedSize.depth = mTargetSize.depth;
3187 mUseAnimatedSize |= AnimatedSizeFlag::DEPTH;
3189 // Notify deriving classes
3190 OnSizeAnimation( animation, mTargetSize );
3195 case Dali::Actor::Property::POSITION:
3197 AdjustValue< Vector3 >( mTargetPosition, value );
3201 case Dali::Actor::Property::POSITION_X:
3203 AdjustValue< float >( mTargetPosition.x, value );
3207 case Dali::Actor::Property::POSITION_Y:
3209 AdjustValue< float >( mTargetPosition.y, value );
3213 case Dali::Actor::Property::POSITION_Z:
3215 AdjustValue< float >( mTargetPosition.z, value );
3219 case Dali::Actor::Property::ORIENTATION:
3221 Quaternion relativeValue;
3222 if( value.Get( relativeValue ) )
3224 mTargetOrientation *= relativeValue;
3229 case Dali::Actor::Property::SCALE:
3231 AdjustValue< Vector3 >( mTargetScale, value );
3235 case Dali::Actor::Property::SCALE_X:
3237 AdjustValue< float >( mTargetScale.x, value );
3241 case Dali::Actor::Property::SCALE_Y:
3243 AdjustValue< float >( mTargetScale.y, value );
3247 case Dali::Actor::Property::SCALE_Z:
3249 AdjustValue< float >( mTargetScale.z, value );
3253 case Dali::Actor::Property::VISIBLE:
3255 bool relativeValue = false;
3256 if( value.Get( relativeValue ) )
3258 bool visible = mVisible || relativeValue;
3259 SetVisibleInternal( visible, SendMessage::FALSE );
3264 case Dali::Actor::Property::COLOR:
3266 AdjustValue< Vector4 >( mTargetColor, value );
3270 case Dali::Actor::Property::COLOR_RED:
3272 AdjustValue< float >( mTargetColor.r, value );
3276 case Dali::Actor::Property::COLOR_GREEN:
3278 AdjustValue< float >( mTargetColor.g, value );
3282 case Dali::Actor::Property::COLOR_BLUE:
3284 AdjustValue< float >( mTargetColor.b, value );
3288 case Dali::Actor::Property::COLOR_ALPHA:
3289 case Dali::DevelActor::Property::OPACITY:
3291 AdjustValue< float >( mTargetColor.a, value );
3297 // Not an animatable property. Do nothing.
3306 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3308 const PropertyBase* property( NULL );
3312 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3313 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3314 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3315 case Dali::Actor::Property::SIZE_DEPTH:
3317 property = &GetNode().mSize;
3320 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3321 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3322 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3323 case Dali::Actor::Property::POSITION_Z:
3325 property = &GetNode().mPosition;
3328 case Dali::Actor::Property::ORIENTATION:
3330 property = &GetNode().mOrientation;
3333 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3334 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3335 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3336 case Dali::Actor::Property::SCALE_Z:
3338 property = &GetNode().mScale;
3341 case Dali::Actor::Property::VISIBLE:
3343 property = &GetNode().mVisible;
3346 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3347 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3348 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3349 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3350 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3351 case Dali::DevelActor::Property::OPACITY:
3353 property = &GetNode().mColor;
3363 // not our property, ask base
3364 property = Object::GetSceneObjectAnimatableProperty( index );
3370 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3372 const PropertyInputImpl* property( NULL );
3376 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3377 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3378 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3379 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3381 property = &GetNode().mParentOrigin;
3384 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3385 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3386 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3387 case Dali::Actor::Property::ANCHOR_POINT_Z:
3389 property = &GetNode().mAnchorPoint;
3392 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3393 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3394 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3395 case Dali::Actor::Property::WORLD_POSITION_Z:
3397 property = &GetNode().mWorldPosition;
3400 case Dali::Actor::Property::WORLD_ORIENTATION:
3402 property = &GetNode().mWorldOrientation;
3405 case Dali::Actor::Property::WORLD_SCALE:
3407 property = &GetNode().mWorldScale;
3410 case Dali::Actor::Property::WORLD_COLOR:
3412 property = &GetNode().mWorldColor;
3415 case Dali::Actor::Property::WORLD_MATRIX:
3417 property = &GetNode().mWorldMatrix;
3420 case Dali::DevelActor::Property::CULLED:
3422 property = &GetNode().mCulled;
3432 // reuse animatable property getter as animatable properties are inputs as well
3433 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3434 property = GetSceneObjectAnimatableProperty( index );
3440 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3442 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3446 case Dali::Actor::Property::PARENT_ORIGIN_X:
3447 case Dali::Actor::Property::ANCHOR_POINT_X:
3448 case Dali::Actor::Property::SIZE_WIDTH:
3449 case Dali::Actor::Property::POSITION_X:
3450 case Dali::Actor::Property::WORLD_POSITION_X:
3451 case Dali::Actor::Property::SCALE_X:
3452 case Dali::Actor::Property::COLOR_RED:
3458 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3459 case Dali::Actor::Property::ANCHOR_POINT_Y:
3460 case Dali::Actor::Property::SIZE_HEIGHT:
3461 case Dali::Actor::Property::POSITION_Y:
3462 case Dali::Actor::Property::WORLD_POSITION_Y:
3463 case Dali::Actor::Property::SCALE_Y:
3464 case Dali::Actor::Property::COLOR_GREEN:
3470 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3471 case Dali::Actor::Property::ANCHOR_POINT_Z:
3472 case Dali::Actor::Property::SIZE_DEPTH:
3473 case Dali::Actor::Property::POSITION_Z:
3474 case Dali::Actor::Property::WORLD_POSITION_Z:
3475 case Dali::Actor::Property::SCALE_Z:
3476 case Dali::Actor::Property::COLOR_BLUE:
3482 case Dali::Actor::Property::COLOR_ALPHA:
3483 case Dali::DevelActor::Property::OPACITY:
3495 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3498 componentIndex = Object::GetPropertyComponentIndex( index );
3501 return componentIndex;
3504 void Actor::SetParent( Actor* parent )
3508 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3512 mScene = parent->mScene;
3514 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3517 // Instruct each actor to create a corresponding node in the scene graph
3518 ConnectToStage( parent->GetHierarchyDepth() );
3521 // Resolve the name and index for the child properties if any
3522 ResolveChildProperties();
3524 else // parent being set to NULL
3526 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3530 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3533 // Disconnect the Node & its children from the scene-graph.
3534 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3536 // Instruct each actor to discard pointers to the scene-graph
3537 DisconnectFromStage();
3544 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3547 Actor* actor = dynamic_cast< Actor* >( object );
3551 if( 0 == actionName.compare( ACTION_SHOW ) )
3553 actor->SetVisible( true );
3556 else if( 0 == actionName.compare( ACTION_HIDE ) )
3558 actor->SetVisible( false );
3566 Rect<> Actor::CalculateScreenExtents( ) const
3568 auto screenPosition = GetCurrentScreenPosition();
3569 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
3570 Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
3571 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
3572 return { position.x, position.y, size.x, size.y };
3575 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3577 bool valueSet = true;
3581 case Dali::Actor::Property::PARENT_ORIGIN:
3583 value = GetCurrentParentOrigin();
3587 case Dali::Actor::Property::PARENT_ORIGIN_X:
3589 value = GetCurrentParentOrigin().x;
3593 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3595 value = GetCurrentParentOrigin().y;
3599 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3601 value = GetCurrentParentOrigin().z;
3605 case Dali::Actor::Property::ANCHOR_POINT:
3607 value = GetCurrentAnchorPoint();
3611 case Dali::Actor::Property::ANCHOR_POINT_X:
3613 value = GetCurrentAnchorPoint().x;
3617 case Dali::Actor::Property::ANCHOR_POINT_Y:
3619 value = GetCurrentAnchorPoint().y;
3623 case Dali::Actor::Property::ANCHOR_POINT_Z:
3625 value = GetCurrentAnchorPoint().z;
3629 case Dali::Actor::Property::SIZE:
3631 value = GetTargetSize();
3635 case Dali::Actor::Property::SIZE_WIDTH:
3637 value = GetTargetSize().width;
3641 case Dali::Actor::Property::SIZE_HEIGHT:
3643 value = GetTargetSize().height;
3647 case Dali::Actor::Property::SIZE_DEPTH:
3649 value = GetTargetSize().depth;
3653 case Dali::Actor::Property::POSITION:
3655 value = GetTargetPosition();
3659 case Dali::Actor::Property::POSITION_X:
3661 value = GetTargetPosition().x;
3665 case Dali::Actor::Property::POSITION_Y:
3667 value = GetTargetPosition().y;
3671 case Dali::Actor::Property::POSITION_Z:
3673 value = GetTargetPosition().z;
3677 case Dali::Actor::Property::ORIENTATION:
3679 value = mTargetOrientation;
3683 case Dali::Actor::Property::SCALE:
3685 value = mTargetScale;
3689 case Dali::Actor::Property::SCALE_X:
3691 value = mTargetScale.x;
3695 case Dali::Actor::Property::SCALE_Y:
3697 value = mTargetScale.y;
3701 case Dali::Actor::Property::SCALE_Z:
3703 value = mTargetScale.z;
3707 case Dali::Actor::Property::VISIBLE:
3713 case Dali::Actor::Property::COLOR:
3715 value = mTargetColor;
3719 case Dali::Actor::Property::COLOR_RED:
3721 value = mTargetColor.r;
3725 case Dali::Actor::Property::COLOR_GREEN:
3727 value = mTargetColor.g;
3731 case Dali::Actor::Property::COLOR_BLUE:
3733 value = mTargetColor.b;
3737 case Dali::Actor::Property::COLOR_ALPHA:
3738 case Dali::DevelActor::Property::OPACITY:
3740 value = mTargetColor.a;
3744 case Dali::Actor::Property::NAME:
3750 case Dali::Actor::Property::SENSITIVE:
3752 value = IsSensitive();
3756 case Dali::Actor::Property::LEAVE_REQUIRED:
3758 value = GetLeaveRequired();
3762 case Dali::Actor::Property::INHERIT_POSITION:
3764 value = IsPositionInherited();
3768 case Dali::Actor::Property::INHERIT_ORIENTATION:
3770 value = IsOrientationInherited();
3774 case Dali::Actor::Property::INHERIT_SCALE:
3776 value = IsScaleInherited();
3780 case Dali::Actor::Property::COLOR_MODE:
3782 value = GetColorMode();
3786 case Dali::Actor::Property::DRAW_MODE:
3788 value = GetDrawMode();
3792 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3794 value = GetSizeModeFactor();
3798 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3800 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3804 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3806 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3810 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3812 value = GetSizeScalePolicy();
3816 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3818 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3822 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3824 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3828 case Dali::Actor::Property::PADDING:
3830 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3831 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3832 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3836 case Dali::Actor::Property::MINIMUM_SIZE:
3838 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3842 case Dali::Actor::Property::MAXIMUM_SIZE:
3844 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3848 case Dali::Actor::Property::CLIPPING_MODE:
3850 value = mClippingMode;
3854 case Dali::DevelActor::Property::SIBLING_ORDER:
3856 value = static_cast<int>( GetSiblingOrder() );
3860 case Dali::DevelActor::Property::SCREEN_POSITION:
3862 value = GetCurrentScreenPosition();
3866 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3868 value = mPositionUsesAnchorPoint;
3872 case Dali::Actor::Property::LAYOUT_DIRECTION:
3874 value = mLayoutDirection;
3878 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3880 value = IsLayoutDirectionInherited();
3886 // Must be a scene-graph only property
3895 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3897 bool valueSet = true;
3901 case Dali::Actor::Property::SIZE:
3903 value = GetCurrentSize();
3907 case Dali::Actor::Property::SIZE_WIDTH:
3909 value = GetCurrentSize().width;
3913 case Dali::Actor::Property::SIZE_HEIGHT:
3915 value = GetCurrentSize().height;
3919 case Dali::Actor::Property::SIZE_DEPTH:
3921 value = GetCurrentSize().depth;
3925 case Dali::Actor::Property::POSITION:
3927 value = GetCurrentPosition();
3931 case Dali::Actor::Property::POSITION_X:
3933 value = GetCurrentPosition().x;
3937 case Dali::Actor::Property::POSITION_Y:
3939 value = GetCurrentPosition().y;
3943 case Dali::Actor::Property::POSITION_Z:
3945 value = GetCurrentPosition().z;
3949 case Dali::Actor::Property::WORLD_POSITION:
3951 value = GetCurrentWorldPosition();
3955 case Dali::Actor::Property::WORLD_POSITION_X:
3957 value = GetCurrentWorldPosition().x;
3961 case Dali::Actor::Property::WORLD_POSITION_Y:
3963 value = GetCurrentWorldPosition().y;
3967 case Dali::Actor::Property::WORLD_POSITION_Z:
3969 value = GetCurrentWorldPosition().z;
3973 case Dali::Actor::Property::ORIENTATION:
3975 value = GetCurrentOrientation();
3979 case Dali::Actor::Property::WORLD_ORIENTATION:
3981 value = GetCurrentWorldOrientation();
3985 case Dali::Actor::Property::SCALE:
3987 value = GetCurrentScale();
3991 case Dali::Actor::Property::SCALE_X:
3993 value = GetCurrentScale().x;
3997 case Dali::Actor::Property::SCALE_Y:
3999 value = GetCurrentScale().y;
4003 case Dali::Actor::Property::SCALE_Z:
4005 value = GetCurrentScale().z;
4009 case Dali::Actor::Property::WORLD_SCALE:
4011 value = GetCurrentWorldScale();
4015 case Dali::Actor::Property::COLOR:
4017 value = GetCurrentColor();
4021 case Dali::Actor::Property::COLOR_RED:
4023 value = GetCurrentColor().r;
4027 case Dali::Actor::Property::COLOR_GREEN:
4029 value = GetCurrentColor().g;
4033 case Dali::Actor::Property::COLOR_BLUE:
4035 value = GetCurrentColor().b;
4039 case Dali::Actor::Property::COLOR_ALPHA:
4040 case Dali::DevelActor::Property::OPACITY:
4042 value = GetCurrentColor().a;
4046 case Dali::Actor::Property::WORLD_COLOR:
4048 value = GetCurrentWorldColor();
4052 case Dali::Actor::Property::WORLD_MATRIX:
4054 value = GetCurrentWorldMatrix();
4058 case Dali::Actor::Property::VISIBLE:
4060 value = IsVisible();
4064 case DevelActor::Property::CULLED:
4066 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4072 // Must be an event-side only property
4081 void Actor::EnsureRelayoutData()
4083 // Assign relayout data.
4084 if( !mRelayoutData )
4086 mRelayoutData = new RelayoutData();
4090 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4092 // Check if actor is dependent on parent
4093 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4095 if( ( dimension & ( 1 << i ) ) )
4097 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4098 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4108 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4110 // Check if actor is dependent on children
4111 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4113 if( ( dimension & ( 1 << i ) ) )
4115 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4116 switch( resizePolicy )
4118 case ResizePolicy::FIT_TO_CHILDREN:
4119 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4135 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4137 return Actor::RelayoutDependentOnChildren( dimension );
4140 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4142 // Check each possible dimension and see if it is dependent on the input one
4143 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4145 if( dimension & ( 1 << i ) )
4147 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4154 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4156 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4158 if( dimension & ( 1 << i ) )
4160 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4165 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4167 // If more than one dimension is requested, just return the first one found
4168 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4170 if( ( dimension & ( 1 << i ) ) )
4172 return mRelayoutData->negotiatedDimensions[ i ];
4176 return 0.0f; // Default
4179 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4181 EnsureRelayoutData();
4183 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4185 if( dimension & ( 1 << i ) )
4187 mRelayoutData->dimensionPadding[ i ] = padding;
4192 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4194 if ( mRelayoutData )
4196 // If more than one dimension is requested, just return the first one found
4197 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4199 if( ( dimension & ( 1 << i ) ) )
4201 return mRelayoutData->dimensionPadding[ i ];
4206 return GetDefaultDimensionPadding();
4209 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4211 EnsureRelayoutData();
4213 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4215 if( dimension & ( 1 << i ) )
4217 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4222 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4224 if ( mRelayoutData )
4226 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4228 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4238 float Actor::GetHeightForWidthBase( float width )
4240 float height = 0.0f;
4242 const Vector3 naturalSize = GetNaturalSize();
4243 if( naturalSize.width > 0.0f )
4245 height = naturalSize.height * width / naturalSize.width;
4247 else // we treat 0 as 1:1 aspect ratio
4255 float Actor::GetWidthForHeightBase( float height )
4259 const Vector3 naturalSize = GetNaturalSize();
4260 if( naturalSize.height > 0.0f )
4262 width = naturalSize.width * height / naturalSize.height;
4264 else // we treat 0 as 1:1 aspect ratio
4272 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4274 // Fill to parent, taking size mode factor into account
4275 switch( child.GetResizePolicy( dimension ) )
4277 case ResizePolicy::FILL_TO_PARENT:
4279 return GetLatestSize( dimension );
4282 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4284 return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4287 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4289 return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
4294 return GetLatestSize( dimension );
4299 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4301 // Can be overridden in derived class
4302 return CalculateChildSizeBase( child, dimension );
4305 float Actor::GetHeightForWidth( float width )
4307 // Can be overridden in derived class
4308 return GetHeightForWidthBase( width );
4311 float Actor::GetWidthForHeight( float height )
4313 // Can be overridden in derived class
4314 return GetWidthForHeightBase( height );
4317 float Actor::GetLatestSize( Dimension::Type dimension ) const
4319 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4322 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4324 Vector2 padding = GetPadding( dimension );
4326 return GetLatestSize( dimension ) + padding.x + padding.y;
4329 float Actor::NegotiateFromParent( Dimension::Type dimension )
4331 Actor* parent = GetParent();
4334 Vector2 padding( GetPadding( dimension ) );
4335 Vector2 parentPadding( parent->GetPadding( dimension ) );
4336 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4342 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4344 float maxDimensionPoint = 0.0f;
4346 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4348 ActorPtr child = GetChildAt( i );
4350 if( !child->RelayoutDependentOnParent( dimension ) )
4352 // Calculate the min and max points that the children range across
4353 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4354 float dimensionSize = child->GetRelayoutSize( dimension );
4355 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4359 return maxDimensionPoint;
4362 float Actor::GetSize( Dimension::Type dimension ) const
4364 return GetDimensionValue( mTargetSize, dimension );
4367 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4369 return GetDimensionValue( GetNaturalSize(), dimension );
4372 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4374 switch( GetResizePolicy( dimension ) )
4376 case ResizePolicy::USE_NATURAL_SIZE:
4378 return GetNaturalSize( dimension );
4381 case ResizePolicy::FIXED:
4383 return GetDimensionValue( GetPreferredSize(), dimension );
4386 case ResizePolicy::USE_ASSIGNED_SIZE:
4388 return GetDimensionValue( maximumSize, dimension );
4391 case ResizePolicy::FILL_TO_PARENT:
4392 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4393 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4395 return NegotiateFromParent( dimension );
4398 case ResizePolicy::FIT_TO_CHILDREN:
4400 return NegotiateFromChildren( dimension );
4403 case ResizePolicy::DIMENSION_DEPENDENCY:
4405 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4408 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4410 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4413 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4415 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4427 return 0.0f; // Default
4430 float Actor::ClampDimension( float size, Dimension::Type dimension )
4432 const float minSize = GetMinimumSize( dimension );
4433 const float maxSize = GetMaximumSize( dimension );
4435 return std::max( minSize, std::min( size, maxSize ) );
4438 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4440 // Check if it needs to be negotiated
4441 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4443 // Check that we havn't gotten into an infinite loop
4444 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4445 bool recursionFound = false;
4446 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4448 if( *it == searchActor )
4450 recursionFound = true;
4455 if( !recursionFound )
4457 // Record the path that we have taken
4458 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4460 // Dimension dependency check
4461 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4463 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4465 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4467 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4471 // Parent dependency check
4472 Actor* parent = GetParent();
4473 if( parent && RelayoutDependentOnParent( dimension ) )
4475 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4478 // Children dependency check
4479 if( RelayoutDependentOnChildren( dimension ) )
4481 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4483 ActorPtr child = GetChildAt( i );
4485 // Only relayout child first if it is not dependent on this actor
4486 if( !child->RelayoutDependentOnParent( dimension ) )
4488 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4493 // For deriving classes
4494 OnCalculateRelayoutSize( dimension );
4496 // All dependencies checked, calculate the size and set negotiated flag
4497 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4499 SetNegotiatedDimension( newSize, dimension );
4500 SetLayoutNegotiated( true, dimension );
4502 // For deriving classes
4503 OnLayoutNegotiated( newSize, dimension );
4505 // This actor has been successfully processed, pop it off the recursion stack
4506 recursionStack.pop_back();
4510 // TODO: Break infinite loop
4511 SetLayoutNegotiated( true, dimension );
4516 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4518 // Negotiate all dimensions that require it
4519 ActorDimensionStack recursionStack;
4521 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4523 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4526 NegotiateDimension( dimension, allocatedSize, recursionStack );
4530 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4532 switch( mRelayoutData->sizeSetPolicy )
4534 case SizeScalePolicy::USE_SIZE_SET:
4539 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4541 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4542 const Vector3 naturalSize = GetNaturalSize();
4543 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4545 const float sizeRatio = size.width / size.height;
4546 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4548 if( naturalSizeRatio < sizeRatio )
4550 return Vector2( naturalSizeRatio * size.height, size.height );
4552 else if( naturalSizeRatio > sizeRatio )
4554 return Vector2( size.width, size.width / naturalSizeRatio );
4565 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4567 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4568 const Vector3 naturalSize = GetNaturalSize();
4569 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4571 const float sizeRatio = size.width / size.height;
4572 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4574 if( naturalSizeRatio < sizeRatio )
4576 return Vector2( size.width, size.width / naturalSizeRatio );
4578 else if( naturalSizeRatio > sizeRatio )
4580 return Vector2( naturalSizeRatio * size.height, size.height );
4599 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4601 // Do the set actor size
4602 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4604 // Adjust for size set policy
4605 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4607 // Lock the flag to stop recursive relayouts on set size
4608 mRelayoutData->insideRelayout = true;
4609 SetSize( negotiatedSize );
4610 mRelayoutData->insideRelayout = false;
4612 // Clear flags for all dimensions
4613 SetLayoutDirty( false );
4615 // Give deriving classes a chance to respond
4616 OnRelayout( negotiatedSize, container );
4618 if( !mOnRelayoutSignal.Empty() )
4620 Dali::Actor handle( this );
4621 mOnRelayoutSignal.Emit( handle );
4625 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4627 // Force a size negotiation for actors that has assigned size during relayout
4628 // This is required as otherwise the flags that force a relayout will not
4629 // necessarilly be set. This will occur if the actor has already been laid out.
4630 // The dirty flags are then cleared. Then if the actor is added back into the
4631 // relayout container afterwards, the dirty flags would still be clear...
4632 // causing a relayout to be skipped. Here we force any actors added to the
4633 // container to be relayed out.
4634 DALI_LOG_TIMER_START( NegSizeTimer1 );
4636 if( GetUseAssignedSize(Dimension::WIDTH ) )
4638 SetLayoutNegotiated( false, Dimension::WIDTH );
4640 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4642 SetLayoutNegotiated( false, Dimension::HEIGHT );
4645 // Do the negotiation
4646 NegotiateDimensions( allocatedSize );
4648 // Set the actor size
4649 SetNegotiatedSize( container );
4651 // Negotiate down to children
4652 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4654 ActorPtr child = GetChildAt( i );
4656 // Forces children that have already been laid out to be relayed out
4657 // if they have assigned size during relayout.
4658 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4660 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4661 child->SetLayoutDirty(true, Dimension::WIDTH);
4664 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4666 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4667 child->SetLayoutDirty(true, Dimension::HEIGHT);
4670 // Only relayout if required
4671 if( child->RelayoutRequired() )
4673 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4676 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4679 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4683 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4685 if( dimension & ( 1 << i ) )
4687 mRelayoutData->useAssignedSize[ i ] = use;
4693 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4695 if ( mRelayoutData )
4697 // If more than one dimension is requested, just return the first one found
4698 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4700 if( dimension & ( 1 << i ) )
4702 return mRelayoutData->useAssignedSize[ i ];
4710 void Actor::RelayoutRequest( Dimension::Type dimension )
4712 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4713 if( relayoutController )
4715 Dali::Actor self( this );
4716 relayoutController->RequestRelayout( self, dimension );
4720 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4724 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4728 void Actor::SetPreferredSize( const Vector2& size )
4730 EnsureRelayoutData();
4732 // If valid width or height, then set the resize policy to FIXED
4733 // A 0 width or height may also be required so if the resize policy has not been changed, i.e. is still set to DEFAULT,
4734 // then change to FIXED as well
4736 if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
4738 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4741 if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
4743 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4746 mRelayoutData->preferredSize = size;
4748 mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
4753 Vector2 Actor::GetPreferredSize() const
4755 if ( mRelayoutData )
4757 return Vector2( mRelayoutData->preferredSize );
4760 return GetDefaultPreferredSize();
4763 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4765 EnsureRelayoutData();
4767 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4769 if( dimension & ( 1 << i ) )
4771 mRelayoutData->minimumSize[ i ] = size;
4778 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4780 if ( mRelayoutData )
4782 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4784 if( dimension & ( 1 << i ) )
4786 return mRelayoutData->minimumSize[ i ];
4791 return 0.0f; // Default
4794 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4796 EnsureRelayoutData();
4798 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4800 if( dimension & ( 1 << i ) )
4802 mRelayoutData->maximumSize[ i ] = size;
4809 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4811 if ( mRelayoutData )
4813 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4815 if( dimension & ( 1 << i ) )
4817 return mRelayoutData->maximumSize[ i ];
4822 return FLT_MAX; // Default
4825 Object* Actor::GetParentObject() const
4830 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4832 if( mVisible != visible )
4834 if( sendMessage == SendMessage::TRUE )
4836 // node is being used in a separate thread; queue a message to set the value & base value
4837 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4842 // Emit the signal on this actor and all its children
4843 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4847 void Actor::SetSiblingOrder( uint32_t order )
4851 ActorContainer& siblings = *(mParent->mChildren);
4852 uint32_t currentOrder = GetSiblingOrder();
4854 if( order != currentOrder )
4860 else if( order < siblings.size() -1 )
4862 if( order > currentOrder )
4864 RaiseAbove( *siblings[order] );
4868 LowerBelow( *siblings[order] );
4879 uint32_t Actor::GetSiblingOrder() const
4885 ActorContainer& siblings = *(mParent->mChildren);
4886 for( std::size_t i = 0; i < siblings.size(); ++i )
4888 if( siblings[i] == this )
4890 order = static_cast<uint32_t>( i );
4899 void Actor::RequestRebuildDepthTree()
4905 mScene->RequestRebuildDepthTree();
4914 ActorContainer& siblings = *(mParent->mChildren);
4915 if( siblings.back() != this ) // If not already at end
4917 for( std::size_t i=0; i<siblings.size(); ++i )
4919 if( siblings[i] == this )
4922 ActorPtr next = siblings[i+1];
4923 siblings[i+1] = this;
4930 Dali::Actor handle( this );
4931 mParent->mChildOrderChangedSignal.Emit( handle );
4933 RequestRebuildDepthTree();
4937 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4945 ActorContainer& siblings = *(mParent->mChildren);
4946 if( siblings.front() != this ) // If not already at beginning
4948 for( std::size_t i=1; i<siblings.size(); ++i )
4950 if( siblings[i] == this )
4952 // Swap with previous
4953 ActorPtr previous = siblings[i-1];
4954 siblings[i-1] = this;
4955 siblings[i] = previous;
4961 Dali::Actor handle( this );
4962 mParent->mChildOrderChangedSignal.Emit( handle );
4964 RequestRebuildDepthTree();
4968 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4972 void Actor::RaiseToTop()
4976 ActorContainer& siblings = *(mParent->mChildren);
4977 if( siblings.back() != this ) // If not already at end
4979 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4980 if( iter != siblings.end() )
4982 siblings.erase(iter);
4983 siblings.push_back(ActorPtr(this));
4987 Dali::Actor handle( this );
4988 mParent->mChildOrderChangedSignal.Emit( handle );
4990 RequestRebuildDepthTree();
4994 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4998 void Actor::LowerToBottom()
5002 ActorContainer& siblings = *(mParent->mChildren);
5003 if( siblings.front() != this ) // If not already at bottom,
5005 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5007 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5008 if( iter != siblings.end() )
5010 siblings.erase(iter);
5011 siblings.insert(siblings.begin(), thisPtr);
5015 Dali::Actor handle( this );
5016 mParent->mChildOrderChangedSignal.Emit( handle );
5018 RequestRebuildDepthTree();
5022 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5026 void Actor::RaiseAbove( Internal::Actor& target )
5030 ActorContainer& siblings = *(mParent->mChildren);
5031 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5033 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5035 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5036 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5037 if( thisIter < targetIter )
5039 siblings.erase(thisIter);
5040 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5041 // invalidate thisIter)
5042 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5044 siblings.insert(targetIter, thisPtr);
5047 Dali::Actor handle( this );
5048 mParent->mChildOrderChangedSignal.Emit( handle );
5050 RequestRebuildDepthTree();
5055 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5059 void Actor::LowerBelow( Internal::Actor& target )
5063 ActorContainer& siblings = *(mParent->mChildren);
5064 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5066 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5068 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5069 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5071 if( thisIter > targetIter )
5073 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5074 siblings.insert(targetIter, thisPtr);
5077 Dali::Actor handle( this );
5078 mParent->mChildOrderChangedSignal.Emit( handle );
5080 RequestRebuildDepthTree();
5085 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5089 void Actor::SetScene( Scene& scene )
5094 Scene& Actor::GetScene() const
5099 void Actor::SetInheritLayoutDirection( bool inherit )
5101 if( mInheritLayoutDirection != inherit )
5103 mInheritLayoutDirection = inherit;
5105 if( inherit && mParent )
5107 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5112 bool Actor::IsLayoutDirectionInherited() const
5114 return mInheritLayoutDirection;
5117 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5119 if( actor && ( actor->mInheritLayoutDirection || set ) )
5121 if( actor->mLayoutDirection != direction )
5123 actor->mLayoutDirection = direction;
5124 actor->EmitLayoutDirectionChangedSignal( direction );
5125 actor->RelayoutRequest();
5128 if( actor->GetChildCount() > 0 )
5130 ActorContainer& children = actor->GetChildrenInternal();
5131 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5133 InheritLayoutDirectionRecursively( *iter, direction );
5139 } // namespace Internal