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/object/weak-handle.h>
37 #include <dali/devel-api/scripting/scripting.h>
38 #include <dali/internal/common/internal-constants.h>
39 #include <dali/internal/event/common/event-thread-services.h>
40 #include <dali/internal/event/render-tasks/render-task-impl.h>
41 #include <dali/internal/event/actors/camera-actor-impl.h>
42 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
43 #include <dali/internal/event/common/property-helper.h>
44 #include <dali/internal/event/common/stage-impl.h>
45 #include <dali/internal/event/common/type-info-impl.h>
46 #include <dali/internal/event/animation/constraint-impl.h>
47 #include <dali/internal/event/common/projection.h>
48 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
49 #include <dali/internal/update/common/animatable-property.h>
50 #include <dali/internal/update/nodes/node-messages.h>
51 #include <dali/internal/update/nodes/node-declarations.h>
52 #include <dali/internal/update/animation/scene-graph-constraint.h>
53 #include <dali/internal/event/events/actor-gesture-data.h>
54 #include <dali/internal/common/message.h>
55 #include <dali/integration-api/debug.h>
57 using Dali::Internal::SceneGraph::Node;
58 using Dali::Internal::SceneGraph::AnimatableProperty;
59 using Dali::Internal::SceneGraph::PropertyBase;
61 #if defined(DEBUG_ENABLED)
62 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
63 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
72 unsigned int Actor::mActorCounter = 0;
76 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
77 inline const Vector3& GetDefaultSizeModeFactor()
82 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
83 inline const Vector2& GetDefaultPreferredSize()
88 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
89 inline const Vector2& GetDefaultDimensionPadding()
94 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
96 } // unnamed namespace
99 * Struct to collect relayout variables
101 struct Actor::RelayoutData
104 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
106 // Set size negotiation defaults
107 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
109 resizePolicies[ i ] = ResizePolicy::DEFAULT;
110 useAssignedSize[ i ] = false;
111 negotiatedDimensions[ i ] = 0.0f;
112 dimensionNegotiated[ i ] = false;
113 dimensionDirty[ i ] = false;
114 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
115 dimensionPadding[ i ] = GetDefaultDimensionPadding();
116 minimumSize[ i ] = 0.0f;
117 maximumSize[ i ] = FLT_MAX;
121 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
122 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
124 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
126 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
128 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
130 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
131 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
133 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
134 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
136 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
138 Vector2 preferredSize; ///< The preferred size of the actor
140 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
142 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
143 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
146 namespace // unnamed namespace
152 * We want to discourage the use of property strings (minimize string comparisons),
153 * particularly for the default properties.
154 * Name Type writable animatable constraint-input enum for index-checking
156 DALI_PROPERTY_TABLE_BEGIN
157 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
158 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
159 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
160 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
161 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
162 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
163 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
164 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
165 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
166 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
167 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
168 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
169 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
170 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
171 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
172 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
173 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
174 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
175 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
176 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
177 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
178 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
179 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
180 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
181 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
182 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
183 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
184 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
185 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
186 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
187 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
188 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
189 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
190 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
191 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
192 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
193 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
194 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
195 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
196 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
197 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
198 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
199 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
200 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
201 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
202 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
203 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
204 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
205 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
206 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
207 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
208 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
209 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
210 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
211 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
212 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
213 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
214 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
215 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::DevelActor::Property::LAYOUT_DIRECTION )
216 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::DevelActor::Property::INHERIT_LAYOUT_DIRECTION )
217 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
221 const char* const SIGNAL_TOUCHED = "touched";
222 const char* const SIGNAL_HOVERED = "hovered";
223 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
224 const char* const SIGNAL_ON_STAGE = "onStage";
225 const char* const SIGNAL_OFF_STAGE = "offStage";
226 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
227 const char* const SIGNAL_TOUCH = "touch";
231 const char* const ACTION_SHOW = "show";
232 const char* const ACTION_HIDE = "hide";
234 BaseHandle CreateActor()
236 return Dali::Actor::New();
239 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
241 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
242 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
243 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
244 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
245 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
247 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
249 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
250 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
255 const Vector3& value;
258 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
259 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
260 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
261 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
262 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
263 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
264 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
265 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
266 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
267 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
268 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
270 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
271 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
272 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
273 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
274 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
275 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
277 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
278 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
279 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
280 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
281 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
282 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
284 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
285 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
287 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
288 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
290 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
299 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
301 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
305 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
307 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
310 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
312 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelActor::LayoutDirection, LTR )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelActor::LayoutDirection, RTL )
315 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
317 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
319 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
321 size_t sizeIgnored = 0;
322 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
324 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
331 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
333 // Values are the same so just use the same table as anchor-point
334 return GetAnchorPointConstant( value, parentOrigin );
338 * @brief Extract a given dimension from a Vector2
340 * @param[in] values The values to extract from
341 * @param[in] dimension The dimension to extract
342 * @return Return the value for the dimension
344 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
348 case Dimension::WIDTH:
352 case Dimension::HEIGHT:
354 return values.height;
365 * @brief Extract a given dimension from a Vector3
367 * @param[in] values The values to extract from
368 * @param[in] dimension The dimension to extract
369 * @return Return the value for the dimension
371 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
373 return GetDimensionValue( values.GetVectorXY(), dimension );
377 * @brief Recursively emits the visibility-changed-signal on the actor tree.
378 * @param[in] actor The actor to emit the signal on
379 * @param[in] visible The new visibility of the actor
380 * @param[in] type Whether the actor's visible property has changed or a parent's
382 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
386 actor->EmitVisibilityChangedSignal( visible, type );
388 if( actor->GetChildCount() > 0 )
390 ActorContainer& children = actor->GetChildrenInternal();
391 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
393 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
399 } // unnamed namespace
401 ActorPtr Actor::New()
403 ActorPtr actor( new Actor( BASIC ) );
405 // Second-phase construction
411 const std::string& Actor::GetName() const
416 void Actor::SetName( const std::string& name )
422 // ATTENTION: string for debug purposes is not thread safe.
423 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
427 unsigned int Actor::GetId() const
432 bool Actor::OnStage() const
437 Dali::Layer Actor::GetLayer()
441 // Short-circuit for Layer derived actors
444 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
447 // Find the immediate Layer parent
448 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
450 if( parent->IsLayer() )
452 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
459 void Actor::Add( Actor& child )
461 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
462 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
466 mChildren = new ActorContainer;
469 Actor* const oldParent( child.mParent );
471 // child might already be ours
472 if( this != oldParent )
474 // if we already have parent, unparent us first
477 oldParent->Remove( child ); // This causes OnChildRemove callback
479 // Old parent may need to readjust to missing child
480 if( oldParent->RelayoutDependentOnChildren() )
482 oldParent->RelayoutRequest();
486 // Guard against Add() during previous OnChildRemove callback
489 // Do this first, since user callbacks from within SetParent() may need to remove child
490 mChildren->push_back( ActorPtr( &child ) );
492 // SetParent asserts that child can be added
493 child.SetParent( this );
495 // Notification for derived classes
498 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
500 // Only put in a relayout request if there is a suitable dependency
501 if( RelayoutDependentOnChildren() )
509 void Actor::Remove( Actor& child )
511 if( (this == &child) || (!mChildren) )
513 // no children or removing itself
519 // Find the child in mChildren, and unparent it
520 ActorIter end = mChildren->end();
521 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
523 ActorPtr actor = (*iter);
525 if( actor.Get() == &child )
527 // Keep handle for OnChildRemove notification
530 // Do this first, since user callbacks from within SetParent() may need to add the child
531 mChildren->erase( iter );
533 DALI_ASSERT_DEBUG( actor->GetParent() == this );
534 actor->SetParent( NULL );
542 // Only put in a relayout request if there is a suitable dependency
543 if( RelayoutDependentOnChildren() )
549 // Notification for derived classes
550 OnChildRemove( child );
553 void Actor::Unparent()
557 // Remove this actor from the parent. The remove will put a relayout request in for
558 // the parent if required
559 mParent->Remove( *this );
560 // mParent is now NULL!
564 unsigned int Actor::GetChildCount() const
566 return ( NULL != mChildren ) ? mChildren->size() : 0;
569 ActorPtr Actor::GetChildAt( unsigned int index ) const
571 DALI_ASSERT_ALWAYS( index < GetChildCount() );
573 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
576 ActorPtr Actor::FindChildByName( const std::string& actorName )
579 if( actorName == mName )
585 ActorIter end = mChildren->end();
586 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
588 child = (*iter)->FindChildByName( actorName );
599 ActorPtr Actor::FindChildById( const unsigned int id )
608 ActorIter end = mChildren->end();
609 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
611 child = (*iter)->FindChildById( id );
622 void Actor::SetParentOrigin( const Vector3& origin )
626 // mNode is being used in a separate thread; queue a message to set the value & base value
627 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
630 // Cache for event-thread access
633 // not allocated, check if different from default
634 if( ParentOrigin::DEFAULT != origin )
636 mParentOrigin = new Vector3( origin );
641 // check if different from current costs more than just set
642 *mParentOrigin = origin;
646 void Actor::SetParentOriginX( float x )
648 const Vector3& current = GetCurrentParentOrigin();
650 SetParentOrigin( Vector3( x, current.y, current.z ) );
653 void Actor::SetParentOriginY( float y )
655 const Vector3& current = GetCurrentParentOrigin();
657 SetParentOrigin( Vector3( current.x, y, current.z ) );
660 void Actor::SetParentOriginZ( float z )
662 const Vector3& current = GetCurrentParentOrigin();
664 SetParentOrigin( Vector3( current.x, current.y, z ) );
667 const Vector3& Actor::GetCurrentParentOrigin() const
669 // Cached for event-thread access
670 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
673 void Actor::SetAnchorPoint( const Vector3& anchor )
677 // mNode is being used in a separate thread; queue a message to set the value & base value
678 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
681 // Cache for event-thread access
684 // not allocated, check if different from default
685 if( AnchorPoint::DEFAULT != anchor )
687 mAnchorPoint = new Vector3( anchor );
692 // check if different from current costs more than just set
693 *mAnchorPoint = anchor;
697 void Actor::SetAnchorPointX( float x )
699 const Vector3& current = GetCurrentAnchorPoint();
701 SetAnchorPoint( Vector3( x, current.y, current.z ) );
704 void Actor::SetAnchorPointY( float y )
706 const Vector3& current = GetCurrentAnchorPoint();
708 SetAnchorPoint( Vector3( current.x, y, current.z ) );
711 void Actor::SetAnchorPointZ( float z )
713 const Vector3& current = GetCurrentAnchorPoint();
715 SetAnchorPoint( Vector3( current.x, current.y, z ) );
718 const Vector3& Actor::GetCurrentAnchorPoint() const
720 // Cached for event-thread access
721 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
724 void Actor::SetPosition( float x, float y )
726 SetPosition( Vector3( x, y, 0.0f ) );
729 void Actor::SetPosition( float x, float y, float z )
731 SetPosition( Vector3( x, y, z ) );
734 void Actor::SetPosition( const Vector3& position )
736 mTargetPosition = position;
740 // mNode is being used in a separate thread; queue a message to set the value & base value
741 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
745 void Actor::SetX( float x )
747 mTargetPosition.x = x;
751 // mNode is being used in a separate thread; queue a message to set the value & base value
752 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
756 void Actor::SetY( float y )
758 mTargetPosition.y = y;
762 // mNode is being used in a separate thread; queue a message to set the value & base value
763 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
767 void Actor::SetZ( float z )
769 mTargetPosition.z = z;
773 // mNode is being used in a separate thread; queue a message to set the value & base value
774 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
778 void Actor::TranslateBy( const Vector3& distance )
780 mTargetPosition += distance;
784 // mNode is being used in a separate thread; queue a message to set the value & base value
785 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
789 const Vector3& Actor::GetCurrentPosition() const
793 // mNode is being used in a separate thread; copy the value from the previous update
794 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
797 return Vector3::ZERO;
800 const Vector3& Actor::GetTargetPosition() const
802 return mTargetPosition;
805 const Vector3& Actor::GetCurrentWorldPosition() const
809 // mNode is being used in a separate thread; copy the value from the previous update
810 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
813 return Vector3::ZERO;
816 const Vector2 Actor::GetCurrentScreenPosition() const
818 if( OnStage() && NULL != mNode )
820 StagePtr stage = Stage::GetCurrent();
821 Vector3 worldPosition = mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
822 Vector3 actorSize = GetCurrentSize() * GetCurrentScale();
823 Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
824 Vector3 halfActorSize( actorSize * 0.5f );
825 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
827 return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
828 halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
831 return Vector2::ZERO;
834 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
836 // this flag is not animatable so keep the value
837 mPositionInheritanceMode = mode;
840 // mNode is being used in a separate thread; queue a message to set the value
841 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
845 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
847 // Cached for event-thread access
848 return mPositionInheritanceMode;
851 void Actor::SetInheritPosition( bool inherit )
853 if( mInheritPosition != inherit && NULL != mNode )
855 // non animateable so keep local copy
856 mInheritPosition = inherit;
857 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
861 bool Actor::IsPositionInherited() const
863 return mInheritPosition;
866 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
868 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
869 normalizedAxis.Normalize();
871 Quaternion orientation( angle, normalizedAxis );
873 SetOrientation( orientation );
876 void Actor::SetOrientation( const Quaternion& orientation )
878 mTargetOrientation = orientation;
882 // mNode is being used in a separate thread; queue a message to set the value & base value
883 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
887 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
889 RotateBy( Quaternion(angle, axis) );
892 void Actor::RotateBy( const Quaternion& relativeRotation )
894 mTargetOrientation *= Quaternion( relativeRotation );
898 // mNode is being used in a separate thread; queue a message to set the value & base value
899 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
903 const Quaternion& Actor::GetCurrentOrientation() const
907 // mNode is being used in a separate thread; copy the value from the previous update
908 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
911 return Quaternion::IDENTITY;
914 const Quaternion& Actor::GetCurrentWorldOrientation() const
918 // mNode is being used in a separate thread; copy the value from the previous update
919 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
922 return Quaternion::IDENTITY;
925 void Actor::SetScale( float scale )
927 SetScale( Vector3( scale, scale, scale ) );
930 void Actor::SetScale( float x, float y, float z )
932 SetScale( Vector3( x, y, z ) );
935 void Actor::SetScale( const Vector3& scale )
937 mTargetScale = scale;
941 // mNode is being used in a separate thread; queue a message to set the value & base value
942 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
946 void Actor::SetScaleX( float x )
952 // mNode is being used in a separate thread; queue a message to set the value & base value
953 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
957 void Actor::SetScaleY( float y )
963 // mNode is being used in a separate thread; queue a message to set the value & base value
964 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
968 void Actor::SetScaleZ( float z )
974 // mNode is being used in a separate thread; queue a message to set the value & base value
975 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
979 void Actor::ScaleBy(const Vector3& relativeScale)
981 mTargetScale *= relativeScale;
985 // mNode is being used in a separate thread; queue a message to set the value & base value
986 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
990 const Vector3& Actor::GetCurrentScale() const
994 // mNode is being used in a separate thread; copy the value from the previous update
995 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
1001 const Vector3& Actor::GetCurrentWorldScale() const
1005 // mNode is being used in a separate thread; copy the value from the previous update
1006 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
1009 return Vector3::ONE;
1012 void Actor::SetInheritScale( bool inherit )
1015 if( mInheritScale != inherit && NULL != mNode )
1017 // non animateable so keep local copy
1018 mInheritScale = inherit;
1019 // mNode is being used in a separate thread; queue a message to set the value
1020 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
1024 bool Actor::IsScaleInherited() const
1026 return mInheritScale;
1029 Matrix Actor::GetCurrentWorldMatrix() const
1033 return mNode->GetWorldMatrix(0);
1036 return Matrix::IDENTITY;
1039 void Actor::SetVisible( bool visible )
1041 SetVisibleInternal( visible, SendMessage::TRUE );
1044 bool Actor::IsVisible() const
1048 // mNode is being used in a separate thread; copy the value from the previous update
1049 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1055 void Actor::SetOpacity( float opacity )
1057 mTargetColor.a = opacity;
1061 // mNode is being used in a separate thread; queue a message to set the value & base value
1062 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1066 float Actor::GetCurrentOpacity() const
1070 // mNode is being used in a separate thread; copy the value from the previous update
1071 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1077 ClippingMode::Type Actor::GetClippingMode() const
1079 return mClippingMode;
1082 unsigned int Actor::GetSortingDepth()
1084 return mSortedDepth;
1087 const Vector4& Actor::GetCurrentWorldColor() const
1091 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1094 return Color::WHITE;
1097 void Actor::SetColor( const Vector4& color )
1099 mTargetColor = color;
1103 // mNode is being used in a separate thread; queue a message to set the value & base value
1104 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1108 void Actor::SetColorRed( float red )
1110 mTargetColor.r = red;
1114 // mNode is being used in a separate thread; queue a message to set the value & base value
1115 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1119 void Actor::SetColorGreen( float green )
1121 mTargetColor.g = green;
1125 // mNode is being used in a separate thread; queue a message to set the value & base value
1126 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1130 void Actor::SetColorBlue( float blue )
1132 mTargetColor.b = blue;
1136 // mNode is being used in a separate thread; queue a message to set the value & base value
1137 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1141 const Vector4& Actor::GetCurrentColor() const
1145 // mNode is being used in a separate thread; copy the value from the previous update
1146 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1149 return Color::WHITE;
1152 void Actor::SetInheritOrientation( bool inherit )
1154 if( mInheritOrientation != inherit && NULL != mNode)
1156 // non animateable so keep local copy
1157 mInheritOrientation = inherit;
1158 // mNode is being used in a separate thread; queue a message to set the value
1159 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1163 bool Actor::IsOrientationInherited() const
1165 return mInheritOrientation;
1168 void Actor::SetSizeModeFactor( const Vector3& factor )
1170 EnsureRelayoutData();
1172 mRelayoutData->sizeModeFactor = factor;
1175 const Vector3& Actor::GetSizeModeFactor() const
1177 if ( mRelayoutData )
1179 return mRelayoutData->sizeModeFactor;
1182 return GetDefaultSizeModeFactor();
1185 void Actor::SetColorMode( ColorMode colorMode )
1187 // non animateable so keep local copy
1188 mColorMode = colorMode;
1191 // mNode is being used in a separate thread; queue a message to set the value
1192 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1196 ColorMode Actor::GetColorMode() const
1198 // we have cached copy
1202 void Actor::SetSize( float width, float height )
1204 SetSize( Vector2( width, height ) );
1207 void Actor::SetSize( float width, float height, float depth )
1209 SetSize( Vector3( width, height, depth ) );
1212 void Actor::SetSize( const Vector2& size )
1214 SetSize( Vector3( size.width, size.height, 0.f ) );
1217 void Actor::SetSizeInternal( const Vector2& size )
1219 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1222 void Actor::SetSize( const Vector3& size )
1224 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1226 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1227 SetPreferredSize( size.GetVectorXY() );
1231 SetSizeInternal( size );
1235 void Actor::SetSizeInternal( const Vector3& size )
1237 // dont allow recursive loop
1238 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1239 // 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
1240 if( ( NULL != mNode )&&
1241 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1242 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1243 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1247 // mNode is being used in a separate thread; queue a message to set the value & base value
1248 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1250 // Notification for derived classes
1251 mInsideOnSizeSet = true;
1252 OnSizeSet( mTargetSize );
1253 mInsideOnSizeSet = false;
1255 // Raise a relayout request if the flag is not locked
1256 if( mRelayoutData && !mRelayoutData->insideRelayout )
1263 void Actor::SetWidth( float width )
1265 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1267 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1268 mRelayoutData->preferredSize.width = width;
1272 mTargetSize.width = width;
1276 // mNode is being used in a separate thread; queue a message to set the value & base value
1277 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1284 void Actor::SetHeight( float height )
1286 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1288 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1289 mRelayoutData->preferredSize.height = height;
1293 mTargetSize.height = height;
1297 // mNode is being used in a separate thread; queue a message to set the value & base value
1298 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1305 void Actor::SetDepth( float depth )
1307 mTargetSize.depth = depth;
1311 // mNode is being used in a separate thread; queue a message to set the value & base value
1312 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1316 Vector3 Actor::GetTargetSize() const
1318 Vector3 size = mTargetSize;
1320 // Should return preferred size if size is fixed as set by SetSize
1321 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1323 size.width = GetPreferredSize().width;
1325 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1327 size.height = GetPreferredSize().height;
1333 const Vector3& Actor::GetCurrentSize() const
1337 // mNode is being used in a separate thread; copy the value from the previous update
1338 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1341 return Vector3::ZERO;
1344 Vector3 Actor::GetNaturalSize() const
1346 // It is up to deriving classes to return the appropriate natural size
1347 return Vector3( 0.0f, 0.0f, 0.0f );
1350 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1352 EnsureRelayoutData();
1354 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1355 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1357 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1359 if( dimension & ( 1 << i ) )
1361 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1363 mRelayoutData->useAssignedSize[ i ] = true;
1367 mRelayoutData->resizePolicies[ i ] = policy;
1368 mRelayoutData->useAssignedSize[ i ] = false;
1373 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1375 if( dimension & Dimension::WIDTH )
1377 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1380 if( dimension & Dimension::HEIGHT )
1382 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1386 // If calling SetResizePolicy, assume we want relayout enabled
1387 SetRelayoutEnabled( true );
1389 // If the resize policy is set to be FIXED, the preferred size
1390 // should be overrided by the target size. Otherwise the target
1391 // size should be overrided by the preferred size.
1393 if( dimension & Dimension::WIDTH )
1395 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1397 mRelayoutData->preferredSize.width = mTargetSize.width;
1399 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1401 mTargetSize.width = mRelayoutData->preferredSize.width;
1405 if( dimension & Dimension::HEIGHT )
1407 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1409 mRelayoutData->preferredSize.height = mTargetSize.height;
1411 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1413 mTargetSize.height = mRelayoutData->preferredSize.height;
1417 OnSetResizePolicy( policy, dimension );
1419 // Trigger relayout on this control
1423 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1425 if ( mRelayoutData )
1427 // If more than one dimension is requested, just return the first one found
1428 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1430 if( ( dimension & ( 1 << i ) ) )
1432 if( mRelayoutData->useAssignedSize[ i ] )
1434 return ResizePolicy::USE_ASSIGNED_SIZE;
1438 return mRelayoutData->resizePolicies[ i ];
1444 return ResizePolicy::DEFAULT;
1447 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1449 EnsureRelayoutData();
1451 mRelayoutData->sizeSetPolicy = policy;
1454 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1456 if ( mRelayoutData )
1458 return mRelayoutData->sizeSetPolicy;
1461 return DEFAULT_SIZE_SCALE_POLICY;
1464 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1466 EnsureRelayoutData();
1468 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1470 if( dimension & ( 1 << i ) )
1472 mRelayoutData->dimensionDependencies[ i ] = dependency;
1477 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1479 if ( mRelayoutData )
1481 // If more than one dimension is requested, just return the first one found
1482 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1484 if( ( dimension & ( 1 << i ) ) )
1486 return mRelayoutData->dimensionDependencies[ i ];
1491 return Dimension::ALL_DIMENSIONS; // Default
1494 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1496 // If relayout data has not been allocated yet and the client is requesting
1497 // to disable it, do nothing
1498 if( mRelayoutData || relayoutEnabled )
1500 EnsureRelayoutData();
1502 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1504 mRelayoutData->relayoutEnabled = relayoutEnabled;
1508 bool Actor::IsRelayoutEnabled() const
1510 // Assume that if relayout data has not been allocated yet then
1511 // relayout is disabled
1512 return mRelayoutData && mRelayoutData->relayoutEnabled;
1515 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1517 EnsureRelayoutData();
1519 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1521 if( dimension & ( 1 << i ) )
1523 mRelayoutData->dimensionDirty[ i ] = dirty;
1528 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1530 if ( mRelayoutData )
1532 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1534 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1544 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1546 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1549 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1551 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1554 unsigned int Actor::AddRenderer( Renderer& renderer )
1558 mRenderers = new RendererContainer;
1561 unsigned int index = mRenderers->size();
1562 RendererPtr rendererPtr = RendererPtr( &renderer );
1563 mRenderers->push_back( rendererPtr );
1564 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1568 unsigned int Actor::GetRendererCount() const
1570 unsigned int rendererCount(0);
1573 rendererCount = mRenderers->size();
1576 return rendererCount;
1579 RendererPtr Actor::GetRendererAt( unsigned int index )
1581 RendererPtr renderer;
1582 if( index < GetRendererCount() )
1584 renderer = ( *mRenderers )[ index ];
1590 void Actor::RemoveRenderer( Renderer& renderer )
1594 RendererIter end = mRenderers->end();
1595 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1597 if( (*iter).Get() == &renderer )
1599 mRenderers->erase( iter );
1600 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1607 void Actor::RemoveRenderer( unsigned int index )
1609 if( index < GetRendererCount() )
1611 RendererPtr renderer = ( *mRenderers )[ index ];
1612 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1613 mRenderers->erase( mRenderers->begin()+index );
1617 bool Actor::IsOverlay() const
1619 return ( DrawMode::OVERLAY_2D == mDrawMode );
1622 void Actor::SetDrawMode( DrawMode::Type drawMode )
1624 // this flag is not animatable so keep the value
1625 mDrawMode = drawMode;
1626 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1628 // mNode is being used in a separate thread; queue a message to set the value
1629 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1633 DrawMode::Type Actor::GetDrawMode() const
1638 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1640 // only valid when on-stage
1641 StagePtr stage = Stage::GetCurrent();
1642 if( stage && OnStage() )
1644 const RenderTaskList& taskList = stage->GetRenderTaskList();
1646 Vector2 converted( screenX, screenY );
1648 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1649 const int taskCount = taskList.GetTaskCount();
1650 for( int i = taskCount - 1; i >= 0; --i )
1652 Dali::RenderTask task = taskList.GetTask( i );
1653 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1655 // found a task where this conversion was ok so return
1663 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1665 bool retval = false;
1666 // only valid when on-stage
1669 CameraActor* camera = renderTask.GetCameraActor();
1673 renderTask.GetViewport( viewport );
1675 // need to translate coordinates to render tasks coordinate space
1676 Vector2 converted( screenX, screenY );
1677 if( renderTask.TranslateCoordinates( converted ) )
1679 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1686 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1688 // Early-out if mNode is NULL
1694 // Get the ModelView matrix
1696 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1698 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1699 Matrix invertedMvp( false/*don't init*/);
1700 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1701 bool success = invertedMvp.Invert();
1703 // Convert to GL coordinates
1704 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1709 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1716 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1722 if( XyPlaneIntersect( nearPos, farPos, local ) )
1724 Vector3 size = GetCurrentSize();
1725 localX = local.x + size.x * 0.5f;
1726 localY = local.y + size.y * 0.5f;
1737 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1740 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1742 Mathematical Formulation
1744 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1746 ( p - c ) dot ( p - c ) = r^2
1748 Given a ray with a point of origin 'o', and a direction vector 'd':
1750 ray(t) = o + td, t >= 0
1752 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1754 (o + td - c ) dot ( o + td - c ) = r^2
1756 To solve for t we first expand the above into a more recognisable quadratic equation form
1758 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1767 B = 2( o - c ) dot d
1768 C = ( o - c ) dot ( o - c ) - r^2
1770 which can be solved using a standard quadratic formula.
1772 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1774 Practical Simplification
1776 In a renderer, we often differentiate between world space and object space. In the object space
1777 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1778 into object space, the mathematical solution presented above can be simplified significantly.
1780 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1784 and we can find the t at which the (transformed) ray intersects the sphere by
1786 ( o + td ) dot ( o + td ) = r^2
1788 According to the reasoning above, we expand the above quadratic equation into the general form
1792 which now has coefficients:
1799 // Early out if mNode is NULL
1805 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1807 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1808 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1809 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1811 // Compute the radius is not needed, square radius it's enough.
1812 const Vector3& size( mNode->GetSize( bufferIndex ) );
1814 // Scale the sphere.
1815 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1817 const float width = size.width * scale.width;
1818 const float height = size.height * scale.height;
1820 float squareSphereRadius = 0.5f * ( width * width + height * height );
1822 float a = rayDir.Dot( rayDir ); // a
1823 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1824 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1826 return ( b2 * b2 - a * c ) >= 0.f;
1829 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1833 if( OnStage() && NULL != mNode )
1835 // Transforms the ray to the local reference system.
1836 // Calculate the inverse of Model matrix
1837 Matrix invModelMatrix( false/*don't init*/);
1839 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1840 invModelMatrix = mNode->GetWorldMatrix(0);
1841 invModelMatrix.Invert();
1843 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1844 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1846 // Test with the actor's XY plane (Normal = 0 0 1 1).
1848 float a = -rayOriginLocal.z;
1849 float b = rayDirLocal.z;
1851 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1853 // Ray travels distance * rayDirLocal to intersect with plane.
1856 const Vector3& size = mNode->GetSize( bufferIndex );
1858 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1859 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1861 // Test with the actor's geometry.
1862 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1869 void Actor::SetLeaveRequired( bool required )
1871 mLeaveRequired = required;
1874 bool Actor::GetLeaveRequired() const
1876 return mLeaveRequired;
1879 void Actor::SetKeyboardFocusable( bool focusable )
1881 mKeyboardFocusable = focusable;
1884 bool Actor::IsKeyboardFocusable() const
1886 return mKeyboardFocusable;
1889 bool Actor::GetTouchRequired() const
1891 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1894 bool Actor::GetHoverRequired() const
1896 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1899 bool Actor::GetWheelEventRequired() const
1901 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1904 bool Actor::IsHittable() const
1906 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1909 ActorGestureData& Actor::GetGestureData()
1911 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1912 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1913 if( NULL == mGestureData )
1915 mGestureData = new ActorGestureData;
1917 return *mGestureData;
1920 bool Actor::IsGestureRequred( Gesture::Type type ) const
1922 return mGestureData && mGestureData->IsGestureRequred( type );
1925 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1927 bool consumed = false;
1929 if( !mTouchSignal.Empty() )
1931 Dali::Actor handle( this );
1932 consumed = mTouchSignal.Emit( handle, touch );
1935 if( !mTouchedSignal.Empty() )
1937 Dali::Actor handle( this );
1938 consumed |= mTouchedSignal.Emit( handle, event );
1943 // Notification for derived classes
1944 consumed = OnTouchEvent( event ); // TODO
1950 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1952 bool consumed = false;
1954 if( !mHoveredSignal.Empty() )
1956 Dali::Actor handle( this );
1957 consumed = mHoveredSignal.Emit( handle, event );
1962 // Notification for derived classes
1963 consumed = OnHoverEvent( event );
1969 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1971 bool consumed = false;
1973 if( !mWheelEventSignal.Empty() )
1975 Dali::Actor handle( this );
1976 consumed = mWheelEventSignal.Emit( handle, event );
1981 // Notification for derived classes
1982 consumed = OnWheelEvent( event );
1988 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1990 if( ! mVisibilityChangedSignal.Empty() )
1992 Dali::Actor handle( this );
1993 mVisibilityChangedSignal.Emit( handle, visible, type );
1997 void Actor::EmitLayoutDirectionChangedSignal( DevelActor::LayoutDirection::Type type )
1999 if( ! mLayoutDirectionChangedSignal.Empty() )
2001 Dali::Actor handle( this );
2002 mLayoutDirectionChangedSignal.Emit( handle, type );
2006 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
2008 return mTouchedSignal;
2011 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
2013 return mTouchSignal;
2016 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2018 return mHoveredSignal;
2021 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
2023 return mWheelEventSignal;
2026 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2028 return mOnStageSignal;
2031 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2033 return mOffStageSignal;
2036 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2038 return mOnRelayoutSignal;
2041 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
2043 return mVisibilityChangedSignal;
2046 DevelActor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
2048 return mLayoutDirectionChangedSignal;
2051 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2053 bool connected( true );
2054 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2056 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2058 actor->TouchedSignal().Connect( tracker, functor );
2060 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2062 actor->HoveredSignal().Connect( tracker, functor );
2064 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2066 actor->WheelEventSignal().Connect( tracker, functor );
2068 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2070 actor->OnStageSignal().Connect( tracker, functor );
2072 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2074 actor->OffStageSignal().Connect( tracker, functor );
2076 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2078 actor->OnRelayoutSignal().Connect( tracker, functor );
2080 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2082 actor->TouchSignal().Connect( tracker, functor );
2086 // signalName does not match any signal
2093 Actor::Actor( DerivedType derivedType )
2098 mParentOrigin( NULL ),
2099 mAnchorPoint( NULL ),
2100 mRelayoutData( NULL ),
2101 mGestureData( NULL ),
2102 mTargetOrientation( Quaternion::IDENTITY ),
2103 mTargetColor( Color::WHITE ),
2104 mTargetSize( Vector3::ZERO ),
2105 mTargetPosition( Vector3::ZERO ),
2106 mTargetScale( Vector3::ONE ),
2108 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2111 mIsRoot( ROOT_LAYER == derivedType ),
2112 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2113 mIsOnStage( false ),
2115 mLeaveRequired( false ),
2116 mKeyboardFocusable( false ),
2117 mDerivedRequiresTouch( false ),
2118 mDerivedRequiresHover( false ),
2119 mDerivedRequiresWheelEvent( false ),
2120 mOnStageSignalled( false ),
2121 mInsideOnSizeSet( false ),
2122 mInheritPosition( true ),
2123 mInheritOrientation( true ),
2124 mInheritScale( true ),
2125 mPositionUsesAnchorPoint( true ),
2127 mInheritLayoutDirection( true ),
2128 mLayoutDirection( DevelActor::LayoutDirection::LTR ),
2129 mDrawMode( DrawMode::NORMAL ),
2130 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2131 mColorMode( Node::DEFAULT_COLOR_MODE ),
2132 mClippingMode( ClippingMode::DISABLED )
2136 void Actor::Initialize()
2138 // Node creation, keep raw-pointer to Node for messaging
2139 mNode = CreateNode();
2140 OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
2141 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
2145 GetEventThreadServices().RegisterObject( this );
2150 // Remove mParent pointers from children even if we're destroying core,
2151 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2154 ActorConstIter endIter = mChildren->end();
2155 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2157 (*iter)->SetParent( NULL );
2163 // Guard to allow handle destruction after Core has been destroyed
2164 if( EventThreadServices::IsCoreRunning() )
2168 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2169 mNode = NULL; // Node is about to be destroyed
2172 GetEventThreadServices().UnregisterObject( this );
2175 // Cleanup optional gesture data
2176 delete mGestureData;
2178 // Cleanup optional parent origin and anchor
2179 delete mParentOrigin;
2180 delete mAnchorPoint;
2182 // Delete optional relayout data
2185 delete mRelayoutData;
2189 void Actor::ConnectToStage( unsigned int parentDepth )
2191 // This container is used instead of walking the Actor hierarchy.
2192 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2193 ActorContainer connectionList;
2195 StagePtr stage = Stage::GetCurrent();
2198 stage->RequestRebuildDepthTree();
2201 // This stage is atomic i.e. not interrupted by user callbacks.
2202 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2204 // Notify applications about the newly connected actors.
2205 const ActorIter endIter = connectionList.end();
2206 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2208 (*iter)->NotifyStageConnection();
2214 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2216 DALI_ASSERT_ALWAYS( !OnStage() );
2221 ConnectToSceneGraph();
2223 // Notification for internal derived classes
2224 OnStageConnectionInternal();
2226 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2227 connectionList.push_back( ActorPtr( this ) );
2229 // Recursively connect children
2232 ActorConstIter endIter = mChildren->end();
2233 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2235 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2241 * This method is called when the Actor is connected to the Stage.
2242 * The parent must have added its Node to the scene-graph.
2243 * The child must connect its Node to the parent's Node.
2244 * This is recursive; the child calls ConnectToStage() for its children.
2246 void Actor::ConnectToSceneGraph()
2248 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2252 // Reparent Node in next Update
2253 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2256 // Request relayout on all actors that are added to the scenegraph
2259 // Notification for Object::Observers
2263 void Actor::NotifyStageConnection()
2265 // Actors can be removed (in a callback), before the on-stage stage is reported.
2266 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2267 if( OnStage() && !mOnStageSignalled )
2269 // Notification for external (CustomActor) derived classes
2270 OnStageConnectionExternal( mDepth );
2272 if( !mOnStageSignal.Empty() )
2274 Dali::Actor handle( this );
2275 mOnStageSignal.Emit( handle );
2278 // Guard against Remove during callbacks
2281 mOnStageSignalled = true; // signal required next time Actor is removed
2286 void Actor::DisconnectFromStage()
2288 // This container is used instead of walking the Actor hierachy.
2289 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2290 ActorContainer disconnectionList;
2292 StagePtr stage = Stage::GetCurrent();
2295 stage->RequestRebuildDepthTree();
2298 // This stage is atomic i.e. not interrupted by user callbacks
2299 RecursiveDisconnectFromStage( disconnectionList );
2301 // Notify applications about the newly disconnected actors.
2302 const ActorIter endIter = disconnectionList.end();
2303 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2305 (*iter)->NotifyStageDisconnection();
2309 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2311 DALI_ASSERT_ALWAYS( OnStage() );
2313 // Recursively disconnect children
2316 ActorConstIter endIter = mChildren->end();
2317 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2319 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2323 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2324 disconnectionList.push_back( ActorPtr( this ) );
2326 // Notification for internal derived classes
2327 OnStageDisconnectionInternal();
2329 DisconnectFromSceneGraph();
2335 * This method is called by an actor or its parent, before a node removal message is sent.
2336 * This is recursive; the child calls DisconnectFromStage() for its children.
2338 void Actor::DisconnectFromSceneGraph()
2340 // Notification for Object::Observers
2341 OnSceneObjectRemove();
2344 void Actor::NotifyStageDisconnection()
2346 // Actors can be added (in a callback), before the off-stage state is reported.
2347 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2348 // only do this step if there is a stage, i.e. Core is not being shut down
2349 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2351 // Notification for external (CustomeActor) derived classes
2352 OnStageDisconnectionExternal();
2354 if( !mOffStageSignal.Empty() )
2356 Dali::Actor handle( this );
2357 mOffStageSignal.Emit( handle );
2360 // Guard against Add during callbacks
2363 mOnStageSignalled = false; // signal required next time Actor is added
2368 bool Actor::IsNodeConnected() const
2370 bool connected( false );
2372 if( OnStage() && ( NULL != mNode ) )
2374 if( IsRoot() || mNode->GetParent() )
2383 // This method initiates traversal of the actor tree using depth-first
2384 // traversal to set a depth index based on traversal order. It sends a
2385 // single message to update manager to update all the actor's nodes in
2386 // this tree with the depth index. The sceneGraphNodeDepths vector's
2387 // elements are ordered by depth, and could be used to reduce sorting
2388 // in the update thread.
2389 void Actor::RebuildDepthTree()
2391 DALI_LOG_TIMER_START(depthTimer);
2393 // Vector of scene-graph nodes and their depths to send to UpdateManager
2394 // in a single message
2395 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2398 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2400 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2401 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2404 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
2406 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2407 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
2409 // Create/add to children of this node
2412 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2414 Actor* childActor = (*it).Get();
2416 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2421 unsigned int Actor::GetDefaultPropertyCount() const
2423 return DEFAULT_PROPERTY_COUNT;
2426 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2428 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2430 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2432 indices.PushBack( i );
2436 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2438 if( index < DEFAULT_PROPERTY_COUNT )
2440 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2446 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2448 Property::Index index = Property::INVALID_INDEX;
2450 // Look for name in default properties
2451 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2453 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2454 if( 0 == name.compare( property->name ) )
2464 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2466 if( index < DEFAULT_PROPERTY_COUNT )
2468 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2474 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2476 if( index < DEFAULT_PROPERTY_COUNT )
2478 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2484 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2486 if( index < DEFAULT_PROPERTY_COUNT )
2488 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2494 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2496 if( index < DEFAULT_PROPERTY_COUNT )
2498 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2501 // index out of range...return Property::NONE
2502 return Property::NONE;
2505 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2509 case Dali::Actor::Property::PARENT_ORIGIN:
2511 Property::Type type = property.GetType();
2512 if( type == Property::VECTOR3 )
2514 SetParentOrigin( property.Get< Vector3 >() );
2516 else if ( type == Property::STRING )
2518 std::string parentOriginString;
2519 property.Get( parentOriginString );
2520 Vector3 parentOrigin;
2521 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2523 SetParentOrigin( parentOrigin );
2529 case Dali::Actor::Property::PARENT_ORIGIN_X:
2531 SetParentOriginX( property.Get< float >() );
2535 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2537 SetParentOriginY( property.Get< float >() );
2541 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2543 SetParentOriginZ( property.Get< float >() );
2547 case Dali::Actor::Property::ANCHOR_POINT:
2549 Property::Type type = property.GetType();
2550 if( type == Property::VECTOR3 )
2552 SetAnchorPoint( property.Get< Vector3 >() );
2554 else if ( type == Property::STRING )
2556 std::string anchorPointString;
2557 property.Get( anchorPointString );
2559 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2561 SetAnchorPoint( anchor );
2567 case Dali::Actor::Property::ANCHOR_POINT_X:
2569 SetAnchorPointX( property.Get< float >() );
2573 case Dali::Actor::Property::ANCHOR_POINT_Y:
2575 SetAnchorPointY( property.Get< float >() );
2579 case Dali::Actor::Property::ANCHOR_POINT_Z:
2581 SetAnchorPointZ( property.Get< float >() );
2585 case Dali::Actor::Property::SIZE:
2587 SetSize( property.Get< Vector3 >() );
2591 case Dali::Actor::Property::SIZE_WIDTH:
2593 SetWidth( property.Get< float >() );
2597 case Dali::Actor::Property::SIZE_HEIGHT:
2599 SetHeight( property.Get< float >() );
2603 case Dali::Actor::Property::SIZE_DEPTH:
2605 SetDepth( property.Get< float >() );
2609 case Dali::Actor::Property::POSITION:
2611 SetPosition( property.Get< Vector3 >() );
2615 case Dali::Actor::Property::POSITION_X:
2617 SetX( property.Get< float >() );
2621 case Dali::Actor::Property::POSITION_Y:
2623 SetY( property.Get< float >() );
2627 case Dali::Actor::Property::POSITION_Z:
2629 SetZ( property.Get< float >() );
2633 case Dali::Actor::Property::ORIENTATION:
2635 SetOrientation( property.Get< Quaternion >() );
2639 case Dali::Actor::Property::SCALE:
2641 SetScale( property.Get< Vector3 >() );
2645 case Dali::Actor::Property::SCALE_X:
2647 SetScaleX( property.Get< float >() );
2651 case Dali::Actor::Property::SCALE_Y:
2653 SetScaleY( property.Get< float >() );
2657 case Dali::Actor::Property::SCALE_Z:
2659 SetScaleZ( property.Get< float >() );
2663 case Dali::Actor::Property::VISIBLE:
2665 SetVisible( property.Get< bool >() );
2669 case Dali::Actor::Property::COLOR:
2671 SetColor( property.Get< Vector4 >() );
2675 case Dali::Actor::Property::COLOR_RED:
2677 SetColorRed( property.Get< float >() );
2681 case Dali::Actor::Property::COLOR_GREEN:
2683 SetColorGreen( property.Get< float >() );
2687 case Dali::Actor::Property::COLOR_BLUE:
2689 SetColorBlue( property.Get< float >() );
2693 case Dali::Actor::Property::COLOR_ALPHA:
2694 case Dali::DevelActor::Property::OPACITY:
2697 if( property.Get( value ) )
2699 SetOpacity( value );
2704 case Dali::Actor::Property::NAME:
2706 SetName( property.Get< std::string >() );
2710 case Dali::Actor::Property::SENSITIVE:
2712 SetSensitive( property.Get< bool >() );
2716 case Dali::Actor::Property::LEAVE_REQUIRED:
2718 SetLeaveRequired( property.Get< bool >() );
2722 case Dali::Actor::Property::INHERIT_POSITION:
2724 SetInheritPosition( property.Get< bool >() );
2728 case Dali::Actor::Property::INHERIT_ORIENTATION:
2730 SetInheritOrientation( property.Get< bool >() );
2734 case Dali::Actor::Property::INHERIT_SCALE:
2736 SetInheritScale( property.Get< bool >() );
2740 case Dali::Actor::Property::COLOR_MODE:
2742 ColorMode mode = mColorMode;
2743 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2745 SetColorMode( mode );
2750 case Dali::Actor::Property::POSITION_INHERITANCE:
2752 PositionInheritanceMode mode = mPositionInheritanceMode;
2753 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2755 SetPositionInheritanceMode( mode );
2760 case Dali::Actor::Property::DRAW_MODE:
2762 DrawMode::Type mode = mDrawMode;
2763 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2765 SetDrawMode( mode );
2770 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2772 SetSizeModeFactor( property.Get< Vector3 >() );
2776 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2778 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2779 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2781 SetResizePolicy( type, Dimension::WIDTH );
2786 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2788 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2789 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2791 SetResizePolicy( type, Dimension::HEIGHT );
2796 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2798 SizeScalePolicy::Type type;
2799 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2801 SetSizeScalePolicy( type );
2806 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2808 if( property.Get< bool >() )
2810 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2815 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2817 if( property.Get< bool >() )
2819 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2824 case Dali::Actor::Property::PADDING:
2826 Vector4 padding = property.Get< Vector4 >();
2827 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2828 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2832 case Dali::Actor::Property::MINIMUM_SIZE:
2834 Vector2 size = property.Get< Vector2 >();
2835 SetMinimumSize( size.x, Dimension::WIDTH );
2836 SetMinimumSize( size.y, Dimension::HEIGHT );
2840 case Dali::Actor::Property::MAXIMUM_SIZE:
2842 Vector2 size = property.Get< Vector2 >();
2843 SetMaximumSize( size.x, Dimension::WIDTH );
2844 SetMaximumSize( size.y, Dimension::HEIGHT );
2848 case Dali::DevelActor::Property::SIBLING_ORDER:
2852 if( property.Get( value ) )
2854 SetSiblingOrder( value );
2859 case Dali::Actor::Property::CLIPPING_MODE:
2861 ClippingMode::Type convertedValue = mClippingMode;
2862 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2864 mClippingMode = convertedValue;
2867 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2873 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2876 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2878 mPositionUsesAnchorPoint = value;
2881 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2887 case Dali::DevelActor::Property::LAYOUT_DIRECTION:
2889 Dali::DevelActor::LayoutDirection::Type direction = mLayoutDirection;
2890 mInheritLayoutDirection = false;
2892 if( Scripting::GetEnumerationProperty< DevelActor::LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2894 InheritLayoutDirectionRecursively( this, direction, true );
2899 case Dali::DevelActor::Property::INHERIT_LAYOUT_DIRECTION:
2902 if( property.Get( value ) )
2904 SetInheritLayoutDirection( value );
2911 // this can happen in the case of a non-animatable default property so just do nothing
2917 // TODO: This method needs to be removed
2918 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2920 switch( entry.GetType() )
2922 case Property::BOOLEAN:
2924 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2925 DALI_ASSERT_DEBUG( NULL != property );
2927 // property is being used in a separate thread; queue a message to set the property
2928 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2933 case Property::INTEGER:
2935 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( 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<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2944 case Property::FLOAT:
2946 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( 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<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2955 case Property::VECTOR2:
2957 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( 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 if(entry.componentIndex == 0)
2963 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2965 else if(entry.componentIndex == 1)
2967 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2971 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2977 case Property::VECTOR3:
2979 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2980 DALI_ASSERT_DEBUG( NULL != property );
2982 // property is being used in a separate thread; queue a message to set the property
2983 if(entry.componentIndex == 0)
2985 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2987 else if(entry.componentIndex == 1)
2989 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2991 else if(entry.componentIndex == 2)
2993 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2997 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
3003 case Property::VECTOR4:
3005 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
3006 DALI_ASSERT_DEBUG( NULL != property );
3008 // property is being used in a separate thread; queue a message to set the property
3009 if(entry.componentIndex == 0)
3011 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3013 else if(entry.componentIndex == 1)
3015 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3017 else if(entry.componentIndex == 2)
3019 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3021 else if(entry.componentIndex == 3)
3023 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3027 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3033 case Property::ROTATION:
3035 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3036 DALI_ASSERT_DEBUG( NULL != property );
3038 // property is being used in a separate thread; queue a message to set the property
3039 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
3044 case Property::MATRIX:
3046 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( 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<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
3055 case Property::MATRIX3:
3057 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( 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<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
3068 // nothing to do for other types
3073 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3075 Property::Value value;
3077 if( ! GetCachedPropertyValue( index, value ) )
3079 // If property value is not stored in the event-side, then it must be a scene-graph only property
3080 GetCurrentPropertyValue( index, value );
3086 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3088 Property::Value value;
3090 if( ! GetCurrentPropertyValue( index, value ) )
3092 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3093 GetCachedPropertyValue( index, value );
3099 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3101 switch( animationType )
3104 case Animation::BETWEEN:
3108 case Dali::Actor::Property::SIZE:
3110 if( value.Get( mTargetSize ) )
3112 // Notify deriving classes
3113 OnSizeAnimation( animation, mTargetSize );
3118 case Dali::Actor::Property::SIZE_WIDTH:
3120 if( value.Get( mTargetSize.width ) )
3122 // Notify deriving classes
3123 OnSizeAnimation( animation, mTargetSize );
3128 case Dali::Actor::Property::SIZE_HEIGHT:
3130 if( value.Get( mTargetSize.height ) )
3132 // Notify deriving classes
3133 OnSizeAnimation( animation, mTargetSize );
3138 case Dali::Actor::Property::SIZE_DEPTH:
3140 if( value.Get( mTargetSize.depth ) )
3142 // Notify deriving classes
3143 OnSizeAnimation( animation, mTargetSize );
3148 case Dali::Actor::Property::POSITION:
3150 value.Get( mTargetPosition );
3154 case Dali::Actor::Property::POSITION_X:
3156 value.Get( mTargetPosition.x );
3160 case Dali::Actor::Property::POSITION_Y:
3162 value.Get( mTargetPosition.y );
3166 case Dali::Actor::Property::POSITION_Z:
3168 value.Get( mTargetPosition.z );
3172 case Dali::Actor::Property::ORIENTATION:
3174 value.Get( mTargetOrientation );
3178 case Dali::Actor::Property::SCALE:
3180 value.Get( mTargetScale );
3184 case Dali::Actor::Property::SCALE_X:
3186 value.Get( mTargetScale.x );
3190 case Dali::Actor::Property::SCALE_Y:
3192 value.Get( mTargetScale.y );
3196 case Dali::Actor::Property::SCALE_Z:
3198 value.Get( mTargetScale.z );
3202 case Dali::Actor::Property::VISIBLE:
3204 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3208 case Dali::Actor::Property::COLOR:
3210 value.Get( mTargetColor );
3214 case Dali::Actor::Property::COLOR_RED:
3216 value.Get( mTargetColor.r );
3220 case Dali::Actor::Property::COLOR_GREEN:
3222 value.Get( mTargetColor.g );
3226 case Dali::Actor::Property::COLOR_BLUE:
3228 value.Get( mTargetColor.b );
3232 case Dali::Actor::Property::COLOR_ALPHA:
3233 case Dali::DevelActor::Property::OPACITY:
3235 value.Get( mTargetColor.a );
3241 // Not an animatable property. Do nothing.
3252 case Dali::Actor::Property::SIZE:
3254 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3256 // Notify deriving classes
3257 OnSizeAnimation( animation, mTargetSize );
3262 case Dali::Actor::Property::SIZE_WIDTH:
3264 if( AdjustValue< float >( mTargetSize.width, value ) )
3266 // Notify deriving classes
3267 OnSizeAnimation( animation, mTargetSize );
3272 case Dali::Actor::Property::SIZE_HEIGHT:
3274 if( AdjustValue< float >( mTargetSize.height, value ) )
3276 // Notify deriving classes
3277 OnSizeAnimation( animation, mTargetSize );
3282 case Dali::Actor::Property::SIZE_DEPTH:
3284 if( AdjustValue< float >( mTargetSize.depth, value ) )
3286 // Notify deriving classes
3287 OnSizeAnimation( animation, mTargetSize );
3292 case Dali::Actor::Property::POSITION:
3294 AdjustValue< Vector3 >( mTargetPosition, value );
3298 case Dali::Actor::Property::POSITION_X:
3300 AdjustValue< float >( mTargetPosition.x, value );
3304 case Dali::Actor::Property::POSITION_Y:
3306 AdjustValue< float >( mTargetPosition.y, value );
3310 case Dali::Actor::Property::POSITION_Z:
3312 AdjustValue< float >( mTargetPosition.z, value );
3316 case Dali::Actor::Property::ORIENTATION:
3318 Quaternion relativeValue;
3319 if( value.Get( relativeValue ) )
3321 mTargetOrientation *= relativeValue;
3326 case Dali::Actor::Property::SCALE:
3328 AdjustValue< Vector3 >( mTargetScale, value );
3332 case Dali::Actor::Property::SCALE_X:
3334 AdjustValue< float >( mTargetScale.x, value );
3338 case Dali::Actor::Property::SCALE_Y:
3340 AdjustValue< float >( mTargetScale.y, value );
3344 case Dali::Actor::Property::SCALE_Z:
3346 AdjustValue< float >( mTargetScale.z, value );
3350 case Dali::Actor::Property::VISIBLE:
3352 bool relativeValue = false;
3353 if( value.Get( relativeValue ) )
3355 bool visible = mVisible || relativeValue;
3356 SetVisibleInternal( visible, SendMessage::FALSE );
3361 case Dali::Actor::Property::COLOR:
3363 AdjustValue< Vector4 >( mTargetColor, value );
3367 case Dali::Actor::Property::COLOR_RED:
3369 AdjustValue< float >( mTargetColor.r, value );
3373 case Dali::Actor::Property::COLOR_GREEN:
3375 AdjustValue< float >( mTargetColor.g, value );
3379 case Dali::Actor::Property::COLOR_BLUE:
3381 AdjustValue< float >( mTargetColor.b, value );
3385 case Dali::Actor::Property::COLOR_ALPHA:
3386 case Dali::DevelActor::Property::OPACITY:
3388 AdjustValue< float >( mTargetColor.a, value );
3394 // Not an animatable property. Do nothing.
3403 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3408 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3410 // This method should only return an object connected to the scene-graph
3411 return OnStage() ? mNode : NULL;
3414 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3416 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3418 const PropertyBase* property( NULL );
3420 // This method should only return a property of an object connected to the scene-graph
3426 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3428 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3429 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3431 property = animatable->GetSceneGraphProperty();
3433 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3434 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3436 CustomPropertyMetadata* custom = FindCustomProperty( index );
3437 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3439 property = custom->GetSceneGraphProperty();
3441 else if( NULL != mNode )
3445 case Dali::Actor::Property::SIZE:
3446 property = &mNode->mSize;
3449 case Dali::Actor::Property::SIZE_WIDTH:
3450 property = &mNode->mSize;
3453 case Dali::Actor::Property::SIZE_HEIGHT:
3454 property = &mNode->mSize;
3457 case Dali::Actor::Property::SIZE_DEPTH:
3458 property = &mNode->mSize;
3461 case Dali::Actor::Property::POSITION:
3462 property = &mNode->mPosition;
3465 case Dali::Actor::Property::POSITION_X:
3466 property = &mNode->mPosition;
3469 case Dali::Actor::Property::POSITION_Y:
3470 property = &mNode->mPosition;
3473 case Dali::Actor::Property::POSITION_Z:
3474 property = &mNode->mPosition;
3477 case Dali::Actor::Property::ORIENTATION:
3478 property = &mNode->mOrientation;
3481 case Dali::Actor::Property::SCALE:
3482 property = &mNode->mScale;
3485 case Dali::Actor::Property::SCALE_X:
3486 property = &mNode->mScale;
3489 case Dali::Actor::Property::SCALE_Y:
3490 property = &mNode->mScale;
3493 case Dali::Actor::Property::SCALE_Z:
3494 property = &mNode->mScale;
3497 case Dali::Actor::Property::VISIBLE:
3498 property = &mNode->mVisible;
3501 case Dali::Actor::Property::COLOR:
3502 property = &mNode->mColor;
3505 case Dali::Actor::Property::COLOR_RED:
3506 property = &mNode->mColor;
3509 case Dali::Actor::Property::COLOR_GREEN:
3510 property = &mNode->mColor;
3513 case Dali::Actor::Property::COLOR_BLUE:
3514 property = &mNode->mColor;
3517 case Dali::Actor::Property::COLOR_ALPHA:
3518 case Dali::DevelActor::Property::OPACITY:
3519 property = &mNode->mColor;
3530 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3532 const PropertyInputImpl* property( NULL );
3534 // This method should only return a property of an object connected to the scene-graph
3540 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3542 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3543 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3545 property = animatable->GetSceneGraphProperty();
3547 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3548 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3550 CustomPropertyMetadata* custom = FindCustomProperty( index );
3551 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3552 property = custom->GetSceneGraphProperty();
3554 else if( NULL != mNode )
3558 case Dali::Actor::Property::PARENT_ORIGIN:
3559 property = &mNode->mParentOrigin;
3562 case Dali::Actor::Property::PARENT_ORIGIN_X:
3563 property = &mNode->mParentOrigin;
3566 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3567 property = &mNode->mParentOrigin;
3570 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3571 property = &mNode->mParentOrigin;
3574 case Dali::Actor::Property::ANCHOR_POINT:
3575 property = &mNode->mAnchorPoint;
3578 case Dali::Actor::Property::ANCHOR_POINT_X:
3579 property = &mNode->mAnchorPoint;
3582 case Dali::Actor::Property::ANCHOR_POINT_Y:
3583 property = &mNode->mAnchorPoint;
3586 case Dali::Actor::Property::ANCHOR_POINT_Z:
3587 property = &mNode->mAnchorPoint;
3590 case Dali::Actor::Property::SIZE:
3591 property = &mNode->mSize;
3594 case Dali::Actor::Property::SIZE_WIDTH:
3595 property = &mNode->mSize;
3598 case Dali::Actor::Property::SIZE_HEIGHT:
3599 property = &mNode->mSize;
3602 case Dali::Actor::Property::SIZE_DEPTH:
3603 property = &mNode->mSize;
3606 case Dali::Actor::Property::POSITION:
3607 property = &mNode->mPosition;
3610 case Dali::Actor::Property::POSITION_X:
3611 property = &mNode->mPosition;
3614 case Dali::Actor::Property::POSITION_Y:
3615 property = &mNode->mPosition;
3618 case Dali::Actor::Property::POSITION_Z:
3619 property = &mNode->mPosition;
3622 case Dali::Actor::Property::WORLD_POSITION:
3623 property = &mNode->mWorldPosition;
3626 case Dali::Actor::Property::WORLD_POSITION_X:
3627 property = &mNode->mWorldPosition;
3630 case Dali::Actor::Property::WORLD_POSITION_Y:
3631 property = &mNode->mWorldPosition;
3634 case Dali::Actor::Property::WORLD_POSITION_Z:
3635 property = &mNode->mWorldPosition;
3638 case Dali::Actor::Property::ORIENTATION:
3639 property = &mNode->mOrientation;
3642 case Dali::Actor::Property::WORLD_ORIENTATION:
3643 property = &mNode->mWorldOrientation;
3646 case Dali::Actor::Property::SCALE:
3647 property = &mNode->mScale;
3650 case Dali::Actor::Property::SCALE_X:
3651 property = &mNode->mScale;
3654 case Dali::Actor::Property::SCALE_Y:
3655 property = &mNode->mScale;
3658 case Dali::Actor::Property::SCALE_Z:
3659 property = &mNode->mScale;
3662 case Dali::Actor::Property::WORLD_SCALE:
3663 property = &mNode->mWorldScale;
3666 case Dali::Actor::Property::VISIBLE:
3667 property = &mNode->mVisible;
3670 case Dali::Actor::Property::COLOR:
3671 property = &mNode->mColor;
3674 case Dali::Actor::Property::COLOR_RED:
3675 property = &mNode->mColor;
3678 case Dali::Actor::Property::COLOR_GREEN:
3679 property = &mNode->mColor;
3682 case Dali::Actor::Property::COLOR_BLUE:
3683 property = &mNode->mColor;
3686 case Dali::Actor::Property::COLOR_ALPHA:
3687 case Dali::DevelActor::Property::OPACITY:
3689 property = &mNode->mColor;
3693 case Dali::Actor::Property::WORLD_COLOR:
3694 property = &mNode->mWorldColor;
3697 case Dali::Actor::Property::WORLD_MATRIX:
3698 property = &mNode->mWorldMatrix;
3709 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3711 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3713 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3715 // check whether the animatable property is registered already, if not then register one.
3716 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3717 if( animatableProperty )
3719 componentIndex = animatableProperty->componentIndex;
3726 case Dali::Actor::Property::PARENT_ORIGIN_X:
3727 case Dali::Actor::Property::ANCHOR_POINT_X:
3728 case Dali::Actor::Property::SIZE_WIDTH:
3729 case Dali::Actor::Property::POSITION_X:
3730 case Dali::Actor::Property::WORLD_POSITION_X:
3731 case Dali::Actor::Property::SCALE_X:
3732 case Dali::Actor::Property::COLOR_RED:
3738 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3739 case Dali::Actor::Property::ANCHOR_POINT_Y:
3740 case Dali::Actor::Property::SIZE_HEIGHT:
3741 case Dali::Actor::Property::POSITION_Y:
3742 case Dali::Actor::Property::WORLD_POSITION_Y:
3743 case Dali::Actor::Property::SCALE_Y:
3744 case Dali::Actor::Property::COLOR_GREEN:
3750 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3751 case Dali::Actor::Property::ANCHOR_POINT_Z:
3752 case Dali::Actor::Property::SIZE_DEPTH:
3753 case Dali::Actor::Property::POSITION_Z:
3754 case Dali::Actor::Property::WORLD_POSITION_Z:
3755 case Dali::Actor::Property::SCALE_Z:
3756 case Dali::Actor::Property::COLOR_BLUE:
3762 case Dali::Actor::Property::COLOR_ALPHA:
3763 case Dali::DevelActor::Property::OPACITY:
3777 return componentIndex;
3780 void Actor::SetParent( Actor* parent )
3784 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3788 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3791 // Instruct each actor to create a corresponding node in the scene graph
3792 ConnectToStage( parent->GetHierarchyDepth() );
3795 // Resolve the name and index for the child properties if any
3796 ResolveChildProperties();
3798 else // parent being set to NULL
3800 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3804 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3807 DALI_ASSERT_ALWAYS( mNode != NULL );
3811 // Disconnect the Node & its children from the scene-graph.
3812 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3815 // Instruct each actor to discard pointers to the scene-graph
3816 DisconnectFromStage();
3821 SceneGraph::Node* Actor::CreateNode() const
3826 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3829 Actor* actor = dynamic_cast< Actor* >( object );
3833 if( 0 == actionName.compare( ACTION_SHOW ) )
3835 actor->SetVisible( true );
3838 else if( 0 == actionName.compare( ACTION_HIDE ) )
3840 actor->SetVisible( false );
3848 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3850 bool valueSet = true;
3854 case Dali::Actor::Property::PARENT_ORIGIN:
3856 value = GetCurrentParentOrigin();
3860 case Dali::Actor::Property::PARENT_ORIGIN_X:
3862 value = GetCurrentParentOrigin().x;
3866 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3868 value = GetCurrentParentOrigin().y;
3872 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3874 value = GetCurrentParentOrigin().z;
3878 case Dali::Actor::Property::ANCHOR_POINT:
3880 value = GetCurrentAnchorPoint();
3884 case Dali::Actor::Property::ANCHOR_POINT_X:
3886 value = GetCurrentAnchorPoint().x;
3890 case Dali::Actor::Property::ANCHOR_POINT_Y:
3892 value = GetCurrentAnchorPoint().y;
3896 case Dali::Actor::Property::ANCHOR_POINT_Z:
3898 value = GetCurrentAnchorPoint().z;
3902 case Dali::Actor::Property::SIZE:
3904 value = GetTargetSize();
3908 case Dali::Actor::Property::SIZE_WIDTH:
3910 value = GetTargetSize().width;
3914 case Dali::Actor::Property::SIZE_HEIGHT:
3916 value = GetTargetSize().height;
3920 case Dali::Actor::Property::SIZE_DEPTH:
3922 value = GetTargetSize().depth;
3926 case Dali::Actor::Property::POSITION:
3928 value = GetTargetPosition();
3932 case Dali::Actor::Property::POSITION_X:
3934 value = GetTargetPosition().x;
3938 case Dali::Actor::Property::POSITION_Y:
3940 value = GetTargetPosition().y;
3944 case Dali::Actor::Property::POSITION_Z:
3946 value = GetTargetPosition().z;
3950 case Dali::Actor::Property::ORIENTATION:
3952 value = mTargetOrientation;
3956 case Dali::Actor::Property::SCALE:
3958 value = mTargetScale;
3962 case Dali::Actor::Property::SCALE_X:
3964 value = mTargetScale.x;
3968 case Dali::Actor::Property::SCALE_Y:
3970 value = mTargetScale.y;
3974 case Dali::Actor::Property::SCALE_Z:
3976 value = mTargetScale.z;
3980 case Dali::Actor::Property::VISIBLE:
3986 case Dali::Actor::Property::COLOR:
3988 value = mTargetColor;
3992 case Dali::Actor::Property::COLOR_RED:
3994 value = mTargetColor.r;
3998 case Dali::Actor::Property::COLOR_GREEN:
4000 value = mTargetColor.g;
4004 case Dali::Actor::Property::COLOR_BLUE:
4006 value = mTargetColor.b;
4010 case Dali::Actor::Property::COLOR_ALPHA:
4011 case Dali::DevelActor::Property::OPACITY:
4013 value = mTargetColor.a;
4017 case Dali::Actor::Property::NAME:
4023 case Dali::Actor::Property::SENSITIVE:
4025 value = IsSensitive();
4029 case Dali::Actor::Property::LEAVE_REQUIRED:
4031 value = GetLeaveRequired();
4035 case Dali::Actor::Property::INHERIT_POSITION:
4037 value = IsPositionInherited();
4041 case Dali::Actor::Property::INHERIT_ORIENTATION:
4043 value = IsOrientationInherited();
4047 case Dali::Actor::Property::INHERIT_SCALE:
4049 value = IsScaleInherited();
4053 case Dali::Actor::Property::COLOR_MODE:
4055 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4059 case Dali::Actor::Property::POSITION_INHERITANCE:
4061 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4065 case Dali::Actor::Property::DRAW_MODE:
4067 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4071 case Dali::Actor::Property::SIZE_MODE_FACTOR:
4073 value = GetSizeModeFactor();
4077 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4079 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4083 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4085 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4089 case Dali::Actor::Property::SIZE_SCALE_POLICY:
4091 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4095 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4097 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4101 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4103 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4107 case Dali::Actor::Property::PADDING:
4109 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4110 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4111 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4115 case Dali::Actor::Property::MINIMUM_SIZE:
4117 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4121 case Dali::Actor::Property::MAXIMUM_SIZE:
4123 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4127 case Dali::Actor::Property::CLIPPING_MODE:
4129 value = mClippingMode;
4133 case Dali::DevelActor::Property::SIBLING_ORDER:
4135 value = static_cast<int>( GetSiblingOrder() );
4139 case Dali::DevelActor::Property::SCREEN_POSITION:
4141 value = GetCurrentScreenPosition();
4145 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4147 value = mPositionUsesAnchorPoint;
4151 case Dali::DevelActor::Property::LAYOUT_DIRECTION:
4153 value = mLayoutDirection;
4157 case Dali::DevelActor::Property::INHERIT_LAYOUT_DIRECTION:
4159 value = IsLayoutDirectionInherited();
4165 // Must be a scene-graph only property
4174 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
4176 bool valueSet = true;
4180 case Dali::Actor::Property::SIZE:
4182 value = GetCurrentSize();
4186 case Dali::Actor::Property::SIZE_WIDTH:
4188 value = GetCurrentSize().width;
4192 case Dali::Actor::Property::SIZE_HEIGHT:
4194 value = GetCurrentSize().height;
4198 case Dali::Actor::Property::SIZE_DEPTH:
4200 value = GetCurrentSize().depth;
4204 case Dali::Actor::Property::POSITION:
4206 value = GetCurrentPosition();
4210 case Dali::Actor::Property::POSITION_X:
4212 value = GetCurrentPosition().x;
4216 case Dali::Actor::Property::POSITION_Y:
4218 value = GetCurrentPosition().y;
4222 case Dali::Actor::Property::POSITION_Z:
4224 value = GetCurrentPosition().z;
4228 case Dali::Actor::Property::WORLD_POSITION:
4230 value = GetCurrentWorldPosition();
4234 case Dali::Actor::Property::WORLD_POSITION_X:
4236 value = GetCurrentWorldPosition().x;
4240 case Dali::Actor::Property::WORLD_POSITION_Y:
4242 value = GetCurrentWorldPosition().y;
4246 case Dali::Actor::Property::WORLD_POSITION_Z:
4248 value = GetCurrentWorldPosition().z;
4252 case Dali::Actor::Property::ORIENTATION:
4254 value = GetCurrentOrientation();
4258 case Dali::Actor::Property::WORLD_ORIENTATION:
4260 value = GetCurrentWorldOrientation();
4264 case Dali::Actor::Property::SCALE:
4266 value = GetCurrentScale();
4270 case Dali::Actor::Property::SCALE_X:
4272 value = GetCurrentScale().x;
4276 case Dali::Actor::Property::SCALE_Y:
4278 value = GetCurrentScale().y;
4282 case Dali::Actor::Property::SCALE_Z:
4284 value = GetCurrentScale().z;
4288 case Dali::Actor::Property::WORLD_SCALE:
4290 value = GetCurrentWorldScale();
4294 case Dali::Actor::Property::COLOR:
4296 value = GetCurrentColor();
4300 case Dali::Actor::Property::COLOR_RED:
4302 value = GetCurrentColor().r;
4306 case Dali::Actor::Property::COLOR_GREEN:
4308 value = GetCurrentColor().g;
4312 case Dali::Actor::Property::COLOR_BLUE:
4314 value = GetCurrentColor().b;
4318 case Dali::Actor::Property::COLOR_ALPHA:
4319 case Dali::DevelActor::Property::OPACITY:
4321 value = GetCurrentColor().a;
4325 case Dali::Actor::Property::WORLD_COLOR:
4327 value = GetCurrentWorldColor();
4331 case Dali::Actor::Property::WORLD_MATRIX:
4333 value = GetCurrentWorldMatrix();
4337 case Dali::Actor::Property::VISIBLE:
4339 value = IsVisible();
4345 // Must be an event-side only property
4354 void Actor::EnsureRelayoutData()
4356 // Assign relayout data.
4357 if( !mRelayoutData )
4359 mRelayoutData = new RelayoutData();
4363 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4365 // Check if actor is dependent on parent
4366 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4368 if( ( dimension & ( 1 << i ) ) )
4370 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4371 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4381 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4383 // Check if actor is dependent on children
4384 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4386 if( ( dimension & ( 1 << i ) ) )
4388 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4389 switch( resizePolicy )
4391 case ResizePolicy::FIT_TO_CHILDREN:
4392 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4408 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4410 return Actor::RelayoutDependentOnChildren( dimension );
4413 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4415 // Check each possible dimension and see if it is dependent on the input one
4416 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4418 if( dimension & ( 1 << i ) )
4420 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4427 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4429 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4431 if( dimension & ( 1 << i ) )
4433 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4438 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4440 // If more than one dimension is requested, just return the first one found
4441 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4443 if( ( dimension & ( 1 << i ) ) )
4445 return mRelayoutData->negotiatedDimensions[ i ];
4449 return 0.0f; // Default
4452 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4454 EnsureRelayoutData();
4456 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4458 if( dimension & ( 1 << i ) )
4460 mRelayoutData->dimensionPadding[ i ] = padding;
4465 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4467 if ( mRelayoutData )
4469 // If more than one dimension is requested, just return the first one found
4470 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4472 if( ( dimension & ( 1 << i ) ) )
4474 return mRelayoutData->dimensionPadding[ i ];
4479 return GetDefaultDimensionPadding();
4482 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4484 EnsureRelayoutData();
4486 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4488 if( dimension & ( 1 << i ) )
4490 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4495 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4497 if ( mRelayoutData )
4499 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4501 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4511 float Actor::GetHeightForWidthBase( float width )
4513 float height = 0.0f;
4515 const Vector3 naturalSize = GetNaturalSize();
4516 if( naturalSize.width > 0.0f )
4518 height = naturalSize.height * width / naturalSize.width;
4520 else // we treat 0 as 1:1 aspect ratio
4528 float Actor::GetWidthForHeightBase( float height )
4532 const Vector3 naturalSize = GetNaturalSize();
4533 if( naturalSize.height > 0.0f )
4535 width = naturalSize.width * height / naturalSize.height;
4537 else // we treat 0 as 1:1 aspect ratio
4545 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4547 // Fill to parent, taking size mode factor into account
4548 switch( child.GetResizePolicy( dimension ) )
4550 case ResizePolicy::FILL_TO_PARENT:
4552 return GetLatestSize( dimension );
4555 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4557 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4560 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4562 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4567 return GetLatestSize( dimension );
4572 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4574 // Can be overridden in derived class
4575 return CalculateChildSizeBase( child, dimension );
4578 float Actor::GetHeightForWidth( float width )
4580 // Can be overridden in derived class
4581 return GetHeightForWidthBase( width );
4584 float Actor::GetWidthForHeight( float height )
4586 // Can be overridden in derived class
4587 return GetWidthForHeightBase( height );
4590 float Actor::GetLatestSize( Dimension::Type dimension ) const
4592 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4595 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4597 Vector2 padding = GetPadding( dimension );
4599 return GetLatestSize( dimension ) + padding.x + padding.y;
4602 float Actor::NegotiateFromParent( Dimension::Type dimension )
4604 Actor* parent = GetParent();
4607 Vector2 padding( GetPadding( dimension ) );
4608 Vector2 parentPadding( parent->GetPadding( dimension ) );
4609 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4615 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4617 float maxDimensionPoint = 0.0f;
4619 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4621 ActorPtr child = GetChildAt( i );
4623 if( !child->RelayoutDependentOnParent( dimension ) )
4625 // Calculate the min and max points that the children range across
4626 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4627 float dimensionSize = child->GetRelayoutSize( dimension );
4628 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4632 return maxDimensionPoint;
4635 float Actor::GetSize( Dimension::Type dimension ) const
4637 return GetDimensionValue( mTargetSize, dimension );
4640 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4642 return GetDimensionValue( GetNaturalSize(), dimension );
4645 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4647 switch( GetResizePolicy( dimension ) )
4649 case ResizePolicy::USE_NATURAL_SIZE:
4651 return GetNaturalSize( dimension );
4654 case ResizePolicy::FIXED:
4656 return GetDimensionValue( GetPreferredSize(), dimension );
4659 case ResizePolicy::USE_ASSIGNED_SIZE:
4661 return GetDimensionValue( maximumSize, dimension );
4664 case ResizePolicy::FILL_TO_PARENT:
4665 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4666 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4668 return NegotiateFromParent( dimension );
4671 case ResizePolicy::FIT_TO_CHILDREN:
4673 return NegotiateFromChildren( dimension );
4676 case ResizePolicy::DIMENSION_DEPENDENCY:
4678 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4681 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4683 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4686 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4688 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4700 return 0.0f; // Default
4703 float Actor::ClampDimension( float size, Dimension::Type dimension )
4705 const float minSize = GetMinimumSize( dimension );
4706 const float maxSize = GetMaximumSize( dimension );
4708 return std::max( minSize, std::min( size, maxSize ) );
4711 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4713 // Check if it needs to be negotiated
4714 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4716 // Check that we havn't gotten into an infinite loop
4717 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4718 bool recursionFound = false;
4719 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4721 if( *it == searchActor )
4723 recursionFound = true;
4728 if( !recursionFound )
4730 // Record the path that we have taken
4731 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4733 // Dimension dependency check
4734 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4736 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4738 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4740 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4744 // Parent dependency check
4745 Actor* parent = GetParent();
4746 if( parent && RelayoutDependentOnParent( dimension ) )
4748 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4751 // Children dependency check
4752 if( RelayoutDependentOnChildren( dimension ) )
4754 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4756 ActorPtr child = GetChildAt( i );
4758 // Only relayout child first if it is not dependent on this actor
4759 if( !child->RelayoutDependentOnParent( dimension ) )
4761 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4766 // For deriving classes
4767 OnCalculateRelayoutSize( dimension );
4769 // All dependencies checked, calculate the size and set negotiated flag
4770 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4772 SetNegotiatedDimension( newSize, dimension );
4773 SetLayoutNegotiated( true, dimension );
4775 // For deriving classes
4776 OnLayoutNegotiated( newSize, dimension );
4778 // This actor has been successfully processed, pop it off the recursion stack
4779 recursionStack.pop_back();
4783 // TODO: Break infinite loop
4784 SetLayoutNegotiated( true, dimension );
4789 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4791 // Negotiate all dimensions that require it
4792 ActorDimensionStack recursionStack;
4794 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4796 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4799 NegotiateDimension( dimension, allocatedSize, recursionStack );
4803 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4805 switch( mRelayoutData->sizeSetPolicy )
4807 case SizeScalePolicy::USE_SIZE_SET:
4812 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4814 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4815 const Vector3 naturalSize = GetNaturalSize();
4816 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4818 const float sizeRatio = size.width / size.height;
4819 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4821 if( naturalSizeRatio < sizeRatio )
4823 return Vector2( naturalSizeRatio * size.height, size.height );
4825 else if( naturalSizeRatio > sizeRatio )
4827 return Vector2( size.width, size.width / naturalSizeRatio );
4838 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4840 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4841 const Vector3 naturalSize = GetNaturalSize();
4842 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4844 const float sizeRatio = size.width / size.height;
4845 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4847 if( naturalSizeRatio < sizeRatio )
4849 return Vector2( size.width, size.width / naturalSizeRatio );
4851 else if( naturalSizeRatio > sizeRatio )
4853 return Vector2( naturalSizeRatio * size.height, size.height );
4872 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4874 // Do the set actor size
4875 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4877 // Adjust for size set policy
4878 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4880 // Lock the flag to stop recursive relayouts on set size
4881 mRelayoutData->insideRelayout = true;
4882 SetSize( negotiatedSize );
4883 mRelayoutData->insideRelayout = false;
4885 // Clear flags for all dimensions
4886 SetLayoutDirty( false );
4888 // Give deriving classes a chance to respond
4889 OnRelayout( negotiatedSize, container );
4891 if( !mOnRelayoutSignal.Empty() )
4893 Dali::Actor handle( this );
4894 mOnRelayoutSignal.Emit( handle );
4898 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4900 // Force a size negotiation for actors that has assigned size during relayout
4901 // This is required as otherwise the flags that force a relayout will not
4902 // necessarilly be set. This will occur if the actor has already been laid out.
4903 // The dirty flags are then cleared. Then if the actor is added back into the
4904 // relayout container afterwards, the dirty flags would still be clear...
4905 // causing a relayout to be skipped. Here we force any actors added to the
4906 // container to be relayed out.
4907 DALI_LOG_TIMER_START( NegSizeTimer1 );
4909 if( GetUseAssignedSize(Dimension::WIDTH ) )
4911 SetLayoutNegotiated( false, Dimension::WIDTH );
4913 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4915 SetLayoutNegotiated( false, Dimension::HEIGHT );
4918 // Do the negotiation
4919 NegotiateDimensions( allocatedSize );
4921 // Set the actor size
4922 SetNegotiatedSize( container );
4924 // Negotiate down to children
4925 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4927 ActorPtr child = GetChildAt( i );
4929 // Forces children that have already been laid out to be relayed out
4930 // if they have assigned size during relayout.
4931 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4933 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4934 child->SetLayoutDirty(true, Dimension::WIDTH);
4937 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4939 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4940 child->SetLayoutDirty(true, Dimension::HEIGHT);
4943 // Only relayout if required
4944 if( child->RelayoutRequired() )
4946 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4949 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4952 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4956 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4958 if( dimension & ( 1 << i ) )
4960 mRelayoutData->useAssignedSize[ i ] = use;
4966 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4968 if ( mRelayoutData )
4970 // If more than one dimension is requested, just return the first one found
4971 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4973 if( dimension & ( 1 << i ) )
4975 return mRelayoutData->useAssignedSize[ i ];
4983 void Actor::RelayoutRequest( Dimension::Type dimension )
4985 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4986 if( relayoutController )
4988 Dali::Actor self( this );
4989 relayoutController->RequestRelayout( self, dimension );
4993 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4997 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
5001 void Actor::SetPreferredSize( const Vector2& size )
5003 EnsureRelayoutData();
5005 if( size.width > 0.0f )
5007 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
5010 if( size.height > 0.0f )
5012 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
5015 mRelayoutData->preferredSize = size;
5020 Vector2 Actor::GetPreferredSize() const
5022 if ( mRelayoutData )
5024 return Vector2( mRelayoutData->preferredSize );
5027 return GetDefaultPreferredSize();
5030 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
5032 EnsureRelayoutData();
5034 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5036 if( dimension & ( 1 << i ) )
5038 mRelayoutData->minimumSize[ i ] = size;
5045 float Actor::GetMinimumSize( Dimension::Type dimension ) const
5047 if ( mRelayoutData )
5049 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5051 if( dimension & ( 1 << i ) )
5053 return mRelayoutData->minimumSize[ i ];
5058 return 0.0f; // Default
5061 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5063 EnsureRelayoutData();
5065 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5067 if( dimension & ( 1 << i ) )
5069 mRelayoutData->maximumSize[ i ] = size;
5076 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5078 if ( mRelayoutData )
5080 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5082 if( dimension & ( 1 << i ) )
5084 return mRelayoutData->maximumSize[ i ];
5089 return FLT_MAX; // Default
5092 Object* Actor::GetParentObject() const
5097 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5099 if( mVisible != visible )
5101 if( sendMessage == SendMessage::TRUE && NULL != mNode )
5103 // mNode is being used in a separate thread; queue a message to set the value & base value
5104 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5109 // Emit the signal on this actor and all its children
5110 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5114 void Actor::SetSiblingOrder( unsigned int order )
5118 ActorContainer& siblings = *(mParent->mChildren);
5119 unsigned int currentOrder = GetSiblingOrder();
5121 if( order != currentOrder )
5127 else if( order < siblings.size() -1 )
5129 if( order > currentOrder )
5131 RaiseAbove( *siblings[order] );
5135 LowerBelow( *siblings[order] );
5146 unsigned int Actor::GetSiblingOrder() const
5148 unsigned int order = 0;
5152 ActorContainer& siblings = *(mParent->mChildren);
5153 for( size_t i=0; i<siblings.size(); ++i )
5155 if( siblings[i] == this )
5166 void Actor::RequestRebuildDepthTree()
5170 StagePtr stage = Stage::GetCurrent();
5173 stage->RequestRebuildDepthTree();
5182 ActorContainer& siblings = *(mParent->mChildren);
5183 if( siblings.back() != this ) // If not already at end
5185 for( size_t i=0; i<siblings.size(); ++i )
5187 if( siblings[i] == this )
5190 ActorPtr next = siblings[i+1];
5191 siblings[i+1] = this;
5197 RequestRebuildDepthTree();
5201 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5209 ActorContainer& siblings = *(mParent->mChildren);
5210 if( siblings.front() != this ) // If not already at beginning
5212 for( size_t i=1; i<siblings.size(); ++i )
5214 if( siblings[i] == this )
5216 // Swap with previous
5217 ActorPtr previous = siblings[i-1];
5218 siblings[i-1] = this;
5219 siblings[i] = previous;
5224 RequestRebuildDepthTree();
5228 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5232 void Actor::RaiseToTop()
5236 ActorContainer& siblings = *(mParent->mChildren);
5237 if( siblings.back() != this ) // If not already at end
5239 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5240 if( iter != siblings.end() )
5242 siblings.erase(iter);
5243 siblings.push_back(ActorPtr(this));
5246 RequestRebuildDepthTree();
5250 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5254 void Actor::LowerToBottom()
5258 ActorContainer& siblings = *(mParent->mChildren);
5259 if( siblings.front() != this ) // If not already at bottom,
5261 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5263 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5264 if( iter != siblings.end() )
5266 siblings.erase(iter);
5267 siblings.insert(siblings.begin(), thisPtr);
5270 RequestRebuildDepthTree();
5274 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5278 void Actor::RaiseAbove( Internal::Actor& target )
5282 ActorContainer& siblings = *(mParent->mChildren);
5283 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5285 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5287 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5288 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5289 if( thisIter < targetIter )
5291 siblings.erase(thisIter);
5292 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5293 // invalidate thisIter)
5294 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5296 siblings.insert(targetIter, thisPtr);
5298 RequestRebuildDepthTree();
5303 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5307 void Actor::LowerBelow( Internal::Actor& target )
5311 ActorContainer& siblings = *(mParent->mChildren);
5312 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5314 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5316 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5317 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5319 if( thisIter > targetIter )
5321 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5322 siblings.insert(targetIter, thisPtr);
5324 RequestRebuildDepthTree();
5329 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5333 void Actor::SetInheritLayoutDirection( bool inherit )
5335 if( mInheritLayoutDirection != inherit )
5337 mInheritLayoutDirection = inherit;
5339 if( inherit && mParent )
5341 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5346 bool Actor::IsLayoutDirectionInherited() const
5348 return mInheritLayoutDirection;
5351 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::DevelActor::LayoutDirection::Type direction, bool set )
5353 if( actor && ( actor->mInheritLayoutDirection || set ) )
5355 if( actor->mLayoutDirection != direction)
5357 actor->mLayoutDirection = direction;
5358 actor->EmitLayoutDirectionChangedSignal( direction );
5359 actor->RelayoutRequest();
5362 if( actor->GetChildCount() > 0 )
5364 ActorContainer& children = actor->GetChildrenInternal();
5365 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5367 InheritLayoutDirectionRecursively( *iter, direction );
5373 } // namespace Internal