2 * Copyright (c) 2018 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/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/common/animatable-property.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/nodes/node-declarations.h>
51 #include <dali/internal/update/animation/scene-graph-constraint.h>
52 #include <dali/internal/event/events/actor-gesture-data.h>
53 #include <dali/internal/common/message.h>
54 #include <dali/integration-api/debug.h>
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::PropertyBase;
60 #if defined(DEBUG_ENABLED)
61 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
62 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
73 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
74 inline const Vector3& GetDefaultSizeModeFactor()
79 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
80 inline const Vector2& GetDefaultPreferredSize()
85 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
86 inline const Vector2& GetDefaultDimensionPadding()
91 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
93 } // unnamed namespace
96 * Struct to collect relayout variables
98 struct Actor::RelayoutData
101 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
103 // Set size negotiation defaults
104 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
106 resizePolicies[ i ] = ResizePolicy::DEFAULT;
107 useAssignedSize[ i ] = false;
108 negotiatedDimensions[ i ] = 0.0f;
109 dimensionNegotiated[ i ] = false;
110 dimensionDirty[ i ] = false;
111 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
112 dimensionPadding[ i ] = GetDefaultDimensionPadding();
113 minimumSize[ i ] = 0.0f;
114 maximumSize[ i ] = FLT_MAX;
118 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
119 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
121 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
123 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
125 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
127 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
128 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
130 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
131 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
133 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
135 Vector2 preferredSize; ///< The preferred size of the actor
137 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
139 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
140 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
143 namespace // unnamed namespace
149 * We want to discourage the use of property strings (minimize string comparisons),
150 * particularly for the default properties.
151 * Name Type writable animatable constraint-input enum for index-checking
153 DALI_PROPERTY_TABLE_BEGIN
154 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
155 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
156 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
157 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
158 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
159 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
160 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
161 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
162 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
163 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
164 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
165 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
166 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
167 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
168 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
169 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
170 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
171 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
172 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
173 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
174 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
175 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
176 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
177 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
178 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
179 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
180 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
181 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
182 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
183 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
184 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
185 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
186 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
187 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
188 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
189 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
190 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
191 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
192 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
193 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
194 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
195 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
196 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
197 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
198 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
199 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
200 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
201 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
202 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
203 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
204 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
205 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
206 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
207 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
208 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
209 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
210 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
211 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
212 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
213 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
214 DALI_PROPERTY( "culled", BOOLEAN, false, false, true, Dali::DevelActor::Property::CULLED )
215 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
219 const char* const SIGNAL_TOUCHED = "touched";
220 const char* const SIGNAL_HOVERED = "hovered";
221 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
222 const char* const SIGNAL_ON_STAGE = "onStage";
223 const char* const SIGNAL_OFF_STAGE = "offStage";
224 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
225 const char* const SIGNAL_TOUCH = "touch";
226 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
227 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
228 const char* const SIGNAL_CHILD_ADDED = "childAdded";
229 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
233 const char* const ACTION_SHOW = "show";
234 const char* const ACTION_HIDE = "hide";
236 BaseHandle CreateActor()
238 return Dali::Actor::New();
241 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
243 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
244 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
245 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
247 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
248 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
249 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
250 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
251 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
255 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
256 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
261 const Vector3& value;
264 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
265 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
266 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
267 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
268 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
269 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
270 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
274 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
276 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
277 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
278 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
279 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
280 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
281 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
283 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
284 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
285 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
286 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
287 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
288 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
290 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
294 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
296 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
299 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
300 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
305 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
307 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
310 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
311 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
313 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
315 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
316 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
318 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
319 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
320 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
321 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
323 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
325 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
327 uint32_t sizeIgnored = 0;
328 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
330 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
337 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
339 // Values are the same so just use the same table as anchor-point
340 return GetAnchorPointConstant( value, parentOrigin );
344 * @brief Extract a given dimension from a Vector2
346 * @param[in] values The values to extract from
347 * @param[in] dimension The dimension to extract
348 * @return Return the value for the dimension
350 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
354 case Dimension::WIDTH:
358 case Dimension::HEIGHT:
360 return values.height;
371 * @brief Extract a given dimension from a Vector3
373 * @param[in] values The values to extract from
374 * @param[in] dimension The dimension to extract
375 * @return Return the value for the dimension
377 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
379 return GetDimensionValue( values.GetVectorXY(), dimension );
383 * @brief Recursively emits the visibility-changed-signal on the actor tree.
384 * @param[in] actor The actor to emit the signal on
385 * @param[in] visible The new visibility of the actor
386 * @param[in] type Whether the actor's visible property has changed or a parent's
388 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
392 actor->EmitVisibilityChangedSignal( visible, type );
394 if( actor->GetChildCount() > 0 )
396 ActorContainer& children = actor->GetChildrenInternal();
397 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
399 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
405 } // unnamed namespace
407 ActorPtr Actor::New()
409 // pass a reference to actor, actor does not own its node
410 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
412 // Second-phase construction
418 const SceneGraph::Node* Actor::CreateNode()
420 // create node. Nodes are owned by the update manager
421 SceneGraph::Node* node = SceneGraph::Node::New();
422 OwnerPointer< SceneGraph::Node > transferOwnership( node );
423 AddNodeMessage( Stage::GetCurrent()->GetUpdateManager(), transferOwnership );
428 const std::string& Actor::GetName() const
433 void Actor::SetName( const std::string& name )
437 // ATTENTION: string for debug purposes is not thread safe.
438 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &mNode ), name );
441 uint32_t Actor::GetId() const
443 return mNode.GetId();
446 bool Actor::OnStage() const
451 Dali::Layer Actor::GetLayer()
455 // Short-circuit for Layer derived actors
458 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
461 // Find the immediate Layer parent
462 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
464 if( parent->IsLayer() )
466 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
473 void Actor::Add( Actor& child )
475 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
476 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
480 mChildren = new ActorContainer;
483 Actor* const oldParent( child.mParent );
485 // child might already be ours
486 if( this != oldParent )
488 // if we already have parent, unparent us first
491 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
493 // Old parent may need to readjust to missing child
494 if( oldParent->RelayoutDependentOnChildren() )
496 oldParent->RelayoutRequest();
500 // Guard against Add() during previous OnChildRemove callback
503 // Do this first, since user callbacks from within SetParent() may need to remove child
504 mChildren->push_back( ActorPtr( &child ) );
506 // SetParent asserts that child can be added
507 child.SetParent( this );
509 // Notification for derived classes
511 EmitChildAddedSignal( child );
513 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
515 // Only put in a relayout request if there is a suitable dependency
516 if( RelayoutDependentOnChildren() )
524 void Actor::Remove( Actor& child )
526 if( (this == &child) || (!mChildren) )
528 // no children or removing itself
534 // Find the child in mChildren, and unparent it
535 ActorIter end = mChildren->end();
536 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
538 ActorPtr actor = (*iter);
540 if( actor.Get() == &child )
542 // Keep handle for OnChildRemove notification
545 // Do this first, since user callbacks from within SetParent() may need to add the child
546 mChildren->erase( iter );
548 DALI_ASSERT_DEBUG( actor->GetParent() == this );
549 actor->SetParent( NULL );
557 // Only put in a relayout request if there is a suitable dependency
558 if( RelayoutDependentOnChildren() )
564 // Notification for derived classes
565 OnChildRemove( child );
566 EmitChildRemovedSignal( child );
569 void Actor::Unparent()
573 // Remove this actor from the parent. The remove will put a relayout request in for
574 // the parent if required
575 mParent->Remove( *this );
576 // mParent is now NULL!
580 uint32_t Actor::GetChildCount() const
582 return ( NULL != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
585 ActorPtr Actor::GetChildAt( uint32_t index ) const
587 DALI_ASSERT_ALWAYS( index < GetChildCount() );
589 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
592 ActorPtr Actor::FindChildByName( const std::string& actorName )
595 if( actorName == mName )
601 ActorIter end = mChildren->end();
602 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
604 child = (*iter)->FindChildByName( actorName );
615 ActorPtr Actor::FindChildById( const uint32_t id )
624 ActorIter end = mChildren->end();
625 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
627 child = (*iter)->FindChildById( id );
638 void Actor::SetParentOrigin( const Vector3& origin )
640 // mNode is being used in a separate thread; queue a message to set the value & base value
641 SetParentOriginMessage( GetEventThreadServices(), mNode, origin );
643 // Cache for event-thread access
646 // not allocated, check if different from default
647 if( ParentOrigin::DEFAULT != origin )
649 mParentOrigin = new Vector3( origin );
654 // check if different from current costs more than just set
655 *mParentOrigin = origin;
659 void Actor::SetParentOriginX( float x )
661 const Vector3& current = GetCurrentParentOrigin();
663 SetParentOrigin( Vector3( x, current.y, current.z ) );
666 void Actor::SetParentOriginY( float y )
668 const Vector3& current = GetCurrentParentOrigin();
670 SetParentOrigin( Vector3( current.x, y, current.z ) );
673 void Actor::SetParentOriginZ( float z )
675 const Vector3& current = GetCurrentParentOrigin();
677 SetParentOrigin( Vector3( current.x, current.y, z ) );
680 const Vector3& Actor::GetCurrentParentOrigin() const
682 // Cached for event-thread access
683 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
686 void Actor::SetAnchorPoint( const Vector3& anchor )
688 // mNode is being used in a separate thread; queue a message to set the value & base value
689 SetAnchorPointMessage( GetEventThreadServices(), mNode, anchor );
691 // Cache for event-thread access
694 // not allocated, check if different from default
695 if( AnchorPoint::DEFAULT != anchor )
697 mAnchorPoint = new Vector3( anchor );
702 // check if different from current costs more than just set
703 *mAnchorPoint = anchor;
707 void Actor::SetAnchorPointX( float x )
709 const Vector3& current = GetCurrentAnchorPoint();
711 SetAnchorPoint( Vector3( x, current.y, current.z ) );
714 void Actor::SetAnchorPointY( float y )
716 const Vector3& current = GetCurrentAnchorPoint();
718 SetAnchorPoint( Vector3( current.x, y, current.z ) );
721 void Actor::SetAnchorPointZ( float z )
723 const Vector3& current = GetCurrentAnchorPoint();
725 SetAnchorPoint( Vector3( current.x, current.y, z ) );
728 const Vector3& Actor::GetCurrentAnchorPoint() const
730 // Cached for event-thread access
731 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
734 void Actor::SetPosition( float x, float y )
736 SetPosition( Vector3( x, y, 0.0f ) );
739 void Actor::SetPosition( float x, float y, float z )
741 SetPosition( Vector3( x, y, z ) );
744 void Actor::SetPosition( const Vector3& position )
746 mTargetPosition = position;
748 // mNode is being used in a separate thread; queue a message to set the value & base value
749 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
752 void Actor::SetX( float x )
754 mTargetPosition.x = x;
756 // mNode is being used in a separate thread; queue a message to set the value & base value
757 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
760 void Actor::SetY( float y )
762 mTargetPosition.y = y;
764 // mNode is being used in a separate thread; queue a message to set the value & base value
765 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
768 void Actor::SetZ( float z )
770 mTargetPosition.z = z;
772 // mNode is being used in a separate thread; queue a message to set the value & base value
773 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
776 void Actor::TranslateBy( const Vector3& distance )
778 mTargetPosition += distance;
780 // mNode is being used in a separate thread; queue a message to set the value & base value
781 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
784 const Vector3& Actor::GetCurrentPosition() const
786 // mNode is being used in a separate thread; copy the value from the previous update
787 return mNode.GetPosition(GetEventThreadServices().GetEventBufferIndex());
790 const Vector3& Actor::GetTargetPosition() const
792 return mTargetPosition;
795 const Vector3& Actor::GetCurrentWorldPosition() const
797 // mNode is being used in a separate thread; copy the value from the previous update
798 return mNode.GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
801 const Vector2 Actor::GetCurrentScreenPosition() const
803 StagePtr stage = Stage::GetCurrent();
804 if( stage && OnStage() )
806 Vector3 worldPosition = mNode.GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
807 Vector3 cameraPosition = stage->GetDefaultCameraActor().mNode.GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
808 worldPosition -= cameraPosition;
810 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
811 Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
812 Vector3 halfActorSize( actorSize * 0.5f );
813 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
815 return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
816 halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
819 return Vector2::ZERO;
822 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
824 // this flag is not animatable so keep the value
825 mPositionInheritanceMode = mode;
826 // mNode is being used in a separate thread; queue a message to set the value
827 SetInheritPositionMessage( GetEventThreadServices(), mNode, mode == INHERIT_PARENT_POSITION );
830 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
832 // Cached for event-thread access
833 return mPositionInheritanceMode;
836 void Actor::SetInheritPosition( bool inherit )
838 if( mInheritPosition != inherit )
840 // non animateable so keep local copy
841 mInheritPosition = inherit;
842 SetInheritPositionMessage( GetEventThreadServices(), mNode, inherit );
846 bool Actor::IsPositionInherited() const
848 return mInheritPosition;
851 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
853 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
854 normalizedAxis.Normalize();
856 Quaternion orientation( angle, normalizedAxis );
858 SetOrientation( orientation );
861 void Actor::SetOrientation( const Quaternion& orientation )
863 mTargetOrientation = orientation;
865 // mNode is being used in a separate thread; queue a message to set the value & base value
866 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &mNode, &mNode.mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
869 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
871 RotateBy( Quaternion(angle, axis) );
874 void Actor::RotateBy( const Quaternion& relativeRotation )
876 mTargetOrientation *= Quaternion( relativeRotation );
878 // mNode is being used in a separate thread; queue a message to set the value & base value
879 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &mNode, &mNode.mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
882 const Quaternion& Actor::GetCurrentOrientation() const
884 // mNode is being used in a separate thread; copy the value from the previous update
885 return mNode.GetOrientation(GetEventThreadServices().GetEventBufferIndex());
888 const Quaternion& Actor::GetCurrentWorldOrientation() const
890 // mNode is being used in a separate thread; copy the value from the previous update
891 return mNode.GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
894 void Actor::SetScale( float scale )
896 SetScale( Vector3( scale, scale, scale ) );
899 void Actor::SetScale( float x, float y, float z )
901 SetScale( Vector3( x, y, z ) );
904 void Actor::SetScale( const Vector3& scale )
906 mTargetScale = scale;
908 // mNode is being used in a separate thread; queue a message to set the value & base value
909 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
912 void Actor::SetScaleX( float x )
916 // mNode is being used in a separate thread; queue a message to set the value & base value
917 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
920 void Actor::SetScaleY( float y )
924 // mNode is being used in a separate thread; queue a message to set the value & base value
925 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
928 void Actor::SetScaleZ( float z )
932 // mNode is being used in a separate thread; queue a message to set the value & base value
933 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
936 void Actor::ScaleBy(const Vector3& relativeScale)
938 mTargetScale *= relativeScale;
940 // mNode is being used in a separate thread; queue a message to set the value & base value
941 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
944 const Vector3& Actor::GetCurrentScale() const
946 // mNode is being used in a separate thread; copy the value from the previous update
947 return mNode.GetScale(GetEventThreadServices().GetEventBufferIndex());
950 const Vector3& Actor::GetCurrentWorldScale() const
952 // mNode is being used in a separate thread; copy the value from the previous update
953 return mNode.GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
956 void Actor::SetInheritScale( bool inherit )
958 if( mInheritScale != inherit )
960 // non animateable so keep local copy
961 mInheritScale = inherit;
962 // mNode is being used in a separate thread; queue a message to set the value
963 SetInheritScaleMessage( GetEventThreadServices(), mNode, inherit );
967 bool Actor::IsScaleInherited() const
969 return mInheritScale;
972 Matrix Actor::GetCurrentWorldMatrix() const
974 return mNode.GetWorldMatrix(0);
977 void Actor::SetVisible( bool visible )
979 SetVisibleInternal( visible, SendMessage::TRUE );
982 bool Actor::IsVisible() const
984 // mNode is being used in a separate thread; copy the value from the previous update
985 return mNode.IsVisible( GetEventThreadServices().GetEventBufferIndex() );
988 void Actor::SetOpacity( float opacity )
990 mTargetColor.a = opacity;
992 // mNode is being used in a separate thread; queue a message to set the value & base value
993 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &mNode, &mNode.mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
996 float Actor::GetCurrentOpacity() const
998 // mNode is being used in a separate thread; copy the value from the previous update
999 return mNode.GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1002 ClippingMode::Type Actor::GetClippingMode() const
1004 return mClippingMode;
1007 uint32_t Actor::GetSortingDepth()
1009 return mSortedDepth;
1012 const Vector4& Actor::GetCurrentWorldColor() const
1014 return mNode.GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1017 void Actor::SetColor( const Vector4& color )
1019 mTargetColor = color;
1021 // mNode is being used in a separate thread; queue a message to set the value & base value
1022 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &mNode, &mNode.mColor, &AnimatableProperty<Vector4>::Bake, color );
1025 void Actor::SetColorRed( float red )
1027 mTargetColor.r = red;
1029 // mNode is being used in a separate thread; queue a message to set the value & base value
1030 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &mNode, &mNode.mColor, &AnimatableProperty<Vector4>::BakeX, red );
1033 void Actor::SetColorGreen( float green )
1035 mTargetColor.g = green;
1037 // mNode is being used in a separate thread; queue a message to set the value & base value
1038 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &mNode, &mNode.mColor, &AnimatableProperty<Vector4>::BakeY, green );
1041 void Actor::SetColorBlue( float blue )
1043 mTargetColor.b = blue;
1045 // mNode is being used in a separate thread; queue a message to set the value & base value
1046 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &mNode, &mNode.mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1049 const Vector4& Actor::GetCurrentColor() const
1051 // mNode is being used in a separate thread; copy the value from the previous update
1052 return mNode.GetColor(GetEventThreadServices().GetEventBufferIndex());
1055 void Actor::SetInheritOrientation( bool inherit )
1057 if( mInheritOrientation != inherit )
1059 // non animateable so keep local copy
1060 mInheritOrientation = inherit;
1061 // mNode is being used in a separate thread; queue a message to set the value
1062 SetInheritOrientationMessage( GetEventThreadServices(), mNode, inherit );
1066 bool Actor::IsOrientationInherited() const
1068 return mInheritOrientation;
1071 void Actor::SetSizeModeFactor( const Vector3& factor )
1073 EnsureRelayoutData();
1075 mRelayoutData->sizeModeFactor = factor;
1078 const Vector3& Actor::GetSizeModeFactor() const
1080 if ( mRelayoutData )
1082 return mRelayoutData->sizeModeFactor;
1085 return GetDefaultSizeModeFactor();
1088 void Actor::SetColorMode( ColorMode colorMode )
1090 // non animateable so keep local copy
1091 mColorMode = colorMode;
1092 // mNode is being used in a separate thread; queue a message to set the value
1093 SetColorModeMessage( GetEventThreadServices(), mNode, colorMode );
1096 ColorMode Actor::GetColorMode() const
1098 // we have cached copy
1102 void Actor::SetSize( float width, float height )
1104 SetSize( Vector2( width, height ) );
1107 void Actor::SetSize( float width, float height, float depth )
1109 SetSize( Vector3( width, height, depth ) );
1112 void Actor::SetSize( const Vector2& size )
1114 SetSize( Vector3( size.width, size.height, 0.f ) );
1117 void Actor::SetSizeInternal( const Vector2& size )
1119 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1122 void Actor::SetSize( const Vector3& size )
1124 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1126 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1127 SetPreferredSize( size.GetVectorXY() );
1131 SetSizeInternal( size );
1135 void Actor::SetSizeInternal( const Vector3& size )
1137 // dont allow recursive loop
1138 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1139 // 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
1140 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1141 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1142 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1146 // mNode is being used in a separate thread; queue a message to set the value & base value
1147 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1149 // Notification for derived classes
1150 mInsideOnSizeSet = true;
1151 OnSizeSet( mTargetSize );
1152 mInsideOnSizeSet = false;
1154 // Raise a relayout request if the flag is not locked
1155 if( mRelayoutData && !mRelayoutData->insideRelayout )
1162 void Actor::SetWidth( float width )
1164 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1166 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1167 mRelayoutData->preferredSize.width = width;
1171 mTargetSize.width = width;
1173 // mNode is being used in a separate thread; queue a message to set the value & base value
1174 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1180 void Actor::SetHeight( float height )
1182 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1184 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1185 mRelayoutData->preferredSize.height = height;
1189 mTargetSize.height = height;
1191 // mNode is being used in a separate thread; queue a message to set the value & base value
1192 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1198 void Actor::SetDepth( float depth )
1200 mTargetSize.depth = depth;
1202 // mNode is being used in a separate thread; queue a message to set the value & base value
1203 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, &mNode.mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1206 Vector3 Actor::GetTargetSize() const
1208 Vector3 size = mTargetSize;
1210 // Should return preferred size if size is fixed as set by SetSize
1211 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1213 size.width = GetPreferredSize().width;
1215 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1217 size.height = GetPreferredSize().height;
1223 const Vector3& Actor::GetCurrentSize() const
1225 // mNode is being used in a separate thread; copy the value from the previous update
1226 return mNode.GetSize( GetEventThreadServices().GetEventBufferIndex() );
1229 Vector3 Actor::GetNaturalSize() const
1231 // It is up to deriving classes to return the appropriate natural size
1232 return Vector3( 0.0f, 0.0f, 0.0f );
1235 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1237 EnsureRelayoutData();
1239 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1240 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1242 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1244 if( dimension & ( 1 << i ) )
1246 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1248 mRelayoutData->useAssignedSize[ i ] = true;
1252 mRelayoutData->resizePolicies[ i ] = policy;
1253 mRelayoutData->useAssignedSize[ i ] = false;
1258 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1260 if( dimension & Dimension::WIDTH )
1262 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1265 if( dimension & Dimension::HEIGHT )
1267 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1271 // If calling SetResizePolicy, assume we want relayout enabled
1272 SetRelayoutEnabled( true );
1274 // If the resize policy is set to be FIXED, the preferred size
1275 // should be overrided by the target size. Otherwise the target
1276 // size should be overrided by the preferred size.
1278 if( dimension & Dimension::WIDTH )
1280 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1282 mRelayoutData->preferredSize.width = mTargetSize.width;
1284 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1286 mTargetSize.width = mRelayoutData->preferredSize.width;
1290 if( dimension & Dimension::HEIGHT )
1292 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1294 mRelayoutData->preferredSize.height = mTargetSize.height;
1296 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1298 mTargetSize.height = mRelayoutData->preferredSize.height;
1302 OnSetResizePolicy( policy, dimension );
1304 // Trigger relayout on this control
1308 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1310 if ( mRelayoutData )
1312 // If more than one dimension is requested, just return the first one found
1313 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1315 if( ( dimension & ( 1 << i ) ) )
1317 if( mRelayoutData->useAssignedSize[ i ] )
1319 return ResizePolicy::USE_ASSIGNED_SIZE;
1323 return mRelayoutData->resizePolicies[ i ];
1329 return ResizePolicy::DEFAULT;
1332 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1334 EnsureRelayoutData();
1336 mRelayoutData->sizeSetPolicy = policy;
1339 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1341 if ( mRelayoutData )
1343 return mRelayoutData->sizeSetPolicy;
1346 return DEFAULT_SIZE_SCALE_POLICY;
1349 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1351 EnsureRelayoutData();
1353 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1355 if( dimension & ( 1 << i ) )
1357 mRelayoutData->dimensionDependencies[ i ] = dependency;
1362 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1364 if ( mRelayoutData )
1366 // If more than one dimension is requested, just return the first one found
1367 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1369 if( ( dimension & ( 1 << i ) ) )
1371 return mRelayoutData->dimensionDependencies[ i ];
1376 return Dimension::ALL_DIMENSIONS; // Default
1379 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1381 // If relayout data has not been allocated yet and the client is requesting
1382 // to disable it, do nothing
1383 if( mRelayoutData || relayoutEnabled )
1385 EnsureRelayoutData();
1387 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1389 mRelayoutData->relayoutEnabled = relayoutEnabled;
1393 bool Actor::IsRelayoutEnabled() const
1395 // Assume that if relayout data has not been allocated yet then
1396 // relayout is disabled
1397 return mRelayoutData && mRelayoutData->relayoutEnabled;
1400 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1402 EnsureRelayoutData();
1404 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1406 if( dimension & ( 1 << i ) )
1408 mRelayoutData->dimensionDirty[ i ] = dirty;
1413 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1415 if ( mRelayoutData )
1417 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1419 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1429 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1431 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1434 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1436 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1439 uint32_t Actor::AddRenderer( Renderer& renderer )
1443 mRenderers = new RendererContainer;
1446 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1447 RendererPtr rendererPtr = RendererPtr( &renderer );
1448 mRenderers->push_back( rendererPtr );
1449 AddRendererMessage( GetEventThreadServices(), mNode, renderer.GetRendererSceneObject() );
1453 uint32_t Actor::GetRendererCount() const
1455 uint32_t rendererCount(0);
1458 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1461 return rendererCount;
1464 RendererPtr Actor::GetRendererAt( uint32_t index )
1466 RendererPtr renderer;
1467 if( index < GetRendererCount() )
1469 renderer = ( *mRenderers )[ index ];
1475 void Actor::RemoveRenderer( Renderer& renderer )
1479 RendererIter end = mRenderers->end();
1480 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1482 if( (*iter).Get() == &renderer )
1484 mRenderers->erase( iter );
1485 RemoveRendererMessage( GetEventThreadServices(), mNode, renderer.GetRendererSceneObject() );
1492 void Actor::RemoveRenderer( uint32_t index )
1494 if( index < GetRendererCount() )
1496 RendererPtr renderer = ( *mRenderers )[ index ];
1497 RemoveRendererMessage( GetEventThreadServices(), mNode, renderer.Get()->GetRendererSceneObject() );
1498 mRenderers->erase( mRenderers->begin()+index );
1502 bool Actor::IsOverlay() const
1504 return ( DrawMode::OVERLAY_2D == mDrawMode );
1507 void Actor::SetDrawMode( DrawMode::Type drawMode )
1509 // this flag is not animatable so keep the value
1510 mDrawMode = drawMode;
1511 if( drawMode != DrawMode::STENCIL )
1513 // mNode is being used in a separate thread; queue a message to set the value
1514 SetDrawModeMessage( GetEventThreadServices(), mNode, drawMode );
1518 DrawMode::Type Actor::GetDrawMode() const
1523 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1525 // only valid when on-stage
1526 StagePtr stage = Stage::GetCurrent();
1527 if( stage && OnStage() )
1529 const RenderTaskList& taskList = stage->GetRenderTaskList();
1531 Vector2 converted( screenX, screenY );
1533 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1534 uint32_t taskCount = taskList.GetTaskCount();
1535 for( uint32_t i = taskCount; i > 0; --i )
1537 Dali::RenderTask task = taskList.GetTask( i - 1 );
1538 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1540 // found a task where this conversion was ok so return
1548 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1550 bool retval = false;
1551 // only valid when on-stage
1554 CameraActor* camera = renderTask.GetCameraActor();
1558 renderTask.GetViewport( viewport );
1560 // need to translate coordinates to render tasks coordinate space
1561 Vector2 converted( screenX, screenY );
1562 if( renderTask.TranslateCoordinates( converted ) )
1564 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1571 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1573 // Early-out if not on stage
1579 // Get the ModelView matrix
1581 Matrix::Multiply( modelView, mNode.GetWorldMatrix(0), viewMatrix );
1583 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1584 Matrix invertedMvp( false/*don't init*/);
1585 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1586 bool success = invertedMvp.Invert();
1588 // Convert to GL coordinates
1589 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1594 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1601 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1607 if( XyPlaneIntersect( nearPos, farPos, local ) )
1609 Vector3 size = GetCurrentSize();
1610 localX = local.x + size.x * 0.5f;
1611 localY = local.y + size.y * 0.5f;
1622 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1625 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1627 Mathematical Formulation
1629 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1631 ( p - c ) dot ( p - c ) = r^2
1633 Given a ray with a point of origin 'o', and a direction vector 'd':
1635 ray(t) = o + td, t >= 0
1637 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1639 (o + td - c ) dot ( o + td - c ) = r^2
1641 To solve for t we first expand the above into a more recognisable quadratic equation form
1643 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1652 B = 2( o - c ) dot d
1653 C = ( o - c ) dot ( o - c ) - r^2
1655 which can be solved using a standard quadratic formula.
1657 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1659 Practical Simplification
1661 In a renderer, we often differentiate between world space and object space. In the object space
1662 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1663 into object space, the mathematical solution presented above can be simplified significantly.
1665 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1669 and we can find the t at which the (transformed) ray intersects the sphere by
1671 ( o + td ) dot ( o + td ) = r^2
1673 According to the reasoning above, we expand the above quadratic equation into the general form
1677 which now has coefficients:
1684 // Early-out if not on stage
1690 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1692 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1693 const Vector3& translation( mNode.GetWorldPosition( bufferIndex ) );
1694 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1696 // Compute the radius is not needed, square radius it's enough.
1697 const Vector3& size( mNode.GetSize( bufferIndex ) );
1699 // Scale the sphere.
1700 const Vector3& scale( mNode.GetWorldScale( bufferIndex ) );
1702 const float width = size.width * scale.width;
1703 const float height = size.height * scale.height;
1705 float squareSphereRadius = 0.5f * ( width * width + height * height );
1707 float a = rayDir.Dot( rayDir ); // a
1708 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1709 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1711 return ( b2 * b2 - a * c ) >= 0.f;
1714 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1720 // Transforms the ray to the local reference system.
1721 // Calculate the inverse of Model matrix
1722 Matrix invModelMatrix( false/*don't init*/);
1724 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1725 invModelMatrix = mNode.GetWorldMatrix(0);
1726 invModelMatrix.Invert();
1728 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1729 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1731 // Test with the actor's XY plane (Normal = 0 0 1 1).
1733 float a = -rayOriginLocal.z;
1734 float b = rayDirLocal.z;
1736 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1738 // Ray travels distance * rayDirLocal to intersect with plane.
1741 const Vector3& size = mNode.GetSize( bufferIndex );
1743 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1744 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1746 // Test with the actor's geometry.
1747 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1754 void Actor::SetLeaveRequired( bool required )
1756 mLeaveRequired = required;
1759 bool Actor::GetLeaveRequired() const
1761 return mLeaveRequired;
1764 void Actor::SetKeyboardFocusable( bool focusable )
1766 mKeyboardFocusable = focusable;
1769 bool Actor::IsKeyboardFocusable() const
1771 return mKeyboardFocusable;
1774 bool Actor::GetTouchRequired() const
1776 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1779 bool Actor::GetHoverRequired() const
1781 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1784 bool Actor::GetWheelEventRequired() const
1786 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1789 bool Actor::IsHittable() const
1791 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1794 ActorGestureData& Actor::GetGestureData()
1796 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1797 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1798 if( NULL == mGestureData )
1800 mGestureData = new ActorGestureData;
1802 return *mGestureData;
1805 bool Actor::IsGestureRequred( Gesture::Type type ) const
1807 return mGestureData && mGestureData->IsGestureRequred( type );
1810 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1812 bool consumed = false;
1814 if( !mTouchSignal.Empty() )
1816 Dali::Actor handle( this );
1817 consumed = mTouchSignal.Emit( handle, touch );
1820 if( !mTouchedSignal.Empty() )
1822 Dali::Actor handle( this );
1823 consumed |= mTouchedSignal.Emit( handle, event );
1828 // Notification for derived classes
1829 consumed = OnTouchEvent( event ); // TODO
1835 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1837 bool consumed = false;
1839 if( !mHoveredSignal.Empty() )
1841 Dali::Actor handle( this );
1842 consumed = mHoveredSignal.Emit( handle, event );
1847 // Notification for derived classes
1848 consumed = OnHoverEvent( event );
1854 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1856 bool consumed = false;
1858 if( !mWheelEventSignal.Empty() )
1860 Dali::Actor handle( this );
1861 consumed = mWheelEventSignal.Emit( handle, event );
1866 // Notification for derived classes
1867 consumed = OnWheelEvent( event );
1873 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1875 if( ! mVisibilityChangedSignal.Empty() )
1877 Dali::Actor handle( this );
1878 mVisibilityChangedSignal.Emit( handle, visible, type );
1882 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1884 if( ! mLayoutDirectionChangedSignal.Empty() )
1886 Dali::Actor handle( this );
1887 mLayoutDirectionChangedSignal.Emit( handle, type );
1891 void Actor::EmitChildAddedSignal( Actor& child )
1893 if( ! mChildAddedSignal.Empty() )
1895 Dali::Actor handle( &child );
1896 mChildAddedSignal.Emit( handle );
1900 void Actor::EmitChildRemovedSignal( Actor& child )
1902 if( ! mChildRemovedSignal.Empty() )
1904 Dali::Actor handle( &child );
1905 mChildRemovedSignal.Emit( handle );
1909 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1911 return mTouchedSignal;
1914 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1916 return mTouchSignal;
1919 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1921 return mHoveredSignal;
1924 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1926 return mWheelEventSignal;
1929 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1931 return mOnStageSignal;
1934 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1936 return mOffStageSignal;
1939 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1941 return mOnRelayoutSignal;
1944 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1946 return mVisibilityChangedSignal;
1949 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1951 return mLayoutDirectionChangedSignal;
1954 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1956 return mChildAddedSignal;
1959 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1961 return mChildRemovedSignal;
1964 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1966 return mChildOrderChangedSignal;
1969 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1971 bool connected( true );
1972 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1974 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1976 actor->TouchedSignal().Connect( tracker, functor );
1978 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1980 actor->HoveredSignal().Connect( tracker, functor );
1982 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1984 actor->WheelEventSignal().Connect( tracker, functor );
1986 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1988 actor->OnStageSignal().Connect( tracker, functor );
1990 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1992 actor->OffStageSignal().Connect( tracker, functor );
1994 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1996 actor->OnRelayoutSignal().Connect( tracker, functor );
1998 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2000 actor->TouchSignal().Connect( tracker, functor );
2002 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
2004 actor->VisibilityChangedSignal().Connect( tracker, functor );
2006 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2008 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2010 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2012 actor->ChildAddedSignal().Connect( tracker, functor );
2014 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2016 actor->ChildRemovedSignal().Connect( tracker, functor );
2020 // signalName does not match any signal
2027 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2032 mParentOrigin( NULL ),
2033 mAnchorPoint( NULL ),
2034 mRelayoutData( NULL ),
2035 mGestureData( NULL ),
2039 mWheelEventSignal(),
2042 mOnRelayoutSignal(),
2043 mVisibilityChangedSignal(),
2044 mLayoutDirectionChangedSignal(),
2045 mChildAddedSignal(),
2046 mChildRemovedSignal(),
2047 mChildOrderChangedSignal(),
2048 mTargetOrientation( Quaternion::IDENTITY ),
2049 mTargetColor( Color::WHITE ),
2050 mTargetSize( Vector3::ZERO ),
2051 mTargetPosition( Vector3::ZERO ),
2052 mTargetScale( Vector3::ONE ),
2056 mIsRoot( ROOT_LAYER == derivedType ),
2057 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2058 mIsOnStage( false ),
2060 mLeaveRequired( false ),
2061 mKeyboardFocusable( false ),
2062 mDerivedRequiresTouch( false ),
2063 mDerivedRequiresHover( false ),
2064 mDerivedRequiresWheelEvent( false ),
2065 mOnStageSignalled( false ),
2066 mInsideOnSizeSet( false ),
2067 mInheritPosition( true ),
2068 mInheritOrientation( true ),
2069 mInheritScale( true ),
2070 mPositionUsesAnchorPoint( true ),
2072 mInheritLayoutDirection( true ),
2073 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2074 mDrawMode( DrawMode::NORMAL ),
2075 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2076 mColorMode( Node::DEFAULT_COLOR_MODE ),
2077 mClippingMode( ClippingMode::DISABLED )
2081 void Actor::Initialize()
2085 GetEventThreadServices().RegisterObject( this );
2090 // Remove mParent pointers from children even if we're destroying core,
2091 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2094 ActorConstIter endIter = mChildren->end();
2095 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2097 (*iter)->SetParent( NULL );
2103 // Guard to allow handle destruction after Core has been destroyed
2104 if( EventThreadServices::IsCoreRunning() )
2106 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), mNode );
2108 GetEventThreadServices().UnregisterObject( this );
2111 // Cleanup optional gesture data
2112 delete mGestureData;
2114 // Cleanup optional parent origin and anchor
2115 delete mParentOrigin;
2116 delete mAnchorPoint;
2118 // Delete optional relayout data
2119 delete mRelayoutData;
2122 void Actor::ConnectToStage( uint32_t parentDepth )
2124 // This container is used instead of walking the Actor hierarchy.
2125 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2126 ActorContainer connectionList;
2128 StagePtr stage = Stage::GetCurrent();
2131 stage->RequestRebuildDepthTree();
2134 // This stage is atomic i.e. not interrupted by user callbacks.
2135 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2137 // Notify applications about the newly connected actors.
2138 const ActorIter endIter = connectionList.end();
2139 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2141 (*iter)->NotifyStageConnection();
2147 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2149 DALI_ASSERT_ALWAYS( !OnStage() );
2152 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2154 ConnectToSceneGraph();
2156 // Notification for internal derived classes
2157 OnStageConnectionInternal();
2159 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2160 connectionList.push_back( ActorPtr( this ) );
2162 // Recursively connect children
2165 ActorConstIter endIter = mChildren->end();
2166 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2168 (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2174 * This method is called when the Actor is connected to the Stage.
2175 * The parent must have added its Node to the scene-graph.
2176 * The child must connect its Node to the parent's Node.
2177 * This is recursive; the child calls ConnectToStage() for its children.
2179 void Actor::ConnectToSceneGraph()
2181 DALI_ASSERT_DEBUG( mParent != NULL);
2183 // Reparent Node in next Update
2184 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->mNode, mNode );
2186 // Request relayout on all actors that are added to the scenegraph
2189 // Notification for Object::Observers
2193 void Actor::NotifyStageConnection()
2195 // Actors can be removed (in a callback), before the on-stage stage is reported.
2196 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2197 if( OnStage() && !mOnStageSignalled )
2199 // Notification for external (CustomActor) derived classes
2200 OnStageConnectionExternal( mDepth );
2202 if( !mOnStageSignal.Empty() )
2204 Dali::Actor handle( this );
2205 mOnStageSignal.Emit( handle );
2208 // Guard against Remove during callbacks
2211 mOnStageSignalled = true; // signal required next time Actor is removed
2216 void Actor::DisconnectFromStage()
2218 // This container is used instead of walking the Actor hierachy.
2219 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2220 ActorContainer disconnectionList;
2222 StagePtr stage = Stage::GetCurrent();
2225 stage->RequestRebuildDepthTree();
2228 // This stage is atomic i.e. not interrupted by user callbacks
2229 RecursiveDisconnectFromStage( disconnectionList );
2231 // Notify applications about the newly disconnected actors.
2232 const ActorIter endIter = disconnectionList.end();
2233 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2235 (*iter)->NotifyStageDisconnection();
2239 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2241 DALI_ASSERT_ALWAYS( OnStage() );
2243 // Recursively disconnect children
2246 ActorConstIter endIter = mChildren->end();
2247 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2249 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2253 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2254 disconnectionList.push_back( ActorPtr( this ) );
2256 // Notification for internal derived classes
2257 OnStageDisconnectionInternal();
2259 DisconnectFromSceneGraph();
2265 * This method is called by an actor or its parent, before a node removal message is sent.
2266 * This is recursive; the child calls DisconnectFromStage() for its children.
2268 void Actor::DisconnectFromSceneGraph()
2270 // Notification for Object::Observers
2271 OnSceneObjectRemove();
2274 void Actor::NotifyStageDisconnection()
2276 // Actors can be added (in a callback), before the off-stage state is reported.
2277 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2278 // only do this step if there is a stage, i.e. Core is not being shut down
2279 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2281 // Notification for external (CustomeActor) derived classes
2282 OnStageDisconnectionExternal();
2284 if( !mOffStageSignal.Empty() )
2286 Dali::Actor handle( this );
2287 mOffStageSignal.Emit( handle );
2290 // Guard against Add during callbacks
2293 mOnStageSignalled = false; // signal required next time Actor is added
2298 bool Actor::IsNodeConnected() const
2300 bool connected( false );
2304 if( IsRoot() || mNode.GetParent() )
2313 // This method initiates traversal of the actor tree using depth-first
2314 // traversal to set a depth index based on traversal order. It sends a
2315 // single message to update manager to update all the actor's nodes in
2316 // this tree with the depth index. The sceneGraphNodeDepths vector's
2317 // elements are ordered by depth, and could be used to reduce sorting
2318 // in the update thread.
2319 void Actor::RebuildDepthTree()
2321 DALI_LOG_TIMER_START(depthTimer);
2323 // Vector of scene-graph nodes and their depths to send to UpdateManager
2324 // in a single message
2325 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2327 int32_t depthIndex = 1;
2328 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2330 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2331 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2334 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2336 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2337 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &mNode ), mSortedDepth );
2339 // Create/add to children of this node
2342 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2344 Actor* childActor = (*it).Get();
2346 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2351 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2355 case Dali::Actor::Property::PARENT_ORIGIN:
2357 Property::Type type = property.GetType();
2358 if( type == Property::VECTOR3 )
2360 SetParentOrigin( property.Get< Vector3 >() );
2362 else if ( type == Property::STRING )
2364 std::string parentOriginString;
2365 property.Get( parentOriginString );
2366 Vector3 parentOrigin;
2367 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2369 SetParentOrigin( parentOrigin );
2375 case Dali::Actor::Property::PARENT_ORIGIN_X:
2377 SetParentOriginX( property.Get< float >() );
2381 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2383 SetParentOriginY( property.Get< float >() );
2387 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2389 SetParentOriginZ( property.Get< float >() );
2393 case Dali::Actor::Property::ANCHOR_POINT:
2395 Property::Type type = property.GetType();
2396 if( type == Property::VECTOR3 )
2398 SetAnchorPoint( property.Get< Vector3 >() );
2400 else if ( type == Property::STRING )
2402 std::string anchorPointString;
2403 property.Get( anchorPointString );
2405 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2407 SetAnchorPoint( anchor );
2413 case Dali::Actor::Property::ANCHOR_POINT_X:
2415 SetAnchorPointX( property.Get< float >() );
2419 case Dali::Actor::Property::ANCHOR_POINT_Y:
2421 SetAnchorPointY( property.Get< float >() );
2425 case Dali::Actor::Property::ANCHOR_POINT_Z:
2427 SetAnchorPointZ( property.Get< float >() );
2431 case Dali::Actor::Property::SIZE:
2433 SetSize( property.Get< Vector3 >() );
2437 case Dali::Actor::Property::SIZE_WIDTH:
2439 SetWidth( property.Get< float >() );
2443 case Dali::Actor::Property::SIZE_HEIGHT:
2445 SetHeight( property.Get< float >() );
2449 case Dali::Actor::Property::SIZE_DEPTH:
2451 SetDepth( property.Get< float >() );
2455 case Dali::Actor::Property::POSITION:
2457 SetPosition( property.Get< Vector3 >() );
2461 case Dali::Actor::Property::POSITION_X:
2463 SetX( property.Get< float >() );
2467 case Dali::Actor::Property::POSITION_Y:
2469 SetY( property.Get< float >() );
2473 case Dali::Actor::Property::POSITION_Z:
2475 SetZ( property.Get< float >() );
2479 case Dali::Actor::Property::ORIENTATION:
2481 SetOrientation( property.Get< Quaternion >() );
2485 case Dali::Actor::Property::SCALE:
2487 SetScale( property.Get< Vector3 >() );
2491 case Dali::Actor::Property::SCALE_X:
2493 SetScaleX( property.Get< float >() );
2497 case Dali::Actor::Property::SCALE_Y:
2499 SetScaleY( property.Get< float >() );
2503 case Dali::Actor::Property::SCALE_Z:
2505 SetScaleZ( property.Get< float >() );
2509 case Dali::Actor::Property::VISIBLE:
2511 SetVisible( property.Get< bool >() );
2515 case Dali::Actor::Property::COLOR:
2517 SetColor( property.Get< Vector4 >() );
2521 case Dali::Actor::Property::COLOR_RED:
2523 SetColorRed( property.Get< float >() );
2527 case Dali::Actor::Property::COLOR_GREEN:
2529 SetColorGreen( property.Get< float >() );
2533 case Dali::Actor::Property::COLOR_BLUE:
2535 SetColorBlue( property.Get< float >() );
2539 case Dali::Actor::Property::COLOR_ALPHA:
2540 case Dali::DevelActor::Property::OPACITY:
2543 if( property.Get( value ) )
2545 SetOpacity( value );
2550 case Dali::Actor::Property::NAME:
2552 SetName( property.Get< std::string >() );
2556 case Dali::Actor::Property::SENSITIVE:
2558 SetSensitive( property.Get< bool >() );
2562 case Dali::Actor::Property::LEAVE_REQUIRED:
2564 SetLeaveRequired( property.Get< bool >() );
2568 case Dali::Actor::Property::INHERIT_POSITION:
2570 SetInheritPosition( property.Get< bool >() );
2574 case Dali::Actor::Property::INHERIT_ORIENTATION:
2576 SetInheritOrientation( property.Get< bool >() );
2580 case Dali::Actor::Property::INHERIT_SCALE:
2582 SetInheritScale( property.Get< bool >() );
2586 case Dali::Actor::Property::COLOR_MODE:
2588 ColorMode mode = mColorMode;
2589 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2591 SetColorMode( mode );
2596 case Dali::Actor::Property::POSITION_INHERITANCE:
2598 PositionInheritanceMode mode = mPositionInheritanceMode;
2599 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2601 SetPositionInheritanceMode( mode );
2606 case Dali::Actor::Property::DRAW_MODE:
2608 DrawMode::Type mode = mDrawMode;
2609 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2611 SetDrawMode( mode );
2616 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2618 SetSizeModeFactor( property.Get< Vector3 >() );
2622 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2624 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2625 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2627 SetResizePolicy( type, Dimension::WIDTH );
2632 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2634 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2635 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2637 SetResizePolicy( type, Dimension::HEIGHT );
2642 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2644 SizeScalePolicy::Type type = GetSizeScalePolicy();
2645 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2647 SetSizeScalePolicy( type );
2652 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2654 if( property.Get< bool >() )
2656 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2661 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2663 if( property.Get< bool >() )
2665 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2670 case Dali::Actor::Property::PADDING:
2672 Vector4 padding = property.Get< Vector4 >();
2673 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2674 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2678 case Dali::Actor::Property::MINIMUM_SIZE:
2680 Vector2 size = property.Get< Vector2 >();
2681 SetMinimumSize( size.x, Dimension::WIDTH );
2682 SetMinimumSize( size.y, Dimension::HEIGHT );
2686 case Dali::Actor::Property::MAXIMUM_SIZE:
2688 Vector2 size = property.Get< Vector2 >();
2689 SetMaximumSize( size.x, Dimension::WIDTH );
2690 SetMaximumSize( size.y, Dimension::HEIGHT );
2694 case Dali::DevelActor::Property::SIBLING_ORDER:
2698 if( property.Get( value ) )
2700 SetSiblingOrder( value );
2705 case Dali::Actor::Property::CLIPPING_MODE:
2707 ClippingMode::Type convertedValue = mClippingMode;
2708 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2710 mClippingMode = convertedValue;
2711 SetClippingModeMessage( GetEventThreadServices(), mNode, mClippingMode );
2716 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2719 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2721 mPositionUsesAnchorPoint = value;
2722 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), mNode, mPositionUsesAnchorPoint );
2727 case Dali::Actor::Property::LAYOUT_DIRECTION:
2729 Dali::LayoutDirection::Type direction = mLayoutDirection;
2730 mInheritLayoutDirection = false;
2732 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2734 InheritLayoutDirectionRecursively( this, direction, true );
2739 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2742 if( property.Get( value ) )
2744 SetInheritLayoutDirection( value );
2751 // this can happen in the case of a non-animatable default property so just do nothing
2757 // TODO: This method needs to be removed
2758 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2760 switch( entry.GetType() )
2762 case Property::BOOLEAN:
2764 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2765 DALI_ASSERT_DEBUG( NULL != property );
2767 // property is being used in a separate thread; queue a message to set the property
2768 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2773 case Property::INTEGER:
2775 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2776 DALI_ASSERT_DEBUG( NULL != property );
2778 // property is being used in a separate thread; queue a message to set the property
2779 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2784 case Property::FLOAT:
2786 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2787 DALI_ASSERT_DEBUG( NULL != property );
2789 // property is being used in a separate thread; queue a message to set the property
2790 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2795 case Property::VECTOR2:
2797 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2798 DALI_ASSERT_DEBUG( NULL != property );
2800 // property is being used in a separate thread; queue a message to set the property
2801 if(entry.componentIndex == 0)
2803 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2805 else if(entry.componentIndex == 1)
2807 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2811 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2817 case Property::VECTOR3:
2819 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2820 DALI_ASSERT_DEBUG( NULL != property );
2822 // property is being used in a separate thread; queue a message to set the property
2823 if(entry.componentIndex == 0)
2825 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2827 else if(entry.componentIndex == 1)
2829 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2831 else if(entry.componentIndex == 2)
2833 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2837 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2843 case Property::VECTOR4:
2845 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2846 DALI_ASSERT_DEBUG( NULL != property );
2848 // property is being used in a separate thread; queue a message to set the property
2849 if(entry.componentIndex == 0)
2851 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2853 else if(entry.componentIndex == 1)
2855 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2857 else if(entry.componentIndex == 2)
2859 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2861 else if(entry.componentIndex == 3)
2863 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2867 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2873 case Property::ROTATION:
2875 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2876 DALI_ASSERT_DEBUG( NULL != property );
2878 // property is being used in a separate thread; queue a message to set the property
2879 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2884 case Property::MATRIX:
2886 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2887 DALI_ASSERT_DEBUG( NULL != property );
2889 // property is being used in a separate thread; queue a message to set the property
2890 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2895 case Property::MATRIX3:
2897 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2898 DALI_ASSERT_DEBUG( NULL != property );
2900 // property is being used in a separate thread; queue a message to set the property
2901 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2908 // nothing to do for other types
2913 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2915 Property::Value value;
2917 if( ! GetCachedPropertyValue( index, value ) )
2919 // If property value is not stored in the event-side, then it must be a scene-graph only property
2920 GetCurrentPropertyValue( index, value );
2926 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2928 Property::Value value;
2930 if( ! GetCurrentPropertyValue( index, value ) )
2932 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2933 GetCachedPropertyValue( index, value );
2939 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2941 switch( animationType )
2944 case Animation::BETWEEN:
2948 case Dali::Actor::Property::SIZE:
2950 if( value.Get( mTargetSize ) )
2952 // Notify deriving classes
2953 OnSizeAnimation( animation, mTargetSize );
2958 case Dali::Actor::Property::SIZE_WIDTH:
2960 if( value.Get( mTargetSize.width ) )
2962 // Notify deriving classes
2963 OnSizeAnimation( animation, mTargetSize );
2968 case Dali::Actor::Property::SIZE_HEIGHT:
2970 if( value.Get( mTargetSize.height ) )
2972 // Notify deriving classes
2973 OnSizeAnimation( animation, mTargetSize );
2978 case Dali::Actor::Property::SIZE_DEPTH:
2980 if( value.Get( mTargetSize.depth ) )
2982 // Notify deriving classes
2983 OnSizeAnimation( animation, mTargetSize );
2988 case Dali::Actor::Property::POSITION:
2990 value.Get( mTargetPosition );
2994 case Dali::Actor::Property::POSITION_X:
2996 value.Get( mTargetPosition.x );
3000 case Dali::Actor::Property::POSITION_Y:
3002 value.Get( mTargetPosition.y );
3006 case Dali::Actor::Property::POSITION_Z:
3008 value.Get( mTargetPosition.z );
3012 case Dali::Actor::Property::ORIENTATION:
3014 value.Get( mTargetOrientation );
3018 case Dali::Actor::Property::SCALE:
3020 value.Get( mTargetScale );
3024 case Dali::Actor::Property::SCALE_X:
3026 value.Get( mTargetScale.x );
3030 case Dali::Actor::Property::SCALE_Y:
3032 value.Get( mTargetScale.y );
3036 case Dali::Actor::Property::SCALE_Z:
3038 value.Get( mTargetScale.z );
3042 case Dali::Actor::Property::VISIBLE:
3044 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3048 case Dali::Actor::Property::COLOR:
3050 value.Get( mTargetColor );
3054 case Dali::Actor::Property::COLOR_RED:
3056 value.Get( mTargetColor.r );
3060 case Dali::Actor::Property::COLOR_GREEN:
3062 value.Get( mTargetColor.g );
3066 case Dali::Actor::Property::COLOR_BLUE:
3068 value.Get( mTargetColor.b );
3072 case Dali::Actor::Property::COLOR_ALPHA:
3073 case Dali::DevelActor::Property::OPACITY:
3075 value.Get( mTargetColor.a );
3081 // Not an animatable property. Do nothing.
3092 case Dali::Actor::Property::SIZE:
3094 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3096 // Notify deriving classes
3097 OnSizeAnimation( animation, mTargetSize );
3102 case Dali::Actor::Property::SIZE_WIDTH:
3104 if( AdjustValue< float >( mTargetSize.width, value ) )
3106 // Notify deriving classes
3107 OnSizeAnimation( animation, mTargetSize );
3112 case Dali::Actor::Property::SIZE_HEIGHT:
3114 if( AdjustValue< float >( mTargetSize.height, value ) )
3116 // Notify deriving classes
3117 OnSizeAnimation( animation, mTargetSize );
3122 case Dali::Actor::Property::SIZE_DEPTH:
3124 if( AdjustValue< float >( mTargetSize.depth, value ) )
3126 // Notify deriving classes
3127 OnSizeAnimation( animation, mTargetSize );
3132 case Dali::Actor::Property::POSITION:
3134 AdjustValue< Vector3 >( mTargetPosition, value );
3138 case Dali::Actor::Property::POSITION_X:
3140 AdjustValue< float >( mTargetPosition.x, value );
3144 case Dali::Actor::Property::POSITION_Y:
3146 AdjustValue< float >( mTargetPosition.y, value );
3150 case Dali::Actor::Property::POSITION_Z:
3152 AdjustValue< float >( mTargetPosition.z, value );
3156 case Dali::Actor::Property::ORIENTATION:
3158 Quaternion relativeValue;
3159 if( value.Get( relativeValue ) )
3161 mTargetOrientation *= relativeValue;
3166 case Dali::Actor::Property::SCALE:
3168 AdjustValue< Vector3 >( mTargetScale, value );
3172 case Dali::Actor::Property::SCALE_X:
3174 AdjustValue< float >( mTargetScale.x, value );
3178 case Dali::Actor::Property::SCALE_Y:
3180 AdjustValue< float >( mTargetScale.y, value );
3184 case Dali::Actor::Property::SCALE_Z:
3186 AdjustValue< float >( mTargetScale.z, value );
3190 case Dali::Actor::Property::VISIBLE:
3192 bool relativeValue = false;
3193 if( value.Get( relativeValue ) )
3195 bool visible = mVisible || relativeValue;
3196 SetVisibleInternal( visible, SendMessage::FALSE );
3201 case Dali::Actor::Property::COLOR:
3203 AdjustValue< Vector4 >( mTargetColor, value );
3207 case Dali::Actor::Property::COLOR_RED:
3209 AdjustValue< float >( mTargetColor.r, value );
3213 case Dali::Actor::Property::COLOR_GREEN:
3215 AdjustValue< float >( mTargetColor.g, value );
3219 case Dali::Actor::Property::COLOR_BLUE:
3221 AdjustValue< float >( mTargetColor.b, value );
3225 case Dali::Actor::Property::COLOR_ALPHA:
3226 case Dali::DevelActor::Property::OPACITY:
3228 AdjustValue< float >( mTargetColor.a, value );
3234 // Not an animatable property. Do nothing.
3243 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3248 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3250 // This method should only return an object connected to the scene-graph
3251 return OnStage() ? &mNode : NULL;
3254 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3256 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3258 const PropertyBase* property( NULL );
3260 // This method should only return a property of an object connected to the scene-graph
3266 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3268 AnimatablePropertyMetadata* animatable = GetSceneAnimatableProperty( index, nullptr );
3269 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3271 property = animatable->GetSceneGraphProperty();
3273 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3274 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3276 CustomPropertyMetadata* custom = FindCustomProperty( index );
3277 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3279 property = custom->GetSceneGraphProperty();
3285 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3286 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3287 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3288 case Dali::Actor::Property::SIZE_DEPTH:
3290 property = &mNode.mSize;
3293 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3294 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3295 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3296 case Dali::Actor::Property::POSITION_Z:
3298 property = &mNode.mPosition;
3301 case Dali::Actor::Property::ORIENTATION:
3303 property = &mNode.mOrientation;
3306 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3307 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3308 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3309 case Dali::Actor::Property::SCALE_Z:
3311 property = &mNode.mScale;
3314 case Dali::Actor::Property::VISIBLE:
3316 property = &mNode.mVisible;
3319 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3320 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3321 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3322 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3323 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3324 case Dali::DevelActor::Property::OPACITY:
3326 property = &mNode.mColor;
3339 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3341 const PropertyInputImpl* property( NULL );
3343 // This method should only return a property of an object connected to the scene-graph
3349 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3351 AnimatablePropertyMetadata* animatable = GetSceneAnimatableProperty( index, nullptr );
3352 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3354 property = animatable->GetSceneGraphProperty();
3356 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3357 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3359 CustomPropertyMetadata* custom = FindCustomProperty( index );
3360 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3361 property = custom->GetSceneGraphProperty();
3367 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3368 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3369 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3370 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3372 property = &mNode.mParentOrigin;
3375 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3376 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3377 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3378 case Dali::Actor::Property::ANCHOR_POINT_Z:
3380 property = &mNode.mAnchorPoint;
3383 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3384 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3385 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3386 case Dali::Actor::Property::SIZE_DEPTH:
3388 property = &mNode.mSize;
3391 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3392 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3393 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3394 case Dali::Actor::Property::POSITION_Z:
3396 property = &mNode.mPosition;
3399 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3400 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3401 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3402 case Dali::Actor::Property::WORLD_POSITION_Z:
3404 property = &mNode.mWorldPosition;
3407 case Dali::Actor::Property::ORIENTATION:
3409 property = &mNode.mOrientation;
3412 case Dali::Actor::Property::WORLD_ORIENTATION:
3414 property = &mNode.mWorldOrientation;
3417 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3418 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3419 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3420 case Dali::Actor::Property::SCALE_Z:
3422 property = &mNode.mScale;
3425 case Dali::Actor::Property::WORLD_SCALE:
3427 property = &mNode.mWorldScale;
3430 case Dali::Actor::Property::VISIBLE:
3432 property = &mNode.mVisible;
3435 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3436 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3437 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3438 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3439 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3440 case Dali::DevelActor::Property::OPACITY:
3442 property = &mNode.mColor;
3445 case Dali::Actor::Property::WORLD_COLOR:
3447 property = &mNode.mWorldColor;
3450 case Dali::Actor::Property::WORLD_MATRIX:
3452 property = &mNode.mWorldMatrix;
3455 case Dali::DevelActor::Property::CULLED:
3457 property = &mNode.mCulled;
3470 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3472 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3474 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3476 // check whether the animatable property is registered already, if not then register one.
3477 AnimatablePropertyMetadata* animatableProperty = GetSceneAnimatableProperty( index, nullptr );
3478 if( animatableProperty )
3480 componentIndex = animatableProperty->componentIndex;
3487 case Dali::Actor::Property::PARENT_ORIGIN_X:
3488 case Dali::Actor::Property::ANCHOR_POINT_X:
3489 case Dali::Actor::Property::SIZE_WIDTH:
3490 case Dali::Actor::Property::POSITION_X:
3491 case Dali::Actor::Property::WORLD_POSITION_X:
3492 case Dali::Actor::Property::SCALE_X:
3493 case Dali::Actor::Property::COLOR_RED:
3499 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3500 case Dali::Actor::Property::ANCHOR_POINT_Y:
3501 case Dali::Actor::Property::SIZE_HEIGHT:
3502 case Dali::Actor::Property::POSITION_Y:
3503 case Dali::Actor::Property::WORLD_POSITION_Y:
3504 case Dali::Actor::Property::SCALE_Y:
3505 case Dali::Actor::Property::COLOR_GREEN:
3511 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3512 case Dali::Actor::Property::ANCHOR_POINT_Z:
3513 case Dali::Actor::Property::SIZE_DEPTH:
3514 case Dali::Actor::Property::POSITION_Z:
3515 case Dali::Actor::Property::WORLD_POSITION_Z:
3516 case Dali::Actor::Property::SCALE_Z:
3517 case Dali::Actor::Property::COLOR_BLUE:
3523 case Dali::Actor::Property::COLOR_ALPHA:
3524 case Dali::DevelActor::Property::OPACITY:
3538 return componentIndex;
3541 void Actor::SetParent( Actor* parent )
3545 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3549 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3552 // Instruct each actor to create a corresponding node in the scene graph
3553 ConnectToStage( parent->GetHierarchyDepth() );
3556 // Resolve the name and index for the child properties if any
3557 ResolveChildProperties();
3559 else // parent being set to NULL
3561 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3565 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3568 // Disconnect the Node & its children from the scene-graph.
3569 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mNode );
3571 // Instruct each actor to discard pointers to the scene-graph
3572 DisconnectFromStage();
3577 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3580 Actor* actor = dynamic_cast< Actor* >( object );
3584 if( 0 == actionName.compare( ACTION_SHOW ) )
3586 actor->SetVisible( true );
3589 else if( 0 == actionName.compare( ACTION_HIDE ) )
3591 actor->SetVisible( false );
3599 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3601 bool valueSet = true;
3605 case Dali::Actor::Property::PARENT_ORIGIN:
3607 value = GetCurrentParentOrigin();
3611 case Dali::Actor::Property::PARENT_ORIGIN_X:
3613 value = GetCurrentParentOrigin().x;
3617 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3619 value = GetCurrentParentOrigin().y;
3623 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3625 value = GetCurrentParentOrigin().z;
3629 case Dali::Actor::Property::ANCHOR_POINT:
3631 value = GetCurrentAnchorPoint();
3635 case Dali::Actor::Property::ANCHOR_POINT_X:
3637 value = GetCurrentAnchorPoint().x;
3641 case Dali::Actor::Property::ANCHOR_POINT_Y:
3643 value = GetCurrentAnchorPoint().y;
3647 case Dali::Actor::Property::ANCHOR_POINT_Z:
3649 value = GetCurrentAnchorPoint().z;
3653 case Dali::Actor::Property::SIZE:
3655 value = GetTargetSize();
3659 case Dali::Actor::Property::SIZE_WIDTH:
3661 value = GetTargetSize().width;
3665 case Dali::Actor::Property::SIZE_HEIGHT:
3667 value = GetTargetSize().height;
3671 case Dali::Actor::Property::SIZE_DEPTH:
3673 value = GetTargetSize().depth;
3677 case Dali::Actor::Property::POSITION:
3679 value = GetTargetPosition();
3683 case Dali::Actor::Property::POSITION_X:
3685 value = GetTargetPosition().x;
3689 case Dali::Actor::Property::POSITION_Y:
3691 value = GetTargetPosition().y;
3695 case Dali::Actor::Property::POSITION_Z:
3697 value = GetTargetPosition().z;
3701 case Dali::Actor::Property::ORIENTATION:
3703 value = mTargetOrientation;
3707 case Dali::Actor::Property::SCALE:
3709 value = mTargetScale;
3713 case Dali::Actor::Property::SCALE_X:
3715 value = mTargetScale.x;
3719 case Dali::Actor::Property::SCALE_Y:
3721 value = mTargetScale.y;
3725 case Dali::Actor::Property::SCALE_Z:
3727 value = mTargetScale.z;
3731 case Dali::Actor::Property::VISIBLE:
3737 case Dali::Actor::Property::COLOR:
3739 value = mTargetColor;
3743 case Dali::Actor::Property::COLOR_RED:
3745 value = mTargetColor.r;
3749 case Dali::Actor::Property::COLOR_GREEN:
3751 value = mTargetColor.g;
3755 case Dali::Actor::Property::COLOR_BLUE:
3757 value = mTargetColor.b;
3761 case Dali::Actor::Property::COLOR_ALPHA:
3762 case Dali::DevelActor::Property::OPACITY:
3764 value = mTargetColor.a;
3768 case Dali::Actor::Property::NAME:
3774 case Dali::Actor::Property::SENSITIVE:
3776 value = IsSensitive();
3780 case Dali::Actor::Property::LEAVE_REQUIRED:
3782 value = GetLeaveRequired();
3786 case Dali::Actor::Property::INHERIT_POSITION:
3788 value = IsPositionInherited();
3792 case Dali::Actor::Property::INHERIT_ORIENTATION:
3794 value = IsOrientationInherited();
3798 case Dali::Actor::Property::INHERIT_SCALE:
3800 value = IsScaleInherited();
3804 case Dali::Actor::Property::COLOR_MODE:
3806 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3810 case Dali::Actor::Property::POSITION_INHERITANCE:
3812 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
3816 case Dali::Actor::Property::DRAW_MODE:
3818 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3822 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3824 value = GetSizeModeFactor();
3828 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3830 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3834 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3836 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3840 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3842 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3846 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3848 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3852 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3854 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3858 case Dali::Actor::Property::PADDING:
3860 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3861 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3862 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3866 case Dali::Actor::Property::MINIMUM_SIZE:
3868 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3872 case Dali::Actor::Property::MAXIMUM_SIZE:
3874 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3878 case Dali::Actor::Property::CLIPPING_MODE:
3880 value = mClippingMode;
3884 case Dali::DevelActor::Property::SIBLING_ORDER:
3886 value = static_cast<int>( GetSiblingOrder() );
3890 case Dali::DevelActor::Property::SCREEN_POSITION:
3892 value = GetCurrentScreenPosition();
3896 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3898 value = mPositionUsesAnchorPoint;
3902 case Dali::Actor::Property::LAYOUT_DIRECTION:
3904 value = mLayoutDirection;
3908 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3910 value = IsLayoutDirectionInherited();
3916 // Must be a scene-graph only property
3925 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3927 bool valueSet = true;
3931 case Dali::Actor::Property::SIZE:
3933 value = GetCurrentSize();
3937 case Dali::Actor::Property::SIZE_WIDTH:
3939 value = GetCurrentSize().width;
3943 case Dali::Actor::Property::SIZE_HEIGHT:
3945 value = GetCurrentSize().height;
3949 case Dali::Actor::Property::SIZE_DEPTH:
3951 value = GetCurrentSize().depth;
3955 case Dali::Actor::Property::POSITION:
3957 value = GetCurrentPosition();
3961 case Dali::Actor::Property::POSITION_X:
3963 value = GetCurrentPosition().x;
3967 case Dali::Actor::Property::POSITION_Y:
3969 value = GetCurrentPosition().y;
3973 case Dali::Actor::Property::POSITION_Z:
3975 value = GetCurrentPosition().z;
3979 case Dali::Actor::Property::WORLD_POSITION:
3981 value = GetCurrentWorldPosition();
3985 case Dali::Actor::Property::WORLD_POSITION_X:
3987 value = GetCurrentWorldPosition().x;
3991 case Dali::Actor::Property::WORLD_POSITION_Y:
3993 value = GetCurrentWorldPosition().y;
3997 case Dali::Actor::Property::WORLD_POSITION_Z:
3999 value = GetCurrentWorldPosition().z;
4003 case Dali::Actor::Property::ORIENTATION:
4005 value = GetCurrentOrientation();
4009 case Dali::Actor::Property::WORLD_ORIENTATION:
4011 value = GetCurrentWorldOrientation();
4015 case Dali::Actor::Property::SCALE:
4017 value = GetCurrentScale();
4021 case Dali::Actor::Property::SCALE_X:
4023 value = GetCurrentScale().x;
4027 case Dali::Actor::Property::SCALE_Y:
4029 value = GetCurrentScale().y;
4033 case Dali::Actor::Property::SCALE_Z:
4035 value = GetCurrentScale().z;
4039 case Dali::Actor::Property::WORLD_SCALE:
4041 value = GetCurrentWorldScale();
4045 case Dali::Actor::Property::COLOR:
4047 value = GetCurrentColor();
4051 case Dali::Actor::Property::COLOR_RED:
4053 value = GetCurrentColor().r;
4057 case Dali::Actor::Property::COLOR_GREEN:
4059 value = GetCurrentColor().g;
4063 case Dali::Actor::Property::COLOR_BLUE:
4065 value = GetCurrentColor().b;
4069 case Dali::Actor::Property::COLOR_ALPHA:
4070 case Dali::DevelActor::Property::OPACITY:
4072 value = GetCurrentColor().a;
4076 case Dali::Actor::Property::WORLD_COLOR:
4078 value = GetCurrentWorldColor();
4082 case Dali::Actor::Property::WORLD_MATRIX:
4084 value = GetCurrentWorldMatrix();
4088 case Dali::Actor::Property::VISIBLE:
4090 value = IsVisible();
4094 case DevelActor::Property::CULLED:
4096 value = mNode.IsCulled( GetEventThreadServices().GetEventBufferIndex() );
4102 // Must be an event-side only property
4111 void Actor::EnsureRelayoutData()
4113 // Assign relayout data.
4114 if( !mRelayoutData )
4116 mRelayoutData = new RelayoutData();
4120 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4122 // Check if actor is dependent on parent
4123 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4125 if( ( dimension & ( 1 << i ) ) )
4127 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4128 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4138 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4140 // Check if actor is dependent on children
4141 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4143 if( ( dimension & ( 1 << i ) ) )
4145 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4146 switch( resizePolicy )
4148 case ResizePolicy::FIT_TO_CHILDREN:
4149 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4165 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4167 return Actor::RelayoutDependentOnChildren( dimension );
4170 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4172 // Check each possible dimension and see if it is dependent on the input one
4173 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4175 if( dimension & ( 1 << i ) )
4177 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4184 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4186 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4188 if( dimension & ( 1 << i ) )
4190 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4195 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4197 // If more than one dimension is requested, just return the first one found
4198 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4200 if( ( dimension & ( 1 << i ) ) )
4202 return mRelayoutData->negotiatedDimensions[ i ];
4206 return 0.0f; // Default
4209 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4211 EnsureRelayoutData();
4213 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4215 if( dimension & ( 1 << i ) )
4217 mRelayoutData->dimensionPadding[ i ] = padding;
4222 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4224 if ( mRelayoutData )
4226 // If more than one dimension is requested, just return the first one found
4227 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4229 if( ( dimension & ( 1 << i ) ) )
4231 return mRelayoutData->dimensionPadding[ i ];
4236 return GetDefaultDimensionPadding();
4239 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4241 EnsureRelayoutData();
4243 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4245 if( dimension & ( 1 << i ) )
4247 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4252 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4254 if ( mRelayoutData )
4256 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4258 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4268 float Actor::GetHeightForWidthBase( float width )
4270 float height = 0.0f;
4272 const Vector3 naturalSize = GetNaturalSize();
4273 if( naturalSize.width > 0.0f )
4275 height = naturalSize.height * width / naturalSize.width;
4277 else // we treat 0 as 1:1 aspect ratio
4285 float Actor::GetWidthForHeightBase( float height )
4289 const Vector3 naturalSize = GetNaturalSize();
4290 if( naturalSize.height > 0.0f )
4292 width = naturalSize.width * height / naturalSize.height;
4294 else // we treat 0 as 1:1 aspect ratio
4302 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4304 // Fill to parent, taking size mode factor into account
4305 switch( child.GetResizePolicy( dimension ) )
4307 case ResizePolicy::FILL_TO_PARENT:
4309 return GetLatestSize( dimension );
4312 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4314 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4317 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4319 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4324 return GetLatestSize( dimension );
4329 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4331 // Can be overridden in derived class
4332 return CalculateChildSizeBase( child, dimension );
4335 float Actor::GetHeightForWidth( float width )
4337 // Can be overridden in derived class
4338 return GetHeightForWidthBase( width );
4341 float Actor::GetWidthForHeight( float height )
4343 // Can be overridden in derived class
4344 return GetWidthForHeightBase( height );
4347 float Actor::GetLatestSize( Dimension::Type dimension ) const
4349 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4352 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4354 Vector2 padding = GetPadding( dimension );
4356 return GetLatestSize( dimension ) + padding.x + padding.y;
4359 float Actor::NegotiateFromParent( Dimension::Type dimension )
4361 Actor* parent = GetParent();
4364 Vector2 padding( GetPadding( dimension ) );
4365 Vector2 parentPadding( parent->GetPadding( dimension ) );
4366 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4372 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4374 float maxDimensionPoint = 0.0f;
4376 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4378 ActorPtr child = GetChildAt( i );
4380 if( !child->RelayoutDependentOnParent( dimension ) )
4382 // Calculate the min and max points that the children range across
4383 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4384 float dimensionSize = child->GetRelayoutSize( dimension );
4385 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4389 return maxDimensionPoint;
4392 float Actor::GetSize( Dimension::Type dimension ) const
4394 return GetDimensionValue( mTargetSize, dimension );
4397 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4399 return GetDimensionValue( GetNaturalSize(), dimension );
4402 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4404 switch( GetResizePolicy( dimension ) )
4406 case ResizePolicy::USE_NATURAL_SIZE:
4408 return GetNaturalSize( dimension );
4411 case ResizePolicy::FIXED:
4413 return GetDimensionValue( GetPreferredSize(), dimension );
4416 case ResizePolicy::USE_ASSIGNED_SIZE:
4418 return GetDimensionValue( maximumSize, dimension );
4421 case ResizePolicy::FILL_TO_PARENT:
4422 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4423 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4425 return NegotiateFromParent( dimension );
4428 case ResizePolicy::FIT_TO_CHILDREN:
4430 return NegotiateFromChildren( dimension );
4433 case ResizePolicy::DIMENSION_DEPENDENCY:
4435 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4438 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4440 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4443 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4445 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4457 return 0.0f; // Default
4460 float Actor::ClampDimension( float size, Dimension::Type dimension )
4462 const float minSize = GetMinimumSize( dimension );
4463 const float maxSize = GetMaximumSize( dimension );
4465 return std::max( minSize, std::min( size, maxSize ) );
4468 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4470 // Check if it needs to be negotiated
4471 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4473 // Check that we havn't gotten into an infinite loop
4474 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4475 bool recursionFound = false;
4476 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4478 if( *it == searchActor )
4480 recursionFound = true;
4485 if( !recursionFound )
4487 // Record the path that we have taken
4488 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4490 // Dimension dependency check
4491 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4493 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4495 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4497 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4501 // Parent dependency check
4502 Actor* parent = GetParent();
4503 if( parent && RelayoutDependentOnParent( dimension ) )
4505 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4508 // Children dependency check
4509 if( RelayoutDependentOnChildren( dimension ) )
4511 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4513 ActorPtr child = GetChildAt( i );
4515 // Only relayout child first if it is not dependent on this actor
4516 if( !child->RelayoutDependentOnParent( dimension ) )
4518 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4523 // For deriving classes
4524 OnCalculateRelayoutSize( dimension );
4526 // All dependencies checked, calculate the size and set negotiated flag
4527 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4529 SetNegotiatedDimension( newSize, dimension );
4530 SetLayoutNegotiated( true, dimension );
4532 // For deriving classes
4533 OnLayoutNegotiated( newSize, dimension );
4535 // This actor has been successfully processed, pop it off the recursion stack
4536 recursionStack.pop_back();
4540 // TODO: Break infinite loop
4541 SetLayoutNegotiated( true, dimension );
4546 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4548 // Negotiate all dimensions that require it
4549 ActorDimensionStack recursionStack;
4551 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4553 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4556 NegotiateDimension( dimension, allocatedSize, recursionStack );
4560 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4562 switch( mRelayoutData->sizeSetPolicy )
4564 case SizeScalePolicy::USE_SIZE_SET:
4569 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4571 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4572 const Vector3 naturalSize = GetNaturalSize();
4573 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4575 const float sizeRatio = size.width / size.height;
4576 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4578 if( naturalSizeRatio < sizeRatio )
4580 return Vector2( naturalSizeRatio * size.height, size.height );
4582 else if( naturalSizeRatio > sizeRatio )
4584 return Vector2( size.width, size.width / naturalSizeRatio );
4595 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4597 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4598 const Vector3 naturalSize = GetNaturalSize();
4599 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4601 const float sizeRatio = size.width / size.height;
4602 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4604 if( naturalSizeRatio < sizeRatio )
4606 return Vector2( size.width, size.width / naturalSizeRatio );
4608 else if( naturalSizeRatio > sizeRatio )
4610 return Vector2( naturalSizeRatio * size.height, size.height );
4629 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4631 // Do the set actor size
4632 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4634 // Adjust for size set policy
4635 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4637 // Lock the flag to stop recursive relayouts on set size
4638 mRelayoutData->insideRelayout = true;
4639 SetSize( negotiatedSize );
4640 mRelayoutData->insideRelayout = false;
4642 // Clear flags for all dimensions
4643 SetLayoutDirty( false );
4645 // Give deriving classes a chance to respond
4646 OnRelayout( negotiatedSize, container );
4648 if( !mOnRelayoutSignal.Empty() )
4650 Dali::Actor handle( this );
4651 mOnRelayoutSignal.Emit( handle );
4655 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4657 // Force a size negotiation for actors that has assigned size during relayout
4658 // This is required as otherwise the flags that force a relayout will not
4659 // necessarilly be set. This will occur if the actor has already been laid out.
4660 // The dirty flags are then cleared. Then if the actor is added back into the
4661 // relayout container afterwards, the dirty flags would still be clear...
4662 // causing a relayout to be skipped. Here we force any actors added to the
4663 // container to be relayed out.
4664 DALI_LOG_TIMER_START( NegSizeTimer1 );
4666 if( GetUseAssignedSize(Dimension::WIDTH ) )
4668 SetLayoutNegotiated( false, Dimension::WIDTH );
4670 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4672 SetLayoutNegotiated( false, Dimension::HEIGHT );
4675 // Do the negotiation
4676 NegotiateDimensions( allocatedSize );
4678 // Set the actor size
4679 SetNegotiatedSize( container );
4681 // Negotiate down to children
4682 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4684 ActorPtr child = GetChildAt( i );
4686 // Forces children that have already been laid out to be relayed out
4687 // if they have assigned size during relayout.
4688 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4690 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4691 child->SetLayoutDirty(true, Dimension::WIDTH);
4694 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4696 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4697 child->SetLayoutDirty(true, Dimension::HEIGHT);
4700 // Only relayout if required
4701 if( child->RelayoutRequired() )
4703 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4706 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4709 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4713 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4715 if( dimension & ( 1 << i ) )
4717 mRelayoutData->useAssignedSize[ i ] = use;
4723 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4725 if ( mRelayoutData )
4727 // If more than one dimension is requested, just return the first one found
4728 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4730 if( dimension & ( 1 << i ) )
4732 return mRelayoutData->useAssignedSize[ i ];
4740 void Actor::RelayoutRequest( Dimension::Type dimension )
4742 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4743 if( relayoutController )
4745 Dali::Actor self( this );
4746 relayoutController->RequestRelayout( self, dimension );
4750 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4754 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4758 void Actor::SetPreferredSize( const Vector2& size )
4760 EnsureRelayoutData();
4762 if( size.width > 0.0f )
4764 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4767 if( size.height > 0.0f )
4769 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4772 mRelayoutData->preferredSize = size;
4777 Vector2 Actor::GetPreferredSize() const
4779 if ( mRelayoutData )
4781 return Vector2( mRelayoutData->preferredSize );
4784 return GetDefaultPreferredSize();
4787 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4789 EnsureRelayoutData();
4791 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4793 if( dimension & ( 1 << i ) )
4795 mRelayoutData->minimumSize[ i ] = size;
4802 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4804 if ( mRelayoutData )
4806 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4808 if( dimension & ( 1 << i ) )
4810 return mRelayoutData->minimumSize[ i ];
4815 return 0.0f; // Default
4818 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4820 EnsureRelayoutData();
4822 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4824 if( dimension & ( 1 << i ) )
4826 mRelayoutData->maximumSize[ i ] = size;
4833 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4835 if ( mRelayoutData )
4837 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4839 if( dimension & ( 1 << i ) )
4841 return mRelayoutData->maximumSize[ i ];
4846 return FLT_MAX; // Default
4849 Object* Actor::GetParentObject() const
4854 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4856 if( mVisible != visible )
4858 if( sendMessage == SendMessage::TRUE )
4860 // mNode is being used in a separate thread; queue a message to set the value & base value
4861 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &mNode, &mNode.mVisible, &AnimatableProperty<bool>::Bake, visible );
4866 // Emit the signal on this actor and all its children
4867 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4871 void Actor::SetSiblingOrder( uint32_t order )
4875 ActorContainer& siblings = *(mParent->mChildren);
4876 uint32_t currentOrder = GetSiblingOrder();
4878 if( order != currentOrder )
4884 else if( order < siblings.size() -1 )
4886 if( order > currentOrder )
4888 RaiseAbove( *siblings[order] );
4892 LowerBelow( *siblings[order] );
4903 uint32_t Actor::GetSiblingOrder() const
4909 ActorContainer& siblings = *(mParent->mChildren);
4910 for( std::size_t i = 0; i < siblings.size(); ++i )
4912 if( siblings[i] == this )
4914 order = static_cast<uint32_t>( i );
4923 void Actor::RequestRebuildDepthTree()
4927 StagePtr stage = Stage::GetCurrent();
4930 stage->RequestRebuildDepthTree();
4939 ActorContainer& siblings = *(mParent->mChildren);
4940 if( siblings.back() != this ) // If not already at end
4942 for( std::size_t i=0; i<siblings.size(); ++i )
4944 if( siblings[i] == this )
4947 ActorPtr next = siblings[i+1];
4948 siblings[i+1] = this;
4955 Dali::Actor handle( this );
4956 mParent->mChildOrderChangedSignal.Emit( handle );
4958 RequestRebuildDepthTree();
4962 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4970 ActorContainer& siblings = *(mParent->mChildren);
4971 if( siblings.front() != this ) // If not already at beginning
4973 for( std::size_t i=1; i<siblings.size(); ++i )
4975 if( siblings[i] == this )
4977 // Swap with previous
4978 ActorPtr previous = siblings[i-1];
4979 siblings[i-1] = this;
4980 siblings[i] = previous;
4986 Dali::Actor handle( this );
4987 mParent->mChildOrderChangedSignal.Emit( handle );
4989 RequestRebuildDepthTree();
4993 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4997 void Actor::RaiseToTop()
5001 ActorContainer& siblings = *(mParent->mChildren);
5002 if( siblings.back() != this ) // If not already at end
5004 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5005 if( iter != siblings.end() )
5007 siblings.erase(iter);
5008 siblings.push_back(ActorPtr(this));
5012 Dali::Actor handle( this );
5013 mParent->mChildOrderChangedSignal.Emit( handle );
5015 RequestRebuildDepthTree();
5019 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5023 void Actor::LowerToBottom()
5027 ActorContainer& siblings = *(mParent->mChildren);
5028 if( siblings.front() != this ) // If not already at bottom,
5030 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5032 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5033 if( iter != siblings.end() )
5035 siblings.erase(iter);
5036 siblings.insert(siblings.begin(), thisPtr);
5040 Dali::Actor handle( this );
5041 mParent->mChildOrderChangedSignal.Emit( handle );
5043 RequestRebuildDepthTree();
5047 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5051 void Actor::RaiseAbove( Internal::Actor& target )
5055 ActorContainer& siblings = *(mParent->mChildren);
5056 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5058 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5060 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5061 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5062 if( thisIter < targetIter )
5064 siblings.erase(thisIter);
5065 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5066 // invalidate thisIter)
5067 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5069 siblings.insert(targetIter, thisPtr);
5072 Dali::Actor handle( this );
5073 mParent->mChildOrderChangedSignal.Emit( handle );
5075 RequestRebuildDepthTree();
5080 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5084 void Actor::LowerBelow( Internal::Actor& target )
5088 ActorContainer& siblings = *(mParent->mChildren);
5089 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5091 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5093 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5094 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5096 if( thisIter > targetIter )
5098 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5099 siblings.insert(targetIter, thisPtr);
5102 Dali::Actor handle( this );
5103 mParent->mChildOrderChangedSignal.Emit( handle );
5105 RequestRebuildDepthTree();
5110 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5114 void Actor::SetInheritLayoutDirection( bool inherit )
5116 if( mInheritLayoutDirection != inherit )
5118 mInheritLayoutDirection = inherit;
5120 if( inherit && mParent )
5122 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5127 bool Actor::IsLayoutDirectionInherited() const
5129 return mInheritLayoutDirection;
5132 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5134 if( actor && ( actor->mInheritLayoutDirection || set ) )
5136 if( actor->mLayoutDirection != direction )
5138 actor->mLayoutDirection = direction;
5139 actor->EmitLayoutDirectionChangedSignal( direction );
5140 actor->RelayoutRequest();
5143 if( actor->GetChildCount() > 0 )
5145 ActorContainer& children = actor->GetChildrenInternal();
5146 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5148 InheritLayoutDirectionRecursively( *iter, direction );
5154 } // namespace Internal