2 * Copyright (c) 2017 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" );
71 unsigned int Actor::mActorCounter = 0;
75 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
76 inline const Vector3& GetDefaultSizeModeFactor()
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultPreferredSize()
87 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
88 inline const Vector2& GetDefaultDimensionPadding()
93 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
95 } // unnamed namespace
98 * Struct to collect relayout variables
100 struct Actor::RelayoutData
103 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
105 // Set size negotiation defaults
106 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
108 resizePolicies[ i ] = ResizePolicy::DEFAULT;
109 useAssignedSize[ i ] = false;
110 negotiatedDimensions[ i ] = 0.0f;
111 dimensionNegotiated[ i ] = false;
112 dimensionDirty[ i ] = false;
113 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
114 dimensionPadding[ i ] = GetDefaultDimensionPadding();
115 minimumSize[ i ] = 0.0f;
116 maximumSize[ i ] = FLT_MAX;
120 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
121 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
123 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
125 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
127 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
129 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
130 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
132 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
133 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
135 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
137 Vector2 preferredSize; ///< The preferred size of the actor
139 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
141 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
142 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
145 namespace // unnamed namespace
151 * We want to discourage the use of property strings (minimize string comparisons),
152 * particularly for the default properties.
153 * Name Type writable animatable constraint-input enum for index-checking
155 DALI_PROPERTY_TABLE_BEGIN
156 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
157 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
158 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
159 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
160 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
161 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
162 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
163 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
164 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
165 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
166 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
167 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
168 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
169 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
170 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
171 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
172 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
173 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
174 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
175 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
176 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
177 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
178 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
179 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
180 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
181 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
182 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
183 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
184 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
185 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
186 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
187 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
188 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
189 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
190 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
191 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
192 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
193 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
194 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
195 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
196 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
198 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
199 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
200 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
201 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
202 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
203 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
204 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
205 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
206 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
207 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
208 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
209 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
210 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
211 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
212 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
213 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
214 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
215 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
216 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
220 const char* const SIGNAL_TOUCHED = "touched";
221 const char* const SIGNAL_HOVERED = "hovered";
222 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
223 const char* const SIGNAL_ON_STAGE = "onStage";
224 const char* const SIGNAL_OFF_STAGE = "offStage";
225 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
226 const char* const SIGNAL_TOUCH = "touch";
230 const char* const ACTION_SHOW = "show";
231 const char* const ACTION_HIDE = "hide";
233 BaseHandle CreateActor()
235 return Dali::Actor::New();
238 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
240 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
241 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
242 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
243 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
244 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
245 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
248 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
249 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
254 const Vector3& value;
257 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
258 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
259 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
260 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
261 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
262 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
263 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
264 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
265 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
266 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
267 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
269 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
270 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
271 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
272 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
273 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
274 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
276 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
277 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
278 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
279 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
280 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
281 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
283 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
284 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
287 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
289 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
290 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
298 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
300 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
304 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
306 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
307 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
309 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
311 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
312 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
314 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
316 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
318 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
320 size_t sizeIgnored = 0;
321 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
323 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
330 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
332 // Values are the same so just use the same table as anchor-point
333 return GetAnchorPointConstant( value, parentOrigin );
337 * @brief Extract a given dimension from a Vector2
339 * @param[in] values The values to extract from
340 * @param[in] dimension The dimension to extract
341 * @return Return the value for the dimension
343 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
347 case Dimension::WIDTH:
351 case Dimension::HEIGHT:
353 return values.height;
364 * @brief Extract a given dimension from a Vector3
366 * @param[in] values The values to extract from
367 * @param[in] dimension The dimension to extract
368 * @return Return the value for the dimension
370 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
372 return GetDimensionValue( values.GetVectorXY(), dimension );
376 * @brief Recursively emits the visibility-changed-signal on the actor tree.
377 * @param[in] actor The actor to emit the signal on
378 * @param[in] visible The new visibility of the actor
379 * @param[in] type Whether the actor's visible property has changed or a parent's
381 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
385 actor->EmitVisibilityChangedSignal( visible, type );
387 if( actor->GetChildCount() > 0 )
389 ActorContainer& children = actor->GetChildrenInternal();
390 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
392 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
398 } // unnamed namespace
400 ActorPtr Actor::New()
402 ActorPtr actor( new Actor( BASIC ) );
404 // Second-phase construction
410 const std::string& Actor::GetName() const
415 void Actor::SetName( const std::string& name )
421 // ATTENTION: string for debug purposes is not thread safe.
422 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
426 unsigned int Actor::GetId() const
431 bool Actor::OnStage() const
436 Dali::Layer Actor::GetLayer()
440 // Short-circuit for Layer derived actors
443 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
446 // Find the immediate Layer parent
447 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
449 if( parent->IsLayer() )
451 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
458 void Actor::Add( Actor& child )
460 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
461 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
465 mChildren = new ActorContainer;
468 Actor* const oldParent( child.mParent );
470 // child might already be ours
471 if( this != oldParent )
473 // if we already have parent, unparent us first
476 oldParent->Remove( child ); // This causes OnChildRemove callback
478 // Old parent may need to readjust to missing child
479 if( oldParent->RelayoutDependentOnChildren() )
481 oldParent->RelayoutRequest();
485 // Guard against Add() during previous OnChildRemove callback
488 // Do this first, since user callbacks from within SetParent() may need to remove child
489 mChildren->push_back( ActorPtr( &child ) );
491 // SetParent asserts that child can be added
492 child.SetParent( this );
494 // Notification for derived classes
497 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
499 // Only put in a relayout request if there is a suitable dependency
500 if( RelayoutDependentOnChildren() )
508 void Actor::Remove( Actor& child )
510 if( (this == &child) || (!mChildren) )
512 // no children or removing itself
518 // Find the child in mChildren, and unparent it
519 ActorIter end = mChildren->end();
520 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
522 ActorPtr actor = (*iter);
524 if( actor.Get() == &child )
526 // Keep handle for OnChildRemove notification
529 // Do this first, since user callbacks from within SetParent() may need to add the child
530 mChildren->erase( iter );
532 DALI_ASSERT_DEBUG( actor->GetParent() == this );
533 actor->SetParent( NULL );
541 // Only put in a relayout request if there is a suitable dependency
542 if( RelayoutDependentOnChildren() )
548 // Notification for derived classes
549 OnChildRemove( child );
552 void Actor::Unparent()
556 // Remove this actor from the parent. The remove will put a relayout request in for
557 // the parent if required
558 mParent->Remove( *this );
559 // mParent is now NULL!
563 unsigned int Actor::GetChildCount() const
565 return ( NULL != mChildren ) ? mChildren->size() : 0;
568 ActorPtr Actor::GetChildAt( unsigned int index ) const
570 DALI_ASSERT_ALWAYS( index < GetChildCount() );
572 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
575 ActorPtr Actor::FindChildByName( const std::string& actorName )
578 if( actorName == mName )
584 ActorIter end = mChildren->end();
585 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
587 child = (*iter)->FindChildByName( actorName );
598 ActorPtr Actor::FindChildById( const unsigned int id )
607 ActorIter end = mChildren->end();
608 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
610 child = (*iter)->FindChildById( id );
621 void Actor::SetParentOrigin( const Vector3& origin )
625 // mNode is being used in a separate thread; queue a message to set the value & base value
626 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
629 // Cache for event-thread access
632 // not allocated, check if different from default
633 if( ParentOrigin::DEFAULT != origin )
635 mParentOrigin = new Vector3( origin );
640 // check if different from current costs more than just set
641 *mParentOrigin = origin;
645 void Actor::SetParentOriginX( float x )
647 const Vector3& current = GetCurrentParentOrigin();
649 SetParentOrigin( Vector3( x, current.y, current.z ) );
652 void Actor::SetParentOriginY( float y )
654 const Vector3& current = GetCurrentParentOrigin();
656 SetParentOrigin( Vector3( current.x, y, current.z ) );
659 void Actor::SetParentOriginZ( float z )
661 const Vector3& current = GetCurrentParentOrigin();
663 SetParentOrigin( Vector3( current.x, current.y, z ) );
666 const Vector3& Actor::GetCurrentParentOrigin() const
668 // Cached for event-thread access
669 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
672 void Actor::SetAnchorPoint( const Vector3& anchor )
676 // mNode is being used in a separate thread; queue a message to set the value & base value
677 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
680 // Cache for event-thread access
683 // not allocated, check if different from default
684 if( AnchorPoint::DEFAULT != anchor )
686 mAnchorPoint = new Vector3( anchor );
691 // check if different from current costs more than just set
692 *mAnchorPoint = anchor;
696 void Actor::SetAnchorPointX( float x )
698 const Vector3& current = GetCurrentAnchorPoint();
700 SetAnchorPoint( Vector3( x, current.y, current.z ) );
703 void Actor::SetAnchorPointY( float y )
705 const Vector3& current = GetCurrentAnchorPoint();
707 SetAnchorPoint( Vector3( current.x, y, current.z ) );
710 void Actor::SetAnchorPointZ( float z )
712 const Vector3& current = GetCurrentAnchorPoint();
714 SetAnchorPoint( Vector3( current.x, current.y, z ) );
717 const Vector3& Actor::GetCurrentAnchorPoint() const
719 // Cached for event-thread access
720 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
723 void Actor::SetPosition( float x, float y )
725 SetPosition( Vector3( x, y, 0.0f ) );
728 void Actor::SetPosition( float x, float y, float z )
730 SetPosition( Vector3( x, y, z ) );
733 void Actor::SetPosition( const Vector3& position )
735 mTargetPosition = position;
739 // mNode is being used in a separate thread; queue a message to set the value & base value
740 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
744 void Actor::SetX( float x )
746 mTargetPosition.x = x;
750 // mNode is being used in a separate thread; queue a message to set the value & base value
751 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
755 void Actor::SetY( float y )
757 mTargetPosition.y = y;
761 // mNode is being used in a separate thread; queue a message to set the value & base value
762 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
766 void Actor::SetZ( float z )
768 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 );
777 void Actor::TranslateBy( const Vector3& distance )
779 mTargetPosition += distance;
783 // mNode is being used in a separate thread; queue a message to set the value & base value
784 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
788 const Vector3& Actor::GetCurrentPosition() const
792 // mNode is being used in a separate thread; copy the value from the previous update
793 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
796 return Vector3::ZERO;
799 const Vector3& Actor::GetTargetPosition() const
801 return mTargetPosition;
804 const Vector3& Actor::GetCurrentWorldPosition() const
808 // mNode is being used in a separate thread; copy the value from the previous update
809 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
812 return Vector3::ZERO;
815 const Vector2 Actor::GetCurrentScreenPosition() const
817 StagePtr stage = Stage::GetCurrent();
818 if( stage && OnStage() && NULL != mNode )
820 Vector3 worldPosition = mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
821 Vector3 cameraPosition = stage->GetDefaultCameraActor().mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
822 worldPosition -= cameraPosition;
824 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
825 Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
826 Vector3 halfActorSize( actorSize * 0.5f );
827 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
829 return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
830 halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
833 return Vector2::ZERO;
836 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
838 // this flag is not animatable so keep the value
839 mPositionInheritanceMode = mode;
842 // mNode is being used in a separate thread; queue a message to set the value
843 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
847 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
849 // Cached for event-thread access
850 return mPositionInheritanceMode;
853 void Actor::SetInheritPosition( bool inherit )
855 if( mInheritPosition != inherit && NULL != mNode )
857 // non animateable so keep local copy
858 mInheritPosition = inherit;
859 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
863 bool Actor::IsPositionInherited() const
865 return mInheritPosition;
868 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
870 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
871 normalizedAxis.Normalize();
873 Quaternion orientation( angle, normalizedAxis );
875 SetOrientation( orientation );
878 void Actor::SetOrientation( const Quaternion& orientation )
880 mTargetOrientation = orientation;
884 // mNode is being used in a separate thread; queue a message to set the value & base value
885 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
889 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
891 RotateBy( Quaternion(angle, axis) );
894 void Actor::RotateBy( const Quaternion& relativeRotation )
896 mTargetOrientation *= Quaternion( relativeRotation );
900 // mNode is being used in a separate thread; queue a message to set the value & base value
901 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
905 const Quaternion& Actor::GetCurrentOrientation() const
909 // mNode is being used in a separate thread; copy the value from the previous update
910 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
913 return Quaternion::IDENTITY;
916 const Quaternion& Actor::GetCurrentWorldOrientation() const
920 // mNode is being used in a separate thread; copy the value from the previous update
921 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
924 return Quaternion::IDENTITY;
927 void Actor::SetScale( float scale )
929 SetScale( Vector3( scale, scale, scale ) );
932 void Actor::SetScale( float x, float y, float z )
934 SetScale( Vector3( x, y, z ) );
937 void Actor::SetScale( const Vector3& scale )
939 mTargetScale = scale;
943 // mNode is being used in a separate thread; queue a message to set the value & base value
944 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
948 void Actor::SetScaleX( float x )
954 // mNode is being used in a separate thread; queue a message to set the value & base value
955 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
959 void Actor::SetScaleY( float y )
965 // mNode is being used in a separate thread; queue a message to set the value & base value
966 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
970 void Actor::SetScaleZ( float z )
976 // mNode is being used in a separate thread; queue a message to set the value & base value
977 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
981 void Actor::ScaleBy(const Vector3& relativeScale)
983 mTargetScale *= relativeScale;
987 // mNode is being used in a separate thread; queue a message to set the value & base value
988 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
992 const Vector3& Actor::GetCurrentScale() const
996 // mNode is being used in a separate thread; copy the value from the previous update
997 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
1000 return Vector3::ONE;
1003 const Vector3& Actor::GetCurrentWorldScale() const
1007 // mNode is being used in a separate thread; copy the value from the previous update
1008 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
1011 return Vector3::ONE;
1014 void Actor::SetInheritScale( bool inherit )
1017 if( mInheritScale != inherit && NULL != mNode )
1019 // non animateable so keep local copy
1020 mInheritScale = inherit;
1021 // mNode is being used in a separate thread; queue a message to set the value
1022 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
1026 bool Actor::IsScaleInherited() const
1028 return mInheritScale;
1031 Matrix Actor::GetCurrentWorldMatrix() const
1035 return mNode->GetWorldMatrix(0);
1038 return Matrix::IDENTITY;
1041 void Actor::SetVisible( bool visible )
1043 SetVisibleInternal( visible, SendMessage::TRUE );
1046 bool Actor::IsVisible() const
1050 // mNode is being used in a separate thread; copy the value from the previous update
1051 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1057 void Actor::SetOpacity( float opacity )
1059 mTargetColor.a = opacity;
1063 // mNode is being used in a separate thread; queue a message to set the value & base value
1064 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1068 float Actor::GetCurrentOpacity() const
1072 // mNode is being used in a separate thread; copy the value from the previous update
1073 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1079 ClippingMode::Type Actor::GetClippingMode() const
1081 return mClippingMode;
1084 unsigned int Actor::GetSortingDepth()
1086 return mSortedDepth;
1089 const Vector4& Actor::GetCurrentWorldColor() const
1093 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1096 return Color::WHITE;
1099 void Actor::SetColor( const Vector4& color )
1101 mTargetColor = color;
1105 // mNode is being used in a separate thread; queue a message to set the value & base value
1106 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1110 void Actor::SetColorRed( float red )
1112 mTargetColor.r = red;
1116 // mNode is being used in a separate thread; queue a message to set the value & base value
1117 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1121 void Actor::SetColorGreen( float green )
1123 mTargetColor.g = green;
1127 // mNode is being used in a separate thread; queue a message to set the value & base value
1128 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1132 void Actor::SetColorBlue( float blue )
1134 mTargetColor.b = blue;
1138 // mNode is being used in a separate thread; queue a message to set the value & base value
1139 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1143 const Vector4& Actor::GetCurrentColor() const
1147 // mNode is being used in a separate thread; copy the value from the previous update
1148 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1151 return Color::WHITE;
1154 void Actor::SetInheritOrientation( bool inherit )
1156 if( mInheritOrientation != inherit && NULL != mNode)
1158 // non animateable so keep local copy
1159 mInheritOrientation = inherit;
1160 // mNode is being used in a separate thread; queue a message to set the value
1161 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1165 bool Actor::IsOrientationInherited() const
1167 return mInheritOrientation;
1170 void Actor::SetSizeModeFactor( const Vector3& factor )
1172 EnsureRelayoutData();
1174 mRelayoutData->sizeModeFactor = factor;
1177 const Vector3& Actor::GetSizeModeFactor() const
1179 if ( mRelayoutData )
1181 return mRelayoutData->sizeModeFactor;
1184 return GetDefaultSizeModeFactor();
1187 void Actor::SetColorMode( ColorMode colorMode )
1189 // non animateable so keep local copy
1190 mColorMode = colorMode;
1193 // mNode is being used in a separate thread; queue a message to set the value
1194 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1198 ColorMode Actor::GetColorMode() const
1200 // we have cached copy
1204 void Actor::SetSize( float width, float height )
1206 SetSize( Vector2( width, height ) );
1209 void Actor::SetSize( float width, float height, float depth )
1211 SetSize( Vector3( width, height, depth ) );
1214 void Actor::SetSize( const Vector2& size )
1216 SetSize( Vector3( size.width, size.height, 0.f ) );
1219 void Actor::SetSizeInternal( const Vector2& size )
1221 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1224 void Actor::SetSize( const Vector3& size )
1226 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1228 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1229 SetPreferredSize( size.GetVectorXY() );
1233 SetSizeInternal( size );
1237 void Actor::SetSizeInternal( const Vector3& size )
1239 // dont allow recursive loop
1240 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1241 // 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
1242 if( ( NULL != mNode )&&
1243 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1244 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1245 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1249 // mNode is being used in a separate thread; queue a message to set the value & base value
1250 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1252 // Notification for derived classes
1253 mInsideOnSizeSet = true;
1254 OnSizeSet( mTargetSize );
1255 mInsideOnSizeSet = false;
1257 // Raise a relayout request if the flag is not locked
1258 if( mRelayoutData && !mRelayoutData->insideRelayout )
1265 void Actor::SetWidth( float width )
1267 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1269 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1270 mRelayoutData->preferredSize.width = width;
1274 mTargetSize.width = width;
1278 // mNode is being used in a separate thread; queue a message to set the value & base value
1279 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1286 void Actor::SetHeight( float height )
1288 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1290 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1291 mRelayoutData->preferredSize.height = height;
1295 mTargetSize.height = height;
1299 // mNode is being used in a separate thread; queue a message to set the value & base value
1300 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1307 void Actor::SetDepth( float depth )
1309 mTargetSize.depth = depth;
1313 // mNode is being used in a separate thread; queue a message to set the value & base value
1314 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1318 Vector3 Actor::GetTargetSize() const
1320 Vector3 size = mTargetSize;
1322 // Should return preferred size if size is fixed as set by SetSize
1323 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1325 size.width = GetPreferredSize().width;
1327 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1329 size.height = GetPreferredSize().height;
1335 const Vector3& Actor::GetCurrentSize() const
1339 // mNode is being used in a separate thread; copy the value from the previous update
1340 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1343 return Vector3::ZERO;
1346 Vector3 Actor::GetNaturalSize() const
1348 // It is up to deriving classes to return the appropriate natural size
1349 return Vector3( 0.0f, 0.0f, 0.0f );
1352 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1354 EnsureRelayoutData();
1356 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1357 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1359 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1361 if( dimension & ( 1 << i ) )
1363 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1365 mRelayoutData->useAssignedSize[ i ] = true;
1369 mRelayoutData->resizePolicies[ i ] = policy;
1370 mRelayoutData->useAssignedSize[ i ] = false;
1375 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1377 if( dimension & Dimension::WIDTH )
1379 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1382 if( dimension & Dimension::HEIGHT )
1384 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1388 // If calling SetResizePolicy, assume we want relayout enabled
1389 SetRelayoutEnabled( true );
1391 // If the resize policy is set to be FIXED, the preferred size
1392 // should be overrided by the target size. Otherwise the target
1393 // size should be overrided by the preferred size.
1395 if( dimension & Dimension::WIDTH )
1397 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1399 mRelayoutData->preferredSize.width = mTargetSize.width;
1401 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1403 mTargetSize.width = mRelayoutData->preferredSize.width;
1407 if( dimension & Dimension::HEIGHT )
1409 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1411 mRelayoutData->preferredSize.height = mTargetSize.height;
1413 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1415 mTargetSize.height = mRelayoutData->preferredSize.height;
1419 OnSetResizePolicy( policy, dimension );
1421 // Trigger relayout on this control
1425 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1427 if ( mRelayoutData )
1429 // If more than one dimension is requested, just return the first one found
1430 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1432 if( ( dimension & ( 1 << i ) ) )
1434 if( mRelayoutData->useAssignedSize[ i ] )
1436 return ResizePolicy::USE_ASSIGNED_SIZE;
1440 return mRelayoutData->resizePolicies[ i ];
1446 return ResizePolicy::DEFAULT;
1449 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1451 EnsureRelayoutData();
1453 mRelayoutData->sizeSetPolicy = policy;
1456 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1458 if ( mRelayoutData )
1460 return mRelayoutData->sizeSetPolicy;
1463 return DEFAULT_SIZE_SCALE_POLICY;
1466 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1468 EnsureRelayoutData();
1470 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1472 if( dimension & ( 1 << i ) )
1474 mRelayoutData->dimensionDependencies[ i ] = dependency;
1479 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1481 if ( mRelayoutData )
1483 // If more than one dimension is requested, just return the first one found
1484 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1486 if( ( dimension & ( 1 << i ) ) )
1488 return mRelayoutData->dimensionDependencies[ i ];
1493 return Dimension::ALL_DIMENSIONS; // Default
1496 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1498 // If relayout data has not been allocated yet and the client is requesting
1499 // to disable it, do nothing
1500 if( mRelayoutData || relayoutEnabled )
1502 EnsureRelayoutData();
1504 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1506 mRelayoutData->relayoutEnabled = relayoutEnabled;
1510 bool Actor::IsRelayoutEnabled() const
1512 // Assume that if relayout data has not been allocated yet then
1513 // relayout is disabled
1514 return mRelayoutData && mRelayoutData->relayoutEnabled;
1517 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1519 EnsureRelayoutData();
1521 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1523 if( dimension & ( 1 << i ) )
1525 mRelayoutData->dimensionDirty[ i ] = dirty;
1530 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1532 if ( mRelayoutData )
1534 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1536 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1546 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1548 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1551 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1553 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1556 unsigned int Actor::AddRenderer( Renderer& renderer )
1560 mRenderers = new RendererContainer;
1563 unsigned int index = mRenderers->size();
1564 RendererPtr rendererPtr = RendererPtr( &renderer );
1565 mRenderers->push_back( rendererPtr );
1566 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1570 unsigned int Actor::GetRendererCount() const
1572 unsigned int rendererCount(0);
1575 rendererCount = mRenderers->size();
1578 return rendererCount;
1581 RendererPtr Actor::GetRendererAt( unsigned int index )
1583 RendererPtr renderer;
1584 if( index < GetRendererCount() )
1586 renderer = ( *mRenderers )[ index ];
1592 void Actor::RemoveRenderer( Renderer& renderer )
1596 RendererIter end = mRenderers->end();
1597 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1599 if( (*iter).Get() == &renderer )
1601 mRenderers->erase( iter );
1602 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1609 void Actor::RemoveRenderer( unsigned int index )
1611 if( index < GetRendererCount() )
1613 RendererPtr renderer = ( *mRenderers )[ index ];
1614 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1615 mRenderers->erase( mRenderers->begin()+index );
1619 bool Actor::IsOverlay() const
1621 return ( DrawMode::OVERLAY_2D == mDrawMode );
1624 void Actor::SetDrawMode( DrawMode::Type drawMode )
1626 // this flag is not animatable so keep the value
1627 mDrawMode = drawMode;
1628 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1630 // mNode is being used in a separate thread; queue a message to set the value
1631 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1635 DrawMode::Type Actor::GetDrawMode() const
1640 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1642 // only valid when on-stage
1643 StagePtr stage = Stage::GetCurrent();
1644 if( stage && OnStage() )
1646 const RenderTaskList& taskList = stage->GetRenderTaskList();
1648 Vector2 converted( screenX, screenY );
1650 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1651 const int taskCount = taskList.GetTaskCount();
1652 for( int i = taskCount - 1; i >= 0; --i )
1654 Dali::RenderTask task = taskList.GetTask( i );
1655 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1657 // found a task where this conversion was ok so return
1665 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1667 bool retval = false;
1668 // only valid when on-stage
1671 CameraActor* camera = renderTask.GetCameraActor();
1675 renderTask.GetViewport( viewport );
1677 // need to translate coordinates to render tasks coordinate space
1678 Vector2 converted( screenX, screenY );
1679 if( renderTask.TranslateCoordinates( converted ) )
1681 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1688 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1690 // Early-out if mNode is NULL
1696 // Get the ModelView matrix
1698 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1700 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1701 Matrix invertedMvp( false/*don't init*/);
1702 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1703 bool success = invertedMvp.Invert();
1705 // Convert to GL coordinates
1706 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1711 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1718 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1724 if( XyPlaneIntersect( nearPos, farPos, local ) )
1726 Vector3 size = GetCurrentSize();
1727 localX = local.x + size.x * 0.5f;
1728 localY = local.y + size.y * 0.5f;
1739 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1742 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1744 Mathematical Formulation
1746 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1748 ( p - c ) dot ( p - c ) = r^2
1750 Given a ray with a point of origin 'o', and a direction vector 'd':
1752 ray(t) = o + td, t >= 0
1754 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1756 (o + td - c ) dot ( o + td - c ) = r^2
1758 To solve for t we first expand the above into a more recognisable quadratic equation form
1760 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1769 B = 2( o - c ) dot d
1770 C = ( o - c ) dot ( o - c ) - r^2
1772 which can be solved using a standard quadratic formula.
1774 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1776 Practical Simplification
1778 In a renderer, we often differentiate between world space and object space. In the object space
1779 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1780 into object space, the mathematical solution presented above can be simplified significantly.
1782 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1786 and we can find the t at which the (transformed) ray intersects the sphere by
1788 ( o + td ) dot ( o + td ) = r^2
1790 According to the reasoning above, we expand the above quadratic equation into the general form
1794 which now has coefficients:
1801 // Early out if mNode is NULL
1807 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1809 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1810 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1811 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1813 // Compute the radius is not needed, square radius it's enough.
1814 const Vector3& size( mNode->GetSize( bufferIndex ) );
1816 // Scale the sphere.
1817 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1819 const float width = size.width * scale.width;
1820 const float height = size.height * scale.height;
1822 float squareSphereRadius = 0.5f * ( width * width + height * height );
1824 float a = rayDir.Dot( rayDir ); // a
1825 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1826 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1828 return ( b2 * b2 - a * c ) >= 0.f;
1831 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1835 if( OnStage() && NULL != mNode )
1837 // Transforms the ray to the local reference system.
1838 // Calculate the inverse of Model matrix
1839 Matrix invModelMatrix( false/*don't init*/);
1841 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1842 invModelMatrix = mNode->GetWorldMatrix(0);
1843 invModelMatrix.Invert();
1845 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1846 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1848 // Test with the actor's XY plane (Normal = 0 0 1 1).
1850 float a = -rayOriginLocal.z;
1851 float b = rayDirLocal.z;
1853 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1855 // Ray travels distance * rayDirLocal to intersect with plane.
1858 const Vector3& size = mNode->GetSize( bufferIndex );
1860 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1861 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1863 // Test with the actor's geometry.
1864 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1871 void Actor::SetLeaveRequired( bool required )
1873 mLeaveRequired = required;
1876 bool Actor::GetLeaveRequired() const
1878 return mLeaveRequired;
1881 void Actor::SetKeyboardFocusable( bool focusable )
1883 mKeyboardFocusable = focusable;
1886 bool Actor::IsKeyboardFocusable() const
1888 return mKeyboardFocusable;
1891 bool Actor::GetTouchRequired() const
1893 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1896 bool Actor::GetHoverRequired() const
1898 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1901 bool Actor::GetWheelEventRequired() const
1903 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1906 bool Actor::IsHittable() const
1908 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1911 ActorGestureData& Actor::GetGestureData()
1913 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1914 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1915 if( NULL == mGestureData )
1917 mGestureData = new ActorGestureData;
1919 return *mGestureData;
1922 bool Actor::IsGestureRequred( Gesture::Type type ) const
1924 return mGestureData && mGestureData->IsGestureRequred( type );
1927 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1929 bool consumed = false;
1931 if( !mTouchSignal.Empty() )
1933 Dali::Actor handle( this );
1934 consumed = mTouchSignal.Emit( handle, touch );
1937 if( !mTouchedSignal.Empty() )
1939 Dali::Actor handle( this );
1940 consumed |= mTouchedSignal.Emit( handle, event );
1945 // Notification for derived classes
1946 consumed = OnTouchEvent( event ); // TODO
1952 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1954 bool consumed = false;
1956 if( !mHoveredSignal.Empty() )
1958 Dali::Actor handle( this );
1959 consumed = mHoveredSignal.Emit( handle, event );
1964 // Notification for derived classes
1965 consumed = OnHoverEvent( event );
1971 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1973 bool consumed = false;
1975 if( !mWheelEventSignal.Empty() )
1977 Dali::Actor handle( this );
1978 consumed = mWheelEventSignal.Emit( handle, event );
1983 // Notification for derived classes
1984 consumed = OnWheelEvent( event );
1990 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1992 if( ! mVisibilityChangedSignal.Empty() )
1994 Dali::Actor handle( this );
1995 mVisibilityChangedSignal.Emit( handle, visible, type );
1999 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
2001 if( ! mLayoutDirectionChangedSignal.Empty() )
2003 Dali::Actor handle( this );
2004 mLayoutDirectionChangedSignal.Emit( handle, type );
2008 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
2010 return mTouchedSignal;
2013 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
2015 return mTouchSignal;
2018 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2020 return mHoveredSignal;
2023 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
2025 return mWheelEventSignal;
2028 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2030 return mOnStageSignal;
2033 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2035 return mOffStageSignal;
2038 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2040 return mOnRelayoutSignal;
2043 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
2045 return mVisibilityChangedSignal;
2048 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
2050 return mLayoutDirectionChangedSignal;
2053 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2055 bool connected( true );
2056 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2058 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2060 actor->TouchedSignal().Connect( tracker, functor );
2062 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2064 actor->HoveredSignal().Connect( tracker, functor );
2066 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2068 actor->WheelEventSignal().Connect( tracker, functor );
2070 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2072 actor->OnStageSignal().Connect( tracker, functor );
2074 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2076 actor->OffStageSignal().Connect( tracker, functor );
2078 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2080 actor->OnRelayoutSignal().Connect( tracker, functor );
2082 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2084 actor->TouchSignal().Connect( tracker, functor );
2088 // signalName does not match any signal
2095 Actor::Actor( DerivedType derivedType )
2100 mParentOrigin( NULL ),
2101 mAnchorPoint( NULL ),
2102 mRelayoutData( NULL ),
2103 mGestureData( NULL ),
2107 mWheelEventSignal(),
2110 mOnRelayoutSignal(),
2111 mVisibilityChangedSignal(),
2112 mLayoutDirectionChangedSignal(),
2113 mTargetOrientation( Quaternion::IDENTITY ),
2114 mTargetColor( Color::WHITE ),
2115 mTargetSize( Vector3::ZERO ),
2116 mTargetPosition( Vector3::ZERO ),
2117 mTargetScale( Vector3::ONE ),
2119 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2122 mIsRoot( ROOT_LAYER == derivedType ),
2123 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2124 mIsOnStage( false ),
2126 mLeaveRequired( false ),
2127 mKeyboardFocusable( false ),
2128 mDerivedRequiresTouch( false ),
2129 mDerivedRequiresHover( false ),
2130 mDerivedRequiresWheelEvent( false ),
2131 mOnStageSignalled( false ),
2132 mInsideOnSizeSet( false ),
2133 mInheritPosition( true ),
2134 mInheritOrientation( true ),
2135 mInheritScale( true ),
2136 mPositionUsesAnchorPoint( true ),
2138 mInheritLayoutDirection( true ),
2139 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2140 mDrawMode( DrawMode::NORMAL ),
2141 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2142 mColorMode( Node::DEFAULT_COLOR_MODE ),
2143 mClippingMode( ClippingMode::DISABLED )
2147 void Actor::Initialize()
2149 // Node creation, keep raw-pointer to Node for messaging
2150 mNode = CreateNode();
2151 OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
2152 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
2156 GetEventThreadServices().RegisterObject( this );
2161 // Remove mParent pointers from children even if we're destroying core,
2162 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2165 ActorConstIter endIter = mChildren->end();
2166 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2168 (*iter)->SetParent( NULL );
2174 // Guard to allow handle destruction after Core has been destroyed
2175 if( EventThreadServices::IsCoreRunning() )
2179 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2180 mNode = NULL; // Node is about to be destroyed
2183 GetEventThreadServices().UnregisterObject( this );
2186 // Cleanup optional gesture data
2187 delete mGestureData;
2189 // Cleanup optional parent origin and anchor
2190 delete mParentOrigin;
2191 delete mAnchorPoint;
2193 // Delete optional relayout data
2196 delete mRelayoutData;
2200 void Actor::ConnectToStage( unsigned int parentDepth )
2202 // This container is used instead of walking the Actor hierarchy.
2203 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2204 ActorContainer connectionList;
2206 StagePtr stage = Stage::GetCurrent();
2209 stage->RequestRebuildDepthTree();
2212 // This stage is atomic i.e. not interrupted by user callbacks.
2213 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2215 // Notify applications about the newly connected actors.
2216 const ActorIter endIter = connectionList.end();
2217 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2219 (*iter)->NotifyStageConnection();
2225 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2227 DALI_ASSERT_ALWAYS( !OnStage() );
2232 ConnectToSceneGraph();
2234 // Notification for internal derived classes
2235 OnStageConnectionInternal();
2237 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2238 connectionList.push_back( ActorPtr( this ) );
2240 // Recursively connect children
2243 ActorConstIter endIter = mChildren->end();
2244 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2246 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2252 * This method is called when the Actor is connected to the Stage.
2253 * The parent must have added its Node to the scene-graph.
2254 * The child must connect its Node to the parent's Node.
2255 * This is recursive; the child calls ConnectToStage() for its children.
2257 void Actor::ConnectToSceneGraph()
2259 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2263 // Reparent Node in next Update
2264 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2267 // Request relayout on all actors that are added to the scenegraph
2270 // Notification for Object::Observers
2274 void Actor::NotifyStageConnection()
2276 // Actors can be removed (in a callback), before the on-stage stage is reported.
2277 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2278 if( OnStage() && !mOnStageSignalled )
2280 // Notification for external (CustomActor) derived classes
2281 OnStageConnectionExternal( mDepth );
2283 if( !mOnStageSignal.Empty() )
2285 Dali::Actor handle( this );
2286 mOnStageSignal.Emit( handle );
2289 // Guard against Remove during callbacks
2292 mOnStageSignalled = true; // signal required next time Actor is removed
2297 void Actor::DisconnectFromStage()
2299 // This container is used instead of walking the Actor hierachy.
2300 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2301 ActorContainer disconnectionList;
2303 StagePtr stage = Stage::GetCurrent();
2306 stage->RequestRebuildDepthTree();
2309 // This stage is atomic i.e. not interrupted by user callbacks
2310 RecursiveDisconnectFromStage( disconnectionList );
2312 // Notify applications about the newly disconnected actors.
2313 const ActorIter endIter = disconnectionList.end();
2314 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2316 (*iter)->NotifyStageDisconnection();
2320 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2322 DALI_ASSERT_ALWAYS( OnStage() );
2324 // Recursively disconnect children
2327 ActorConstIter endIter = mChildren->end();
2328 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2330 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2334 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2335 disconnectionList.push_back( ActorPtr( this ) );
2337 // Notification for internal derived classes
2338 OnStageDisconnectionInternal();
2340 DisconnectFromSceneGraph();
2346 * This method is called by an actor or its parent, before a node removal message is sent.
2347 * This is recursive; the child calls DisconnectFromStage() for its children.
2349 void Actor::DisconnectFromSceneGraph()
2351 // Notification for Object::Observers
2352 OnSceneObjectRemove();
2355 void Actor::NotifyStageDisconnection()
2357 // Actors can be added (in a callback), before the off-stage state is reported.
2358 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2359 // only do this step if there is a stage, i.e. Core is not being shut down
2360 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2362 // Notification for external (CustomeActor) derived classes
2363 OnStageDisconnectionExternal();
2365 if( !mOffStageSignal.Empty() )
2367 Dali::Actor handle( this );
2368 mOffStageSignal.Emit( handle );
2371 // Guard against Add during callbacks
2374 mOnStageSignalled = false; // signal required next time Actor is added
2379 bool Actor::IsNodeConnected() const
2381 bool connected( false );
2383 if( OnStage() && ( NULL != mNode ) )
2385 if( IsRoot() || mNode->GetParent() )
2394 // This method initiates traversal of the actor tree using depth-first
2395 // traversal to set a depth index based on traversal order. It sends a
2396 // single message to update manager to update all the actor's nodes in
2397 // this tree with the depth index. The sceneGraphNodeDepths vector's
2398 // elements are ordered by depth, and could be used to reduce sorting
2399 // in the update thread.
2400 void Actor::RebuildDepthTree()
2402 DALI_LOG_TIMER_START(depthTimer);
2404 // Vector of scene-graph nodes and their depths to send to UpdateManager
2405 // in a single message
2406 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2409 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2411 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2412 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2415 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
2417 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2418 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
2420 // Create/add to children of this node
2423 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2425 Actor* childActor = (*it).Get();
2427 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2432 unsigned int Actor::GetDefaultPropertyCount() const
2434 return DEFAULT_PROPERTY_COUNT;
2437 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2439 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2441 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2443 indices.PushBack( i );
2447 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2449 if( index < DEFAULT_PROPERTY_COUNT )
2451 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2457 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2459 Property::Index index = Property::INVALID_INDEX;
2461 // Look for name in default properties
2462 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2464 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2465 if( 0 == name.compare( property->name ) )
2475 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2477 if( index < DEFAULT_PROPERTY_COUNT )
2479 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2485 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2487 if( index < DEFAULT_PROPERTY_COUNT )
2489 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2495 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2497 if( index < DEFAULT_PROPERTY_COUNT )
2499 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2505 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2507 if( index < DEFAULT_PROPERTY_COUNT )
2509 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2512 // index out of range...return Property::NONE
2513 return Property::NONE;
2516 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2520 case Dali::Actor::Property::PARENT_ORIGIN:
2522 Property::Type type = property.GetType();
2523 if( type == Property::VECTOR3 )
2525 SetParentOrigin( property.Get< Vector3 >() );
2527 else if ( type == Property::STRING )
2529 std::string parentOriginString;
2530 property.Get( parentOriginString );
2531 Vector3 parentOrigin;
2532 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2534 SetParentOrigin( parentOrigin );
2540 case Dali::Actor::Property::PARENT_ORIGIN_X:
2542 SetParentOriginX( property.Get< float >() );
2546 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2548 SetParentOriginY( property.Get< float >() );
2552 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2554 SetParentOriginZ( property.Get< float >() );
2558 case Dali::Actor::Property::ANCHOR_POINT:
2560 Property::Type type = property.GetType();
2561 if( type == Property::VECTOR3 )
2563 SetAnchorPoint( property.Get< Vector3 >() );
2565 else if ( type == Property::STRING )
2567 std::string anchorPointString;
2568 property.Get( anchorPointString );
2570 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2572 SetAnchorPoint( anchor );
2578 case Dali::Actor::Property::ANCHOR_POINT_X:
2580 SetAnchorPointX( property.Get< float >() );
2584 case Dali::Actor::Property::ANCHOR_POINT_Y:
2586 SetAnchorPointY( property.Get< float >() );
2590 case Dali::Actor::Property::ANCHOR_POINT_Z:
2592 SetAnchorPointZ( property.Get< float >() );
2596 case Dali::Actor::Property::SIZE:
2598 SetSize( property.Get< Vector3 >() );
2602 case Dali::Actor::Property::SIZE_WIDTH:
2604 SetWidth( property.Get< float >() );
2608 case Dali::Actor::Property::SIZE_HEIGHT:
2610 SetHeight( property.Get< float >() );
2614 case Dali::Actor::Property::SIZE_DEPTH:
2616 SetDepth( property.Get< float >() );
2620 case Dali::Actor::Property::POSITION:
2622 SetPosition( property.Get< Vector3 >() );
2626 case Dali::Actor::Property::POSITION_X:
2628 SetX( property.Get< float >() );
2632 case Dali::Actor::Property::POSITION_Y:
2634 SetY( property.Get< float >() );
2638 case Dali::Actor::Property::POSITION_Z:
2640 SetZ( property.Get< float >() );
2644 case Dali::Actor::Property::ORIENTATION:
2646 SetOrientation( property.Get< Quaternion >() );
2650 case Dali::Actor::Property::SCALE:
2652 SetScale( property.Get< Vector3 >() );
2656 case Dali::Actor::Property::SCALE_X:
2658 SetScaleX( property.Get< float >() );
2662 case Dali::Actor::Property::SCALE_Y:
2664 SetScaleY( property.Get< float >() );
2668 case Dali::Actor::Property::SCALE_Z:
2670 SetScaleZ( property.Get< float >() );
2674 case Dali::Actor::Property::VISIBLE:
2676 SetVisible( property.Get< bool >() );
2680 case Dali::Actor::Property::COLOR:
2682 SetColor( property.Get< Vector4 >() );
2686 case Dali::Actor::Property::COLOR_RED:
2688 SetColorRed( property.Get< float >() );
2692 case Dali::Actor::Property::COLOR_GREEN:
2694 SetColorGreen( property.Get< float >() );
2698 case Dali::Actor::Property::COLOR_BLUE:
2700 SetColorBlue( property.Get< float >() );
2704 case Dali::Actor::Property::COLOR_ALPHA:
2705 case Dali::DevelActor::Property::OPACITY:
2708 if( property.Get( value ) )
2710 SetOpacity( value );
2715 case Dali::Actor::Property::NAME:
2717 SetName( property.Get< std::string >() );
2721 case Dali::Actor::Property::SENSITIVE:
2723 SetSensitive( property.Get< bool >() );
2727 case Dali::Actor::Property::LEAVE_REQUIRED:
2729 SetLeaveRequired( property.Get< bool >() );
2733 case Dali::Actor::Property::INHERIT_POSITION:
2735 SetInheritPosition( property.Get< bool >() );
2739 case Dali::Actor::Property::INHERIT_ORIENTATION:
2741 SetInheritOrientation( property.Get< bool >() );
2745 case Dali::Actor::Property::INHERIT_SCALE:
2747 SetInheritScale( property.Get< bool >() );
2751 case Dali::Actor::Property::COLOR_MODE:
2753 ColorMode mode = mColorMode;
2754 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2756 SetColorMode( mode );
2761 case Dali::Actor::Property::POSITION_INHERITANCE:
2763 PositionInheritanceMode mode = mPositionInheritanceMode;
2764 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2766 SetPositionInheritanceMode( mode );
2771 case Dali::Actor::Property::DRAW_MODE:
2773 DrawMode::Type mode = mDrawMode;
2774 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2776 SetDrawMode( mode );
2781 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2783 SetSizeModeFactor( property.Get< Vector3 >() );
2787 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2789 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2790 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2792 SetResizePolicy( type, Dimension::WIDTH );
2797 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2799 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2800 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2802 SetResizePolicy( type, Dimension::HEIGHT );
2807 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2809 SizeScalePolicy::Type type;
2810 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2812 SetSizeScalePolicy( type );
2817 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2819 if( property.Get< bool >() )
2821 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2826 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2828 if( property.Get< bool >() )
2830 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2835 case Dali::Actor::Property::PADDING:
2837 Vector4 padding = property.Get< Vector4 >();
2838 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2839 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2843 case Dali::Actor::Property::MINIMUM_SIZE:
2845 Vector2 size = property.Get< Vector2 >();
2846 SetMinimumSize( size.x, Dimension::WIDTH );
2847 SetMinimumSize( size.y, Dimension::HEIGHT );
2851 case Dali::Actor::Property::MAXIMUM_SIZE:
2853 Vector2 size = property.Get< Vector2 >();
2854 SetMaximumSize( size.x, Dimension::WIDTH );
2855 SetMaximumSize( size.y, Dimension::HEIGHT );
2859 case Dali::DevelActor::Property::SIBLING_ORDER:
2863 if( property.Get( value ) )
2865 SetSiblingOrder( value );
2870 case Dali::Actor::Property::CLIPPING_MODE:
2872 ClippingMode::Type convertedValue = mClippingMode;
2873 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2875 mClippingMode = convertedValue;
2878 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2884 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2887 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2889 mPositionUsesAnchorPoint = value;
2892 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2898 case Dali::Actor::Property::LAYOUT_DIRECTION:
2900 Dali::LayoutDirection::Type direction = mLayoutDirection;
2901 mInheritLayoutDirection = false;
2903 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2905 InheritLayoutDirectionRecursively( this, direction, true );
2910 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2913 if( property.Get( value ) )
2915 SetInheritLayoutDirection( value );
2922 // this can happen in the case of a non-animatable default property so just do nothing
2928 // TODO: This method needs to be removed
2929 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2931 switch( entry.GetType() )
2933 case Property::BOOLEAN:
2935 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2936 DALI_ASSERT_DEBUG( NULL != property );
2938 // property is being used in a separate thread; queue a message to set the property
2939 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2944 case Property::INTEGER:
2946 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2947 DALI_ASSERT_DEBUG( NULL != property );
2949 // property is being used in a separate thread; queue a message to set the property
2950 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2955 case Property::FLOAT:
2957 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2958 DALI_ASSERT_DEBUG( NULL != property );
2960 // property is being used in a separate thread; queue a message to set the property
2961 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2966 case Property::VECTOR2:
2968 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2969 DALI_ASSERT_DEBUG( NULL != property );
2971 // property is being used in a separate thread; queue a message to set the property
2972 if(entry.componentIndex == 0)
2974 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2976 else if(entry.componentIndex == 1)
2978 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2982 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2988 case Property::VECTOR3:
2990 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2991 DALI_ASSERT_DEBUG( NULL != property );
2993 // property is being used in a separate thread; queue a message to set the property
2994 if(entry.componentIndex == 0)
2996 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2998 else if(entry.componentIndex == 1)
3000 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
3002 else if(entry.componentIndex == 2)
3004 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
3008 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
3014 case Property::VECTOR4:
3016 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
3017 DALI_ASSERT_DEBUG( NULL != property );
3019 // property is being used in a separate thread; queue a message to set the property
3020 if(entry.componentIndex == 0)
3022 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3024 else if(entry.componentIndex == 1)
3026 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3028 else if(entry.componentIndex == 2)
3030 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3032 else if(entry.componentIndex == 3)
3034 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3038 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3044 case Property::ROTATION:
3046 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3047 DALI_ASSERT_DEBUG( NULL != property );
3049 // property is being used in a separate thread; queue a message to set the property
3050 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
3055 case Property::MATRIX:
3057 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3058 DALI_ASSERT_DEBUG( NULL != property );
3060 // property is being used in a separate thread; queue a message to set the property
3061 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
3066 case Property::MATRIX3:
3068 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3069 DALI_ASSERT_DEBUG( NULL != property );
3071 // property is being used in a separate thread; queue a message to set the property
3072 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
3079 // nothing to do for other types
3084 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3086 Property::Value value;
3088 if( ! GetCachedPropertyValue( index, value ) )
3090 // If property value is not stored in the event-side, then it must be a scene-graph only property
3091 GetCurrentPropertyValue( index, value );
3097 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3099 Property::Value value;
3101 if( ! GetCurrentPropertyValue( index, value ) )
3103 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3104 GetCachedPropertyValue( index, value );
3110 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3112 switch( animationType )
3115 case Animation::BETWEEN:
3119 case Dali::Actor::Property::SIZE:
3121 if( value.Get( mTargetSize ) )
3123 // Notify deriving classes
3124 OnSizeAnimation( animation, mTargetSize );
3129 case Dali::Actor::Property::SIZE_WIDTH:
3131 if( value.Get( mTargetSize.width ) )
3133 // Notify deriving classes
3134 OnSizeAnimation( animation, mTargetSize );
3139 case Dali::Actor::Property::SIZE_HEIGHT:
3141 if( value.Get( mTargetSize.height ) )
3143 // Notify deriving classes
3144 OnSizeAnimation( animation, mTargetSize );
3149 case Dali::Actor::Property::SIZE_DEPTH:
3151 if( value.Get( mTargetSize.depth ) )
3153 // Notify deriving classes
3154 OnSizeAnimation( animation, mTargetSize );
3159 case Dali::Actor::Property::POSITION:
3161 value.Get( mTargetPosition );
3165 case Dali::Actor::Property::POSITION_X:
3167 value.Get( mTargetPosition.x );
3171 case Dali::Actor::Property::POSITION_Y:
3173 value.Get( mTargetPosition.y );
3177 case Dali::Actor::Property::POSITION_Z:
3179 value.Get( mTargetPosition.z );
3183 case Dali::Actor::Property::ORIENTATION:
3185 value.Get( mTargetOrientation );
3189 case Dali::Actor::Property::SCALE:
3191 value.Get( mTargetScale );
3195 case Dali::Actor::Property::SCALE_X:
3197 value.Get( mTargetScale.x );
3201 case Dali::Actor::Property::SCALE_Y:
3203 value.Get( mTargetScale.y );
3207 case Dali::Actor::Property::SCALE_Z:
3209 value.Get( mTargetScale.z );
3213 case Dali::Actor::Property::VISIBLE:
3215 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3219 case Dali::Actor::Property::COLOR:
3221 value.Get( mTargetColor );
3225 case Dali::Actor::Property::COLOR_RED:
3227 value.Get( mTargetColor.r );
3231 case Dali::Actor::Property::COLOR_GREEN:
3233 value.Get( mTargetColor.g );
3237 case Dali::Actor::Property::COLOR_BLUE:
3239 value.Get( mTargetColor.b );
3243 case Dali::Actor::Property::COLOR_ALPHA:
3244 case Dali::DevelActor::Property::OPACITY:
3246 value.Get( mTargetColor.a );
3252 // Not an animatable property. Do nothing.
3263 case Dali::Actor::Property::SIZE:
3265 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3267 // Notify deriving classes
3268 OnSizeAnimation( animation, mTargetSize );
3273 case Dali::Actor::Property::SIZE_WIDTH:
3275 if( AdjustValue< float >( mTargetSize.width, value ) )
3277 // Notify deriving classes
3278 OnSizeAnimation( animation, mTargetSize );
3283 case Dali::Actor::Property::SIZE_HEIGHT:
3285 if( AdjustValue< float >( mTargetSize.height, value ) )
3287 // Notify deriving classes
3288 OnSizeAnimation( animation, mTargetSize );
3293 case Dali::Actor::Property::SIZE_DEPTH:
3295 if( AdjustValue< float >( mTargetSize.depth, value ) )
3297 // Notify deriving classes
3298 OnSizeAnimation( animation, mTargetSize );
3303 case Dali::Actor::Property::POSITION:
3305 AdjustValue< Vector3 >( mTargetPosition, value );
3309 case Dali::Actor::Property::POSITION_X:
3311 AdjustValue< float >( mTargetPosition.x, value );
3315 case Dali::Actor::Property::POSITION_Y:
3317 AdjustValue< float >( mTargetPosition.y, value );
3321 case Dali::Actor::Property::POSITION_Z:
3323 AdjustValue< float >( mTargetPosition.z, value );
3327 case Dali::Actor::Property::ORIENTATION:
3329 Quaternion relativeValue;
3330 if( value.Get( relativeValue ) )
3332 mTargetOrientation *= relativeValue;
3337 case Dali::Actor::Property::SCALE:
3339 AdjustValue< Vector3 >( mTargetScale, value );
3343 case Dali::Actor::Property::SCALE_X:
3345 AdjustValue< float >( mTargetScale.x, value );
3349 case Dali::Actor::Property::SCALE_Y:
3351 AdjustValue< float >( mTargetScale.y, value );
3355 case Dali::Actor::Property::SCALE_Z:
3357 AdjustValue< float >( mTargetScale.z, value );
3361 case Dali::Actor::Property::VISIBLE:
3363 bool relativeValue = false;
3364 if( value.Get( relativeValue ) )
3366 bool visible = mVisible || relativeValue;
3367 SetVisibleInternal( visible, SendMessage::FALSE );
3372 case Dali::Actor::Property::COLOR:
3374 AdjustValue< Vector4 >( mTargetColor, value );
3378 case Dali::Actor::Property::COLOR_RED:
3380 AdjustValue< float >( mTargetColor.r, value );
3384 case Dali::Actor::Property::COLOR_GREEN:
3386 AdjustValue< float >( mTargetColor.g, value );
3390 case Dali::Actor::Property::COLOR_BLUE:
3392 AdjustValue< float >( mTargetColor.b, value );
3396 case Dali::Actor::Property::COLOR_ALPHA:
3397 case Dali::DevelActor::Property::OPACITY:
3399 AdjustValue< float >( mTargetColor.a, value );
3405 // Not an animatable property. Do nothing.
3414 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3419 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3421 // This method should only return an object connected to the scene-graph
3422 return OnStage() ? mNode : NULL;
3425 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3427 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3429 const PropertyBase* property( NULL );
3431 // This method should only return a property of an object connected to the scene-graph
3437 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3439 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3440 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3442 property = animatable->GetSceneGraphProperty();
3444 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3445 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3447 CustomPropertyMetadata* custom = FindCustomProperty( index );
3448 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3450 property = custom->GetSceneGraphProperty();
3452 else if( NULL != mNode )
3456 case Dali::Actor::Property::SIZE:
3457 property = &mNode->mSize;
3460 case Dali::Actor::Property::SIZE_WIDTH:
3461 property = &mNode->mSize;
3464 case Dali::Actor::Property::SIZE_HEIGHT:
3465 property = &mNode->mSize;
3468 case Dali::Actor::Property::SIZE_DEPTH:
3469 property = &mNode->mSize;
3472 case Dali::Actor::Property::POSITION:
3473 property = &mNode->mPosition;
3476 case Dali::Actor::Property::POSITION_X:
3477 property = &mNode->mPosition;
3480 case Dali::Actor::Property::POSITION_Y:
3481 property = &mNode->mPosition;
3484 case Dali::Actor::Property::POSITION_Z:
3485 property = &mNode->mPosition;
3488 case Dali::Actor::Property::ORIENTATION:
3489 property = &mNode->mOrientation;
3492 case Dali::Actor::Property::SCALE:
3493 property = &mNode->mScale;
3496 case Dali::Actor::Property::SCALE_X:
3497 property = &mNode->mScale;
3500 case Dali::Actor::Property::SCALE_Y:
3501 property = &mNode->mScale;
3504 case Dali::Actor::Property::SCALE_Z:
3505 property = &mNode->mScale;
3508 case Dali::Actor::Property::VISIBLE:
3509 property = &mNode->mVisible;
3512 case Dali::Actor::Property::COLOR:
3513 property = &mNode->mColor;
3516 case Dali::Actor::Property::COLOR_RED:
3517 property = &mNode->mColor;
3520 case Dali::Actor::Property::COLOR_GREEN:
3521 property = &mNode->mColor;
3524 case Dali::Actor::Property::COLOR_BLUE:
3525 property = &mNode->mColor;
3528 case Dali::Actor::Property::COLOR_ALPHA:
3529 case Dali::DevelActor::Property::OPACITY:
3530 property = &mNode->mColor;
3541 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3543 const PropertyInputImpl* property( NULL );
3545 // This method should only return a property of an object connected to the scene-graph
3551 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3553 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3554 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3556 property = animatable->GetSceneGraphProperty();
3558 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3559 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3561 CustomPropertyMetadata* custom = FindCustomProperty( index );
3562 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3563 property = custom->GetSceneGraphProperty();
3565 else if( NULL != mNode )
3569 case Dali::Actor::Property::PARENT_ORIGIN:
3570 property = &mNode->mParentOrigin;
3573 case Dali::Actor::Property::PARENT_ORIGIN_X:
3574 property = &mNode->mParentOrigin;
3577 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3578 property = &mNode->mParentOrigin;
3581 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3582 property = &mNode->mParentOrigin;
3585 case Dali::Actor::Property::ANCHOR_POINT:
3586 property = &mNode->mAnchorPoint;
3589 case Dali::Actor::Property::ANCHOR_POINT_X:
3590 property = &mNode->mAnchorPoint;
3593 case Dali::Actor::Property::ANCHOR_POINT_Y:
3594 property = &mNode->mAnchorPoint;
3597 case Dali::Actor::Property::ANCHOR_POINT_Z:
3598 property = &mNode->mAnchorPoint;
3601 case Dali::Actor::Property::SIZE:
3602 property = &mNode->mSize;
3605 case Dali::Actor::Property::SIZE_WIDTH:
3606 property = &mNode->mSize;
3609 case Dali::Actor::Property::SIZE_HEIGHT:
3610 property = &mNode->mSize;
3613 case Dali::Actor::Property::SIZE_DEPTH:
3614 property = &mNode->mSize;
3617 case Dali::Actor::Property::POSITION:
3618 property = &mNode->mPosition;
3621 case Dali::Actor::Property::POSITION_X:
3622 property = &mNode->mPosition;
3625 case Dali::Actor::Property::POSITION_Y:
3626 property = &mNode->mPosition;
3629 case Dali::Actor::Property::POSITION_Z:
3630 property = &mNode->mPosition;
3633 case Dali::Actor::Property::WORLD_POSITION:
3634 property = &mNode->mWorldPosition;
3637 case Dali::Actor::Property::WORLD_POSITION_X:
3638 property = &mNode->mWorldPosition;
3641 case Dali::Actor::Property::WORLD_POSITION_Y:
3642 property = &mNode->mWorldPosition;
3645 case Dali::Actor::Property::WORLD_POSITION_Z:
3646 property = &mNode->mWorldPosition;
3649 case Dali::Actor::Property::ORIENTATION:
3650 property = &mNode->mOrientation;
3653 case Dali::Actor::Property::WORLD_ORIENTATION:
3654 property = &mNode->mWorldOrientation;
3657 case Dali::Actor::Property::SCALE:
3658 property = &mNode->mScale;
3661 case Dali::Actor::Property::SCALE_X:
3662 property = &mNode->mScale;
3665 case Dali::Actor::Property::SCALE_Y:
3666 property = &mNode->mScale;
3669 case Dali::Actor::Property::SCALE_Z:
3670 property = &mNode->mScale;
3673 case Dali::Actor::Property::WORLD_SCALE:
3674 property = &mNode->mWorldScale;
3677 case Dali::Actor::Property::VISIBLE:
3678 property = &mNode->mVisible;
3681 case Dali::Actor::Property::COLOR:
3682 property = &mNode->mColor;
3685 case Dali::Actor::Property::COLOR_RED:
3686 property = &mNode->mColor;
3689 case Dali::Actor::Property::COLOR_GREEN:
3690 property = &mNode->mColor;
3693 case Dali::Actor::Property::COLOR_BLUE:
3694 property = &mNode->mColor;
3697 case Dali::Actor::Property::COLOR_ALPHA:
3698 case Dali::DevelActor::Property::OPACITY:
3700 property = &mNode->mColor;
3704 case Dali::Actor::Property::WORLD_COLOR:
3705 property = &mNode->mWorldColor;
3708 case Dali::Actor::Property::WORLD_MATRIX:
3709 property = &mNode->mWorldMatrix;
3720 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3722 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3724 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3726 // check whether the animatable property is registered already, if not then register one.
3727 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3728 if( animatableProperty )
3730 componentIndex = animatableProperty->componentIndex;
3737 case Dali::Actor::Property::PARENT_ORIGIN_X:
3738 case Dali::Actor::Property::ANCHOR_POINT_X:
3739 case Dali::Actor::Property::SIZE_WIDTH:
3740 case Dali::Actor::Property::POSITION_X:
3741 case Dali::Actor::Property::WORLD_POSITION_X:
3742 case Dali::Actor::Property::SCALE_X:
3743 case Dali::Actor::Property::COLOR_RED:
3749 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3750 case Dali::Actor::Property::ANCHOR_POINT_Y:
3751 case Dali::Actor::Property::SIZE_HEIGHT:
3752 case Dali::Actor::Property::POSITION_Y:
3753 case Dali::Actor::Property::WORLD_POSITION_Y:
3754 case Dali::Actor::Property::SCALE_Y:
3755 case Dali::Actor::Property::COLOR_GREEN:
3761 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3762 case Dali::Actor::Property::ANCHOR_POINT_Z:
3763 case Dali::Actor::Property::SIZE_DEPTH:
3764 case Dali::Actor::Property::POSITION_Z:
3765 case Dali::Actor::Property::WORLD_POSITION_Z:
3766 case Dali::Actor::Property::SCALE_Z:
3767 case Dali::Actor::Property::COLOR_BLUE:
3773 case Dali::Actor::Property::COLOR_ALPHA:
3774 case Dali::DevelActor::Property::OPACITY:
3788 return componentIndex;
3791 void Actor::SetParent( Actor* parent )
3795 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3799 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3802 // Instruct each actor to create a corresponding node in the scene graph
3803 ConnectToStage( parent->GetHierarchyDepth() );
3806 // Resolve the name and index for the child properties if any
3807 ResolveChildProperties();
3809 else // parent being set to NULL
3811 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3815 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3818 DALI_ASSERT_ALWAYS( mNode != NULL );
3822 // Disconnect the Node & its children from the scene-graph.
3823 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3826 // Instruct each actor to discard pointers to the scene-graph
3827 DisconnectFromStage();
3832 SceneGraph::Node* Actor::CreateNode() const
3837 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3840 Actor* actor = dynamic_cast< Actor* >( object );
3844 if( 0 == actionName.compare( ACTION_SHOW ) )
3846 actor->SetVisible( true );
3849 else if( 0 == actionName.compare( ACTION_HIDE ) )
3851 actor->SetVisible( false );
3859 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3861 bool valueSet = true;
3865 case Dali::Actor::Property::PARENT_ORIGIN:
3867 value = GetCurrentParentOrigin();
3871 case Dali::Actor::Property::PARENT_ORIGIN_X:
3873 value = GetCurrentParentOrigin().x;
3877 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3879 value = GetCurrentParentOrigin().y;
3883 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3885 value = GetCurrentParentOrigin().z;
3889 case Dali::Actor::Property::ANCHOR_POINT:
3891 value = GetCurrentAnchorPoint();
3895 case Dali::Actor::Property::ANCHOR_POINT_X:
3897 value = GetCurrentAnchorPoint().x;
3901 case Dali::Actor::Property::ANCHOR_POINT_Y:
3903 value = GetCurrentAnchorPoint().y;
3907 case Dali::Actor::Property::ANCHOR_POINT_Z:
3909 value = GetCurrentAnchorPoint().z;
3913 case Dali::Actor::Property::SIZE:
3915 value = GetTargetSize();
3919 case Dali::Actor::Property::SIZE_WIDTH:
3921 value = GetTargetSize().width;
3925 case Dali::Actor::Property::SIZE_HEIGHT:
3927 value = GetTargetSize().height;
3931 case Dali::Actor::Property::SIZE_DEPTH:
3933 value = GetTargetSize().depth;
3937 case Dali::Actor::Property::POSITION:
3939 value = GetTargetPosition();
3943 case Dali::Actor::Property::POSITION_X:
3945 value = GetTargetPosition().x;
3949 case Dali::Actor::Property::POSITION_Y:
3951 value = GetTargetPosition().y;
3955 case Dali::Actor::Property::POSITION_Z:
3957 value = GetTargetPosition().z;
3961 case Dali::Actor::Property::ORIENTATION:
3963 value = mTargetOrientation;
3967 case Dali::Actor::Property::SCALE:
3969 value = mTargetScale;
3973 case Dali::Actor::Property::SCALE_X:
3975 value = mTargetScale.x;
3979 case Dali::Actor::Property::SCALE_Y:
3981 value = mTargetScale.y;
3985 case Dali::Actor::Property::SCALE_Z:
3987 value = mTargetScale.z;
3991 case Dali::Actor::Property::VISIBLE:
3997 case Dali::Actor::Property::COLOR:
3999 value = mTargetColor;
4003 case Dali::Actor::Property::COLOR_RED:
4005 value = mTargetColor.r;
4009 case Dali::Actor::Property::COLOR_GREEN:
4011 value = mTargetColor.g;
4015 case Dali::Actor::Property::COLOR_BLUE:
4017 value = mTargetColor.b;
4021 case Dali::Actor::Property::COLOR_ALPHA:
4022 case Dali::DevelActor::Property::OPACITY:
4024 value = mTargetColor.a;
4028 case Dali::Actor::Property::NAME:
4034 case Dali::Actor::Property::SENSITIVE:
4036 value = IsSensitive();
4040 case Dali::Actor::Property::LEAVE_REQUIRED:
4042 value = GetLeaveRequired();
4046 case Dali::Actor::Property::INHERIT_POSITION:
4048 value = IsPositionInherited();
4052 case Dali::Actor::Property::INHERIT_ORIENTATION:
4054 value = IsOrientationInherited();
4058 case Dali::Actor::Property::INHERIT_SCALE:
4060 value = IsScaleInherited();
4064 case Dali::Actor::Property::COLOR_MODE:
4066 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4070 case Dali::Actor::Property::POSITION_INHERITANCE:
4072 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4076 case Dali::Actor::Property::DRAW_MODE:
4078 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4082 case Dali::Actor::Property::SIZE_MODE_FACTOR:
4084 value = GetSizeModeFactor();
4088 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4090 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4094 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4096 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4100 case Dali::Actor::Property::SIZE_SCALE_POLICY:
4102 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4106 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4108 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4112 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4114 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4118 case Dali::Actor::Property::PADDING:
4120 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4121 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4122 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4126 case Dali::Actor::Property::MINIMUM_SIZE:
4128 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4132 case Dali::Actor::Property::MAXIMUM_SIZE:
4134 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4138 case Dali::Actor::Property::CLIPPING_MODE:
4140 value = mClippingMode;
4144 case Dali::DevelActor::Property::SIBLING_ORDER:
4146 value = static_cast<int>( GetSiblingOrder() );
4150 case Dali::DevelActor::Property::SCREEN_POSITION:
4152 value = GetCurrentScreenPosition();
4156 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4158 value = mPositionUsesAnchorPoint;
4162 case Dali::Actor::Property::LAYOUT_DIRECTION:
4164 value = mLayoutDirection;
4168 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
4170 value = IsLayoutDirectionInherited();
4176 // Must be a scene-graph only property
4185 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
4187 bool valueSet = true;
4191 case Dali::Actor::Property::SIZE:
4193 value = GetCurrentSize();
4197 case Dali::Actor::Property::SIZE_WIDTH:
4199 value = GetCurrentSize().width;
4203 case Dali::Actor::Property::SIZE_HEIGHT:
4205 value = GetCurrentSize().height;
4209 case Dali::Actor::Property::SIZE_DEPTH:
4211 value = GetCurrentSize().depth;
4215 case Dali::Actor::Property::POSITION:
4217 value = GetCurrentPosition();
4221 case Dali::Actor::Property::POSITION_X:
4223 value = GetCurrentPosition().x;
4227 case Dali::Actor::Property::POSITION_Y:
4229 value = GetCurrentPosition().y;
4233 case Dali::Actor::Property::POSITION_Z:
4235 value = GetCurrentPosition().z;
4239 case Dali::Actor::Property::WORLD_POSITION:
4241 value = GetCurrentWorldPosition();
4245 case Dali::Actor::Property::WORLD_POSITION_X:
4247 value = GetCurrentWorldPosition().x;
4251 case Dali::Actor::Property::WORLD_POSITION_Y:
4253 value = GetCurrentWorldPosition().y;
4257 case Dali::Actor::Property::WORLD_POSITION_Z:
4259 value = GetCurrentWorldPosition().z;
4263 case Dali::Actor::Property::ORIENTATION:
4265 value = GetCurrentOrientation();
4269 case Dali::Actor::Property::WORLD_ORIENTATION:
4271 value = GetCurrentWorldOrientation();
4275 case Dali::Actor::Property::SCALE:
4277 value = GetCurrentScale();
4281 case Dali::Actor::Property::SCALE_X:
4283 value = GetCurrentScale().x;
4287 case Dali::Actor::Property::SCALE_Y:
4289 value = GetCurrentScale().y;
4293 case Dali::Actor::Property::SCALE_Z:
4295 value = GetCurrentScale().z;
4299 case Dali::Actor::Property::WORLD_SCALE:
4301 value = GetCurrentWorldScale();
4305 case Dali::Actor::Property::COLOR:
4307 value = GetCurrentColor();
4311 case Dali::Actor::Property::COLOR_RED:
4313 value = GetCurrentColor().r;
4317 case Dali::Actor::Property::COLOR_GREEN:
4319 value = GetCurrentColor().g;
4323 case Dali::Actor::Property::COLOR_BLUE:
4325 value = GetCurrentColor().b;
4329 case Dali::Actor::Property::COLOR_ALPHA:
4330 case Dali::DevelActor::Property::OPACITY:
4332 value = GetCurrentColor().a;
4336 case Dali::Actor::Property::WORLD_COLOR:
4338 value = GetCurrentWorldColor();
4342 case Dali::Actor::Property::WORLD_MATRIX:
4344 value = GetCurrentWorldMatrix();
4348 case Dali::Actor::Property::VISIBLE:
4350 value = IsVisible();
4356 // Must be an event-side only property
4365 void Actor::EnsureRelayoutData()
4367 // Assign relayout data.
4368 if( !mRelayoutData )
4370 mRelayoutData = new RelayoutData();
4374 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4376 // Check if actor is dependent on parent
4377 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4379 if( ( dimension & ( 1 << i ) ) )
4381 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4382 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4392 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4394 // Check if actor is dependent on children
4395 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4397 if( ( dimension & ( 1 << i ) ) )
4399 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4400 switch( resizePolicy )
4402 case ResizePolicy::FIT_TO_CHILDREN:
4403 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4419 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4421 return Actor::RelayoutDependentOnChildren( dimension );
4424 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4426 // Check each possible dimension and see if it is dependent on the input one
4427 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4429 if( dimension & ( 1 << i ) )
4431 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4438 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4440 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4442 if( dimension & ( 1 << i ) )
4444 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4449 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4451 // If more than one dimension is requested, just return the first one found
4452 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4454 if( ( dimension & ( 1 << i ) ) )
4456 return mRelayoutData->negotiatedDimensions[ i ];
4460 return 0.0f; // Default
4463 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4465 EnsureRelayoutData();
4467 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4469 if( dimension & ( 1 << i ) )
4471 mRelayoutData->dimensionPadding[ i ] = padding;
4476 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4478 if ( mRelayoutData )
4480 // If more than one dimension is requested, just return the first one found
4481 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4483 if( ( dimension & ( 1 << i ) ) )
4485 return mRelayoutData->dimensionPadding[ i ];
4490 return GetDefaultDimensionPadding();
4493 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4495 EnsureRelayoutData();
4497 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4499 if( dimension & ( 1 << i ) )
4501 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4506 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4508 if ( mRelayoutData )
4510 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4512 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4522 float Actor::GetHeightForWidthBase( float width )
4524 float height = 0.0f;
4526 const Vector3 naturalSize = GetNaturalSize();
4527 if( naturalSize.width > 0.0f )
4529 height = naturalSize.height * width / naturalSize.width;
4531 else // we treat 0 as 1:1 aspect ratio
4539 float Actor::GetWidthForHeightBase( float height )
4543 const Vector3 naturalSize = GetNaturalSize();
4544 if( naturalSize.height > 0.0f )
4546 width = naturalSize.width * height / naturalSize.height;
4548 else // we treat 0 as 1:1 aspect ratio
4556 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4558 // Fill to parent, taking size mode factor into account
4559 switch( child.GetResizePolicy( dimension ) )
4561 case ResizePolicy::FILL_TO_PARENT:
4563 return GetLatestSize( dimension );
4566 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4568 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4571 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4573 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4578 return GetLatestSize( dimension );
4583 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4585 // Can be overridden in derived class
4586 return CalculateChildSizeBase( child, dimension );
4589 float Actor::GetHeightForWidth( float width )
4591 // Can be overridden in derived class
4592 return GetHeightForWidthBase( width );
4595 float Actor::GetWidthForHeight( float height )
4597 // Can be overridden in derived class
4598 return GetWidthForHeightBase( height );
4601 float Actor::GetLatestSize( Dimension::Type dimension ) const
4603 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4606 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4608 Vector2 padding = GetPadding( dimension );
4610 return GetLatestSize( dimension ) + padding.x + padding.y;
4613 float Actor::NegotiateFromParent( Dimension::Type dimension )
4615 Actor* parent = GetParent();
4618 Vector2 padding( GetPadding( dimension ) );
4619 Vector2 parentPadding( parent->GetPadding( dimension ) );
4620 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4626 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4628 float maxDimensionPoint = 0.0f;
4630 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4632 ActorPtr child = GetChildAt( i );
4634 if( !child->RelayoutDependentOnParent( dimension ) )
4636 // Calculate the min and max points that the children range across
4637 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4638 float dimensionSize = child->GetRelayoutSize( dimension );
4639 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4643 return maxDimensionPoint;
4646 float Actor::GetSize( Dimension::Type dimension ) const
4648 return GetDimensionValue( mTargetSize, dimension );
4651 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4653 return GetDimensionValue( GetNaturalSize(), dimension );
4656 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4658 switch( GetResizePolicy( dimension ) )
4660 case ResizePolicy::USE_NATURAL_SIZE:
4662 return GetNaturalSize( dimension );
4665 case ResizePolicy::FIXED:
4667 return GetDimensionValue( GetPreferredSize(), dimension );
4670 case ResizePolicy::USE_ASSIGNED_SIZE:
4672 return GetDimensionValue( maximumSize, dimension );
4675 case ResizePolicy::FILL_TO_PARENT:
4676 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4677 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4679 return NegotiateFromParent( dimension );
4682 case ResizePolicy::FIT_TO_CHILDREN:
4684 return NegotiateFromChildren( dimension );
4687 case ResizePolicy::DIMENSION_DEPENDENCY:
4689 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4692 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4694 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4697 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4699 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4711 return 0.0f; // Default
4714 float Actor::ClampDimension( float size, Dimension::Type dimension )
4716 const float minSize = GetMinimumSize( dimension );
4717 const float maxSize = GetMaximumSize( dimension );
4719 return std::max( minSize, std::min( size, maxSize ) );
4722 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4724 // Check if it needs to be negotiated
4725 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4727 // Check that we havn't gotten into an infinite loop
4728 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4729 bool recursionFound = false;
4730 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4732 if( *it == searchActor )
4734 recursionFound = true;
4739 if( !recursionFound )
4741 // Record the path that we have taken
4742 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4744 // Dimension dependency check
4745 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4747 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4749 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4751 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4755 // Parent dependency check
4756 Actor* parent = GetParent();
4757 if( parent && RelayoutDependentOnParent( dimension ) )
4759 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4762 // Children dependency check
4763 if( RelayoutDependentOnChildren( dimension ) )
4765 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4767 ActorPtr child = GetChildAt( i );
4769 // Only relayout child first if it is not dependent on this actor
4770 if( !child->RelayoutDependentOnParent( dimension ) )
4772 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4777 // For deriving classes
4778 OnCalculateRelayoutSize( dimension );
4780 // All dependencies checked, calculate the size and set negotiated flag
4781 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4783 SetNegotiatedDimension( newSize, dimension );
4784 SetLayoutNegotiated( true, dimension );
4786 // For deriving classes
4787 OnLayoutNegotiated( newSize, dimension );
4789 // This actor has been successfully processed, pop it off the recursion stack
4790 recursionStack.pop_back();
4794 // TODO: Break infinite loop
4795 SetLayoutNegotiated( true, dimension );
4800 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4802 // Negotiate all dimensions that require it
4803 ActorDimensionStack recursionStack;
4805 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4807 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4810 NegotiateDimension( dimension, allocatedSize, recursionStack );
4814 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4816 switch( mRelayoutData->sizeSetPolicy )
4818 case SizeScalePolicy::USE_SIZE_SET:
4823 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4825 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4826 const Vector3 naturalSize = GetNaturalSize();
4827 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4829 const float sizeRatio = size.width / size.height;
4830 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4832 if( naturalSizeRatio < sizeRatio )
4834 return Vector2( naturalSizeRatio * size.height, size.height );
4836 else if( naturalSizeRatio > sizeRatio )
4838 return Vector2( size.width, size.width / naturalSizeRatio );
4849 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4851 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4852 const Vector3 naturalSize = GetNaturalSize();
4853 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4855 const float sizeRatio = size.width / size.height;
4856 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4858 if( naturalSizeRatio < sizeRatio )
4860 return Vector2( size.width, size.width / naturalSizeRatio );
4862 else if( naturalSizeRatio > sizeRatio )
4864 return Vector2( naturalSizeRatio * size.height, size.height );
4883 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4885 // Do the set actor size
4886 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4888 // Adjust for size set policy
4889 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4891 // Lock the flag to stop recursive relayouts on set size
4892 mRelayoutData->insideRelayout = true;
4893 SetSize( negotiatedSize );
4894 mRelayoutData->insideRelayout = false;
4896 // Clear flags for all dimensions
4897 SetLayoutDirty( false );
4899 // Give deriving classes a chance to respond
4900 OnRelayout( negotiatedSize, container );
4902 if( !mOnRelayoutSignal.Empty() )
4904 Dali::Actor handle( this );
4905 mOnRelayoutSignal.Emit( handle );
4909 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4911 // Force a size negotiation for actors that has assigned size during relayout
4912 // This is required as otherwise the flags that force a relayout will not
4913 // necessarilly be set. This will occur if the actor has already been laid out.
4914 // The dirty flags are then cleared. Then if the actor is added back into the
4915 // relayout container afterwards, the dirty flags would still be clear...
4916 // causing a relayout to be skipped. Here we force any actors added to the
4917 // container to be relayed out.
4918 DALI_LOG_TIMER_START( NegSizeTimer1 );
4920 if( GetUseAssignedSize(Dimension::WIDTH ) )
4922 SetLayoutNegotiated( false, Dimension::WIDTH );
4924 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4926 SetLayoutNegotiated( false, Dimension::HEIGHT );
4929 // Do the negotiation
4930 NegotiateDimensions( allocatedSize );
4932 // Set the actor size
4933 SetNegotiatedSize( container );
4935 // Negotiate down to children
4936 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4938 ActorPtr child = GetChildAt( i );
4940 // Forces children that have already been laid out to be relayed out
4941 // if they have assigned size during relayout.
4942 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4944 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4945 child->SetLayoutDirty(true, Dimension::WIDTH);
4948 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4950 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4951 child->SetLayoutDirty(true, Dimension::HEIGHT);
4954 // Only relayout if required
4955 if( child->RelayoutRequired() )
4957 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4960 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4963 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4967 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4969 if( dimension & ( 1 << i ) )
4971 mRelayoutData->useAssignedSize[ i ] = use;
4977 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4979 if ( mRelayoutData )
4981 // If more than one dimension is requested, just return the first one found
4982 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4984 if( dimension & ( 1 << i ) )
4986 return mRelayoutData->useAssignedSize[ i ];
4994 void Actor::RelayoutRequest( Dimension::Type dimension )
4996 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4997 if( relayoutController )
4999 Dali::Actor self( this );
5000 relayoutController->RequestRelayout( self, dimension );
5004 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
5008 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
5012 void Actor::SetPreferredSize( const Vector2& size )
5014 EnsureRelayoutData();
5016 if( size.width > 0.0f )
5018 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
5021 if( size.height > 0.0f )
5023 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
5026 mRelayoutData->preferredSize = size;
5031 Vector2 Actor::GetPreferredSize() const
5033 if ( mRelayoutData )
5035 return Vector2( mRelayoutData->preferredSize );
5038 return GetDefaultPreferredSize();
5041 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
5043 EnsureRelayoutData();
5045 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5047 if( dimension & ( 1 << i ) )
5049 mRelayoutData->minimumSize[ i ] = size;
5056 float Actor::GetMinimumSize( Dimension::Type dimension ) const
5058 if ( mRelayoutData )
5060 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5062 if( dimension & ( 1 << i ) )
5064 return mRelayoutData->minimumSize[ i ];
5069 return 0.0f; // Default
5072 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5074 EnsureRelayoutData();
5076 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5078 if( dimension & ( 1 << i ) )
5080 mRelayoutData->maximumSize[ i ] = size;
5087 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5089 if ( mRelayoutData )
5091 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5093 if( dimension & ( 1 << i ) )
5095 return mRelayoutData->maximumSize[ i ];
5100 return FLT_MAX; // Default
5103 Object* Actor::GetParentObject() const
5108 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5110 if( mVisible != visible )
5112 if( sendMessage == SendMessage::TRUE && NULL != mNode )
5114 // mNode is being used in a separate thread; queue a message to set the value & base value
5115 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5120 // Emit the signal on this actor and all its children
5121 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5125 void Actor::SetSiblingOrder( unsigned int order )
5129 ActorContainer& siblings = *(mParent->mChildren);
5130 unsigned int currentOrder = GetSiblingOrder();
5132 if( order != currentOrder )
5138 else if( order < siblings.size() -1 )
5140 if( order > currentOrder )
5142 RaiseAbove( *siblings[order] );
5146 LowerBelow( *siblings[order] );
5157 unsigned int Actor::GetSiblingOrder() const
5159 unsigned int order = 0;
5163 ActorContainer& siblings = *(mParent->mChildren);
5164 for( size_t i=0; i<siblings.size(); ++i )
5166 if( siblings[i] == this )
5177 void Actor::RequestRebuildDepthTree()
5181 StagePtr stage = Stage::GetCurrent();
5184 stage->RequestRebuildDepthTree();
5193 ActorContainer& siblings = *(mParent->mChildren);
5194 if( siblings.back() != this ) // If not already at end
5196 for( size_t i=0; i<siblings.size(); ++i )
5198 if( siblings[i] == this )
5201 ActorPtr next = siblings[i+1];
5202 siblings[i+1] = this;
5208 RequestRebuildDepthTree();
5212 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5220 ActorContainer& siblings = *(mParent->mChildren);
5221 if( siblings.front() != this ) // If not already at beginning
5223 for( size_t i=1; i<siblings.size(); ++i )
5225 if( siblings[i] == this )
5227 // Swap with previous
5228 ActorPtr previous = siblings[i-1];
5229 siblings[i-1] = this;
5230 siblings[i] = previous;
5235 RequestRebuildDepthTree();
5239 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5243 void Actor::RaiseToTop()
5247 ActorContainer& siblings = *(mParent->mChildren);
5248 if( siblings.back() != this ) // If not already at end
5250 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5251 if( iter != siblings.end() )
5253 siblings.erase(iter);
5254 siblings.push_back(ActorPtr(this));
5257 RequestRebuildDepthTree();
5261 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5265 void Actor::LowerToBottom()
5269 ActorContainer& siblings = *(mParent->mChildren);
5270 if( siblings.front() != this ) // If not already at bottom,
5272 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5274 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5275 if( iter != siblings.end() )
5277 siblings.erase(iter);
5278 siblings.insert(siblings.begin(), thisPtr);
5281 RequestRebuildDepthTree();
5285 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5289 void Actor::RaiseAbove( Internal::Actor& target )
5293 ActorContainer& siblings = *(mParent->mChildren);
5294 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5296 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5298 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5299 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5300 if( thisIter < targetIter )
5302 siblings.erase(thisIter);
5303 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5304 // invalidate thisIter)
5305 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5307 siblings.insert(targetIter, thisPtr);
5309 RequestRebuildDepthTree();
5314 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5318 void Actor::LowerBelow( Internal::Actor& target )
5322 ActorContainer& siblings = *(mParent->mChildren);
5323 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5325 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5327 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5328 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5330 if( thisIter > targetIter )
5332 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5333 siblings.insert(targetIter, thisPtr);
5335 RequestRebuildDepthTree();
5340 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5344 void Actor::SetInheritLayoutDirection( bool inherit )
5346 if( mInheritLayoutDirection != inherit )
5348 mInheritLayoutDirection = inherit;
5350 if( inherit && mParent )
5352 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5357 bool Actor::IsLayoutDirectionInherited() const
5359 return mInheritLayoutDirection;
5362 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5364 if( actor && ( actor->mInheritLayoutDirection || set ) )
5366 if( actor->mLayoutDirection != direction)
5368 actor->mLayoutDirection = direction;
5369 actor->EmitLayoutDirectionChangedSignal( direction );
5370 actor->RelayoutRequest();
5373 if( actor->GetChildCount() > 0 )
5375 ActorContainer& children = actor->GetChildrenInternal();
5376 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5378 InheritLayoutDirectionRecursively( *iter, direction );
5384 } // namespace Internal