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( "layoutDirectionInheritance", BOOLEAN, true, false, false, Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE )
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 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1999 return mTouchedSignal;
2002 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
2004 return mTouchSignal;
2007 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2009 return mHoveredSignal;
2012 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
2014 return mWheelEventSignal;
2017 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2019 return mOnStageSignal;
2022 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2024 return mOffStageSignal;
2027 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2029 return mOnRelayoutSignal;
2032 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
2034 return mVisibilityChangedSignal;
2037 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2039 bool connected( true );
2040 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2042 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2044 actor->TouchedSignal().Connect( tracker, functor );
2046 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2048 actor->HoveredSignal().Connect( tracker, functor );
2050 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2052 actor->WheelEventSignal().Connect( tracker, functor );
2054 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2056 actor->OnStageSignal().Connect( tracker, functor );
2058 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2060 actor->OffStageSignal().Connect( tracker, functor );
2062 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2064 actor->OnRelayoutSignal().Connect( tracker, functor );
2066 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2068 actor->TouchSignal().Connect( tracker, functor );
2072 // signalName does not match any signal
2079 Actor::Actor( DerivedType derivedType )
2084 mParentOrigin( NULL ),
2085 mAnchorPoint( NULL ),
2086 mRelayoutData( NULL ),
2087 mGestureData( NULL ),
2088 mTargetOrientation( Quaternion::IDENTITY ),
2089 mTargetColor( Color::WHITE ),
2090 mTargetSize( Vector3::ZERO ),
2091 mTargetPosition( Vector3::ZERO ),
2092 mTargetScale( Vector3::ONE ),
2094 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2097 mIsRoot( ROOT_LAYER == derivedType ),
2098 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2099 mIsOnStage( false ),
2101 mLeaveRequired( false ),
2102 mKeyboardFocusable( false ),
2103 mDerivedRequiresTouch( false ),
2104 mDerivedRequiresHover( false ),
2105 mDerivedRequiresWheelEvent( false ),
2106 mOnStageSignalled( false ),
2107 mInsideOnSizeSet( false ),
2108 mInheritPosition( true ),
2109 mInheritOrientation( true ),
2110 mInheritScale( true ),
2111 mPositionUsesAnchorPoint( true ),
2113 mLayoutDirectionInheritance( true ),
2114 mLayoutDirection( DevelActor::LayoutDirection::LTR ),
2115 mDrawMode( DrawMode::NORMAL ),
2116 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2117 mColorMode( Node::DEFAULT_COLOR_MODE ),
2118 mClippingMode( ClippingMode::DISABLED )
2122 void Actor::Initialize()
2124 // Node creation, keep raw-pointer to Node for messaging
2125 mNode = CreateNode();
2126 OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
2127 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
2131 GetEventThreadServices().RegisterObject( this );
2136 // Remove mParent pointers from children even if we're destroying core,
2137 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2140 ActorConstIter endIter = mChildren->end();
2141 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2143 (*iter)->SetParent( NULL );
2149 // Guard to allow handle destruction after Core has been destroyed
2150 if( EventThreadServices::IsCoreRunning() )
2154 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2155 mNode = NULL; // Node is about to be destroyed
2158 GetEventThreadServices().UnregisterObject( this );
2161 // Cleanup optional gesture data
2162 delete mGestureData;
2164 // Cleanup optional parent origin and anchor
2165 delete mParentOrigin;
2166 delete mAnchorPoint;
2168 // Delete optional relayout data
2171 delete mRelayoutData;
2175 void Actor::ConnectToStage( unsigned int parentDepth )
2177 // This container is used instead of walking the Actor hierarchy.
2178 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2179 ActorContainer connectionList;
2181 StagePtr stage = Stage::GetCurrent();
2184 stage->RequestRebuildDepthTree();
2187 // This stage is atomic i.e. not interrupted by user callbacks.
2188 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2190 // Notify applications about the newly connected actors.
2191 const ActorIter endIter = connectionList.end();
2192 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2194 (*iter)->NotifyStageConnection();
2200 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2202 DALI_ASSERT_ALWAYS( !OnStage() );
2207 ConnectToSceneGraph();
2209 // Notification for internal derived classes
2210 OnStageConnectionInternal();
2212 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2213 connectionList.push_back( ActorPtr( this ) );
2215 // Recursively connect children
2218 ActorConstIter endIter = mChildren->end();
2219 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2221 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2227 * This method is called when the Actor is connected to the Stage.
2228 * The parent must have added its Node to the scene-graph.
2229 * The child must connect its Node to the parent's Node.
2230 * This is recursive; the child calls ConnectToStage() for its children.
2232 void Actor::ConnectToSceneGraph()
2234 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2238 // Reparent Node in next Update
2239 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2242 // Request relayout on all actors that are added to the scenegraph
2245 // Notification for Object::Observers
2249 void Actor::NotifyStageConnection()
2251 // Actors can be removed (in a callback), before the on-stage stage is reported.
2252 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2253 if( OnStage() && !mOnStageSignalled )
2255 // Notification for external (CustomActor) derived classes
2256 OnStageConnectionExternal( mDepth );
2258 if( !mOnStageSignal.Empty() )
2260 Dali::Actor handle( this );
2261 mOnStageSignal.Emit( handle );
2264 // Guard against Remove during callbacks
2267 mOnStageSignalled = true; // signal required next time Actor is removed
2272 void Actor::DisconnectFromStage()
2274 // This container is used instead of walking the Actor hierachy.
2275 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2276 ActorContainer disconnectionList;
2278 StagePtr stage = Stage::GetCurrent();
2281 stage->RequestRebuildDepthTree();
2284 // This stage is atomic i.e. not interrupted by user callbacks
2285 RecursiveDisconnectFromStage( disconnectionList );
2287 // Notify applications about the newly disconnected actors.
2288 const ActorIter endIter = disconnectionList.end();
2289 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2291 (*iter)->NotifyStageDisconnection();
2295 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2297 DALI_ASSERT_ALWAYS( OnStage() );
2299 // Recursively disconnect children
2302 ActorConstIter endIter = mChildren->end();
2303 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2305 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2309 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2310 disconnectionList.push_back( ActorPtr( this ) );
2312 // Notification for internal derived classes
2313 OnStageDisconnectionInternal();
2315 DisconnectFromSceneGraph();
2321 * This method is called by an actor or its parent, before a node removal message is sent.
2322 * This is recursive; the child calls DisconnectFromStage() for its children.
2324 void Actor::DisconnectFromSceneGraph()
2326 // Notification for Object::Observers
2327 OnSceneObjectRemove();
2330 void Actor::NotifyStageDisconnection()
2332 // Actors can be added (in a callback), before the off-stage state is reported.
2333 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2334 // only do this step if there is a stage, i.e. Core is not being shut down
2335 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2337 // Notification for external (CustomeActor) derived classes
2338 OnStageDisconnectionExternal();
2340 if( !mOffStageSignal.Empty() )
2342 Dali::Actor handle( this );
2343 mOffStageSignal.Emit( handle );
2346 // Guard against Add during callbacks
2349 mOnStageSignalled = false; // signal required next time Actor is added
2354 bool Actor::IsNodeConnected() const
2356 bool connected( false );
2358 if( OnStage() && ( NULL != mNode ) )
2360 if( IsRoot() || mNode->GetParent() )
2369 // This method initiates traversal of the actor tree using depth-first
2370 // traversal to set a depth index based on traversal order. It sends a
2371 // single message to update manager to update all the actor's nodes in
2372 // this tree with the depth index. The sceneGraphNodeDepths vector's
2373 // elements are ordered by depth, and could be used to reduce sorting
2374 // in the update thread.
2375 void Actor::RebuildDepthTree()
2377 DALI_LOG_TIMER_START(depthTimer);
2379 // Vector of scene-graph nodes and their depths to send to UpdateManager
2380 // in a single message
2381 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2384 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2386 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2387 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2390 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
2392 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2393 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
2395 // Create/add to children of this node
2398 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2400 Actor* childActor = (*it).Get();
2402 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2407 unsigned int Actor::GetDefaultPropertyCount() const
2409 return DEFAULT_PROPERTY_COUNT;
2412 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2414 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2416 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2418 indices.PushBack( i );
2422 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2424 if( index < DEFAULT_PROPERTY_COUNT )
2426 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2432 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2434 Property::Index index = Property::INVALID_INDEX;
2436 // Look for name in default properties
2437 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2439 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2440 if( 0 == name.compare( property->name ) )
2450 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2452 if( index < DEFAULT_PROPERTY_COUNT )
2454 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2460 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2462 if( index < DEFAULT_PROPERTY_COUNT )
2464 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2470 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2472 if( index < DEFAULT_PROPERTY_COUNT )
2474 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2480 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2482 if( index < DEFAULT_PROPERTY_COUNT )
2484 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2487 // index out of range...return Property::NONE
2488 return Property::NONE;
2491 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2495 case Dali::Actor::Property::PARENT_ORIGIN:
2497 Property::Type type = property.GetType();
2498 if( type == Property::VECTOR3 )
2500 SetParentOrigin( property.Get< Vector3 >() );
2502 else if ( type == Property::STRING )
2504 std::string parentOriginString;
2505 property.Get( parentOriginString );
2506 Vector3 parentOrigin;
2507 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2509 SetParentOrigin( parentOrigin );
2515 case Dali::Actor::Property::PARENT_ORIGIN_X:
2517 SetParentOriginX( property.Get< float >() );
2521 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2523 SetParentOriginY( property.Get< float >() );
2527 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2529 SetParentOriginZ( property.Get< float >() );
2533 case Dali::Actor::Property::ANCHOR_POINT:
2535 Property::Type type = property.GetType();
2536 if( type == Property::VECTOR3 )
2538 SetAnchorPoint( property.Get< Vector3 >() );
2540 else if ( type == Property::STRING )
2542 std::string anchorPointString;
2543 property.Get( anchorPointString );
2545 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2547 SetAnchorPoint( anchor );
2553 case Dali::Actor::Property::ANCHOR_POINT_X:
2555 SetAnchorPointX( property.Get< float >() );
2559 case Dali::Actor::Property::ANCHOR_POINT_Y:
2561 SetAnchorPointY( property.Get< float >() );
2565 case Dali::Actor::Property::ANCHOR_POINT_Z:
2567 SetAnchorPointZ( property.Get< float >() );
2571 case Dali::Actor::Property::SIZE:
2573 SetSize( property.Get< Vector3 >() );
2577 case Dali::Actor::Property::SIZE_WIDTH:
2579 SetWidth( property.Get< float >() );
2583 case Dali::Actor::Property::SIZE_HEIGHT:
2585 SetHeight( property.Get< float >() );
2589 case Dali::Actor::Property::SIZE_DEPTH:
2591 SetDepth( property.Get< float >() );
2595 case Dali::Actor::Property::POSITION:
2597 SetPosition( property.Get< Vector3 >() );
2601 case Dali::Actor::Property::POSITION_X:
2603 SetX( property.Get< float >() );
2607 case Dali::Actor::Property::POSITION_Y:
2609 SetY( property.Get< float >() );
2613 case Dali::Actor::Property::POSITION_Z:
2615 SetZ( property.Get< float >() );
2619 case Dali::Actor::Property::ORIENTATION:
2621 SetOrientation( property.Get< Quaternion >() );
2625 case Dali::Actor::Property::SCALE:
2627 SetScale( property.Get< Vector3 >() );
2631 case Dali::Actor::Property::SCALE_X:
2633 SetScaleX( property.Get< float >() );
2637 case Dali::Actor::Property::SCALE_Y:
2639 SetScaleY( property.Get< float >() );
2643 case Dali::Actor::Property::SCALE_Z:
2645 SetScaleZ( property.Get< float >() );
2649 case Dali::Actor::Property::VISIBLE:
2651 SetVisible( property.Get< bool >() );
2655 case Dali::Actor::Property::COLOR:
2657 SetColor( property.Get< Vector4 >() );
2661 case Dali::Actor::Property::COLOR_RED:
2663 SetColorRed( property.Get< float >() );
2667 case Dali::Actor::Property::COLOR_GREEN:
2669 SetColorGreen( property.Get< float >() );
2673 case Dali::Actor::Property::COLOR_BLUE:
2675 SetColorBlue( property.Get< float >() );
2679 case Dali::Actor::Property::COLOR_ALPHA:
2680 case Dali::DevelActor::Property::OPACITY:
2683 if( property.Get( value ) )
2685 SetOpacity( value );
2690 case Dali::Actor::Property::NAME:
2692 SetName( property.Get< std::string >() );
2696 case Dali::Actor::Property::SENSITIVE:
2698 SetSensitive( property.Get< bool >() );
2702 case Dali::Actor::Property::LEAVE_REQUIRED:
2704 SetLeaveRequired( property.Get< bool >() );
2708 case Dali::Actor::Property::INHERIT_POSITION:
2710 SetInheritPosition( property.Get< bool >() );
2714 case Dali::Actor::Property::INHERIT_ORIENTATION:
2716 SetInheritOrientation( property.Get< bool >() );
2720 case Dali::Actor::Property::INHERIT_SCALE:
2722 SetInheritScale( property.Get< bool >() );
2726 case Dali::Actor::Property::COLOR_MODE:
2728 ColorMode mode = mColorMode;
2729 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2731 SetColorMode( mode );
2736 case Dali::Actor::Property::POSITION_INHERITANCE:
2738 PositionInheritanceMode mode = mPositionInheritanceMode;
2739 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2741 SetPositionInheritanceMode( mode );
2746 case Dali::Actor::Property::DRAW_MODE:
2748 DrawMode::Type mode = mDrawMode;
2749 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2751 SetDrawMode( mode );
2756 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2758 SetSizeModeFactor( property.Get< Vector3 >() );
2762 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2764 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2765 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2767 SetResizePolicy( type, Dimension::WIDTH );
2772 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2774 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2775 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2777 SetResizePolicy( type, Dimension::HEIGHT );
2782 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2784 SizeScalePolicy::Type type;
2785 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2787 SetSizeScalePolicy( type );
2792 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2794 if( property.Get< bool >() )
2796 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2801 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2803 if( property.Get< bool >() )
2805 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2810 case Dali::Actor::Property::PADDING:
2812 Vector4 padding = property.Get< Vector4 >();
2813 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2814 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2818 case Dali::Actor::Property::MINIMUM_SIZE:
2820 Vector2 size = property.Get< Vector2 >();
2821 SetMinimumSize( size.x, Dimension::WIDTH );
2822 SetMinimumSize( size.y, Dimension::HEIGHT );
2826 case Dali::Actor::Property::MAXIMUM_SIZE:
2828 Vector2 size = property.Get< Vector2 >();
2829 SetMaximumSize( size.x, Dimension::WIDTH );
2830 SetMaximumSize( size.y, Dimension::HEIGHT );
2834 case Dali::DevelActor::Property::SIBLING_ORDER:
2838 if( property.Get( value ) )
2840 SetSiblingOrder( value );
2845 case Dali::Actor::Property::CLIPPING_MODE:
2847 ClippingMode::Type convertedValue = mClippingMode;
2848 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2850 mClippingMode = convertedValue;
2853 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2859 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2862 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2864 mPositionUsesAnchorPoint = value;
2867 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2873 case Dali::DevelActor::Property::LAYOUT_DIRECTION:
2875 Dali::DevelActor::LayoutDirection::Type direction = mLayoutDirection;
2878 if( Scripting::GetEnumerationProperty< DevelActor::LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2880 flag = mLayoutDirectionInheritance;
2881 mLayoutDirectionInheritance = true;
2882 InheritLayoutDirectionRecursively( this, direction );
2883 mLayoutDirectionInheritance = flag;
2888 case Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE:
2891 if( property.Get( value ) && value != mLayoutDirectionInheritance )
2893 mLayoutDirectionInheritance = value;
2900 // this can happen in the case of a non-animatable default property so just do nothing
2906 // TODO: This method needs to be removed
2907 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2909 switch( entry.GetType() )
2911 case Property::BOOLEAN:
2913 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2914 DALI_ASSERT_DEBUG( NULL != property );
2916 // property is being used in a separate thread; queue a message to set the property
2917 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2922 case Property::INTEGER:
2924 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( 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<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2933 case Property::FLOAT:
2935 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( 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<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2944 case Property::VECTOR2:
2946 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( 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 if(entry.componentIndex == 0)
2952 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2954 else if(entry.componentIndex == 1)
2956 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2960 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2966 case Property::VECTOR3:
2968 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2969 DALI_ASSERT_DEBUG( NULL != property );
2971 // property is being used in a separate thread; queue a message to set the property
2972 if(entry.componentIndex == 0)
2974 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2976 else if(entry.componentIndex == 1)
2978 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2980 else if(entry.componentIndex == 2)
2982 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2986 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2992 case Property::VECTOR4:
2994 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2995 DALI_ASSERT_DEBUG( NULL != property );
2997 // property is being used in a separate thread; queue a message to set the property
2998 if(entry.componentIndex == 0)
3000 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3002 else if(entry.componentIndex == 1)
3004 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3006 else if(entry.componentIndex == 2)
3008 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3010 else if(entry.componentIndex == 3)
3012 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3016 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3022 case Property::ROTATION:
3024 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3025 DALI_ASSERT_DEBUG( NULL != property );
3027 // property is being used in a separate thread; queue a message to set the property
3028 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
3033 case Property::MATRIX:
3035 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( 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<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
3044 case Property::MATRIX3:
3046 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( 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<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
3057 // nothing to do for other types
3062 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3064 Property::Value value;
3066 if( ! GetCachedPropertyValue( index, value ) )
3068 // If property value is not stored in the event-side, then it must be a scene-graph only property
3069 GetCurrentPropertyValue( index, value );
3075 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3077 Property::Value value;
3079 if( ! GetCurrentPropertyValue( index, value ) )
3081 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3082 GetCachedPropertyValue( index, value );
3088 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3090 switch( animationType )
3093 case Animation::BETWEEN:
3097 case Dali::Actor::Property::SIZE:
3099 if( value.Get( mTargetSize ) )
3101 // Notify deriving classes
3102 OnSizeAnimation( animation, mTargetSize );
3107 case Dali::Actor::Property::SIZE_WIDTH:
3109 if( value.Get( mTargetSize.width ) )
3111 // Notify deriving classes
3112 OnSizeAnimation( animation, mTargetSize );
3117 case Dali::Actor::Property::SIZE_HEIGHT:
3119 if( value.Get( mTargetSize.height ) )
3121 // Notify deriving classes
3122 OnSizeAnimation( animation, mTargetSize );
3127 case Dali::Actor::Property::SIZE_DEPTH:
3129 if( value.Get( mTargetSize.depth ) )
3131 // Notify deriving classes
3132 OnSizeAnimation( animation, mTargetSize );
3137 case Dali::Actor::Property::POSITION:
3139 value.Get( mTargetPosition );
3143 case Dali::Actor::Property::POSITION_X:
3145 value.Get( mTargetPosition.x );
3149 case Dali::Actor::Property::POSITION_Y:
3151 value.Get( mTargetPosition.y );
3155 case Dali::Actor::Property::POSITION_Z:
3157 value.Get( mTargetPosition.z );
3161 case Dali::Actor::Property::ORIENTATION:
3163 value.Get( mTargetOrientation );
3167 case Dali::Actor::Property::SCALE:
3169 value.Get( mTargetScale );
3173 case Dali::Actor::Property::SCALE_X:
3175 value.Get( mTargetScale.x );
3179 case Dali::Actor::Property::SCALE_Y:
3181 value.Get( mTargetScale.y );
3185 case Dali::Actor::Property::SCALE_Z:
3187 value.Get( mTargetScale.z );
3191 case Dali::Actor::Property::VISIBLE:
3193 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3197 case Dali::Actor::Property::COLOR:
3199 value.Get( mTargetColor );
3203 case Dali::Actor::Property::COLOR_RED:
3205 value.Get( mTargetColor.r );
3209 case Dali::Actor::Property::COLOR_GREEN:
3211 value.Get( mTargetColor.g );
3215 case Dali::Actor::Property::COLOR_BLUE:
3217 value.Get( mTargetColor.b );
3221 case Dali::Actor::Property::COLOR_ALPHA:
3222 case Dali::DevelActor::Property::OPACITY:
3224 value.Get( mTargetColor.a );
3230 // Not an animatable property. Do nothing.
3241 case Dali::Actor::Property::SIZE:
3243 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3245 // Notify deriving classes
3246 OnSizeAnimation( animation, mTargetSize );
3251 case Dali::Actor::Property::SIZE_WIDTH:
3253 if( AdjustValue< float >( mTargetSize.width, value ) )
3255 // Notify deriving classes
3256 OnSizeAnimation( animation, mTargetSize );
3261 case Dali::Actor::Property::SIZE_HEIGHT:
3263 if( AdjustValue< float >( mTargetSize.height, value ) )
3265 // Notify deriving classes
3266 OnSizeAnimation( animation, mTargetSize );
3271 case Dali::Actor::Property::SIZE_DEPTH:
3273 if( AdjustValue< float >( mTargetSize.depth, value ) )
3275 // Notify deriving classes
3276 OnSizeAnimation( animation, mTargetSize );
3281 case Dali::Actor::Property::POSITION:
3283 AdjustValue< Vector3 >( mTargetPosition, value );
3287 case Dali::Actor::Property::POSITION_X:
3289 AdjustValue< float >( mTargetPosition.x, value );
3293 case Dali::Actor::Property::POSITION_Y:
3295 AdjustValue< float >( mTargetPosition.y, value );
3299 case Dali::Actor::Property::POSITION_Z:
3301 AdjustValue< float >( mTargetPosition.z, value );
3305 case Dali::Actor::Property::ORIENTATION:
3307 Quaternion relativeValue;
3308 if( value.Get( relativeValue ) )
3310 mTargetOrientation *= relativeValue;
3315 case Dali::Actor::Property::SCALE:
3317 AdjustValue< Vector3 >( mTargetScale, value );
3321 case Dali::Actor::Property::SCALE_X:
3323 AdjustValue< float >( mTargetScale.x, value );
3327 case Dali::Actor::Property::SCALE_Y:
3329 AdjustValue< float >( mTargetScale.y, value );
3333 case Dali::Actor::Property::SCALE_Z:
3335 AdjustValue< float >( mTargetScale.z, value );
3339 case Dali::Actor::Property::VISIBLE:
3341 bool relativeValue = false;
3342 if( value.Get( relativeValue ) )
3344 bool visible = mVisible || relativeValue;
3345 SetVisibleInternal( visible, SendMessage::FALSE );
3350 case Dali::Actor::Property::COLOR:
3352 AdjustValue< Vector4 >( mTargetColor, value );
3356 case Dali::Actor::Property::COLOR_RED:
3358 AdjustValue< float >( mTargetColor.r, value );
3362 case Dali::Actor::Property::COLOR_GREEN:
3364 AdjustValue< float >( mTargetColor.g, value );
3368 case Dali::Actor::Property::COLOR_BLUE:
3370 AdjustValue< float >( mTargetColor.b, value );
3374 case Dali::Actor::Property::COLOR_ALPHA:
3375 case Dali::DevelActor::Property::OPACITY:
3377 AdjustValue< float >( mTargetColor.a, value );
3383 // Not an animatable property. Do nothing.
3392 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3397 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3399 // This method should only return an object connected to the scene-graph
3400 return OnStage() ? mNode : NULL;
3403 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3405 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3407 const PropertyBase* property( NULL );
3409 // This method should only return a property of an object connected to the scene-graph
3415 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3417 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3418 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3420 property = animatable->GetSceneGraphProperty();
3422 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3423 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3425 CustomPropertyMetadata* custom = FindCustomProperty( index );
3426 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3428 property = custom->GetSceneGraphProperty();
3430 else if( NULL != mNode )
3434 case Dali::Actor::Property::SIZE:
3435 property = &mNode->mSize;
3438 case Dali::Actor::Property::SIZE_WIDTH:
3439 property = &mNode->mSize;
3442 case Dali::Actor::Property::SIZE_HEIGHT:
3443 property = &mNode->mSize;
3446 case Dali::Actor::Property::SIZE_DEPTH:
3447 property = &mNode->mSize;
3450 case Dali::Actor::Property::POSITION:
3451 property = &mNode->mPosition;
3454 case Dali::Actor::Property::POSITION_X:
3455 property = &mNode->mPosition;
3458 case Dali::Actor::Property::POSITION_Y:
3459 property = &mNode->mPosition;
3462 case Dali::Actor::Property::POSITION_Z:
3463 property = &mNode->mPosition;
3466 case Dali::Actor::Property::ORIENTATION:
3467 property = &mNode->mOrientation;
3470 case Dali::Actor::Property::SCALE:
3471 property = &mNode->mScale;
3474 case Dali::Actor::Property::SCALE_X:
3475 property = &mNode->mScale;
3478 case Dali::Actor::Property::SCALE_Y:
3479 property = &mNode->mScale;
3482 case Dali::Actor::Property::SCALE_Z:
3483 property = &mNode->mScale;
3486 case Dali::Actor::Property::VISIBLE:
3487 property = &mNode->mVisible;
3490 case Dali::Actor::Property::COLOR:
3491 property = &mNode->mColor;
3494 case Dali::Actor::Property::COLOR_RED:
3495 property = &mNode->mColor;
3498 case Dali::Actor::Property::COLOR_GREEN:
3499 property = &mNode->mColor;
3502 case Dali::Actor::Property::COLOR_BLUE:
3503 property = &mNode->mColor;
3506 case Dali::Actor::Property::COLOR_ALPHA:
3507 case Dali::DevelActor::Property::OPACITY:
3508 property = &mNode->mColor;
3519 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3521 const PropertyInputImpl* property( NULL );
3523 // This method should only return a property of an object connected to the scene-graph
3529 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3531 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3532 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3534 property = animatable->GetSceneGraphProperty();
3536 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3537 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3539 CustomPropertyMetadata* custom = FindCustomProperty( index );
3540 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3541 property = custom->GetSceneGraphProperty();
3543 else if( NULL != mNode )
3547 case Dali::Actor::Property::PARENT_ORIGIN:
3548 property = &mNode->mParentOrigin;
3551 case Dali::Actor::Property::PARENT_ORIGIN_X:
3552 property = &mNode->mParentOrigin;
3555 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3556 property = &mNode->mParentOrigin;
3559 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3560 property = &mNode->mParentOrigin;
3563 case Dali::Actor::Property::ANCHOR_POINT:
3564 property = &mNode->mAnchorPoint;
3567 case Dali::Actor::Property::ANCHOR_POINT_X:
3568 property = &mNode->mAnchorPoint;
3571 case Dali::Actor::Property::ANCHOR_POINT_Y:
3572 property = &mNode->mAnchorPoint;
3575 case Dali::Actor::Property::ANCHOR_POINT_Z:
3576 property = &mNode->mAnchorPoint;
3579 case Dali::Actor::Property::SIZE:
3580 property = &mNode->mSize;
3583 case Dali::Actor::Property::SIZE_WIDTH:
3584 property = &mNode->mSize;
3587 case Dali::Actor::Property::SIZE_HEIGHT:
3588 property = &mNode->mSize;
3591 case Dali::Actor::Property::SIZE_DEPTH:
3592 property = &mNode->mSize;
3595 case Dali::Actor::Property::POSITION:
3596 property = &mNode->mPosition;
3599 case Dali::Actor::Property::POSITION_X:
3600 property = &mNode->mPosition;
3603 case Dali::Actor::Property::POSITION_Y:
3604 property = &mNode->mPosition;
3607 case Dali::Actor::Property::POSITION_Z:
3608 property = &mNode->mPosition;
3611 case Dali::Actor::Property::WORLD_POSITION:
3612 property = &mNode->mWorldPosition;
3615 case Dali::Actor::Property::WORLD_POSITION_X:
3616 property = &mNode->mWorldPosition;
3619 case Dali::Actor::Property::WORLD_POSITION_Y:
3620 property = &mNode->mWorldPosition;
3623 case Dali::Actor::Property::WORLD_POSITION_Z:
3624 property = &mNode->mWorldPosition;
3627 case Dali::Actor::Property::ORIENTATION:
3628 property = &mNode->mOrientation;
3631 case Dali::Actor::Property::WORLD_ORIENTATION:
3632 property = &mNode->mWorldOrientation;
3635 case Dali::Actor::Property::SCALE:
3636 property = &mNode->mScale;
3639 case Dali::Actor::Property::SCALE_X:
3640 property = &mNode->mScale;
3643 case Dali::Actor::Property::SCALE_Y:
3644 property = &mNode->mScale;
3647 case Dali::Actor::Property::SCALE_Z:
3648 property = &mNode->mScale;
3651 case Dali::Actor::Property::WORLD_SCALE:
3652 property = &mNode->mWorldScale;
3655 case Dali::Actor::Property::VISIBLE:
3656 property = &mNode->mVisible;
3659 case Dali::Actor::Property::COLOR:
3660 property = &mNode->mColor;
3663 case Dali::Actor::Property::COLOR_RED:
3664 property = &mNode->mColor;
3667 case Dali::Actor::Property::COLOR_GREEN:
3668 property = &mNode->mColor;
3671 case Dali::Actor::Property::COLOR_BLUE:
3672 property = &mNode->mColor;
3675 case Dali::Actor::Property::COLOR_ALPHA:
3676 case Dali::DevelActor::Property::OPACITY:
3678 property = &mNode->mColor;
3682 case Dali::Actor::Property::WORLD_COLOR:
3683 property = &mNode->mWorldColor;
3686 case Dali::Actor::Property::WORLD_MATRIX:
3687 property = &mNode->mWorldMatrix;
3698 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3700 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3702 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3704 // check whether the animatable property is registered already, if not then register one.
3705 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3706 if( animatableProperty )
3708 componentIndex = animatableProperty->componentIndex;
3715 case Dali::Actor::Property::PARENT_ORIGIN_X:
3716 case Dali::Actor::Property::ANCHOR_POINT_X:
3717 case Dali::Actor::Property::SIZE_WIDTH:
3718 case Dali::Actor::Property::POSITION_X:
3719 case Dali::Actor::Property::WORLD_POSITION_X:
3720 case Dali::Actor::Property::SCALE_X:
3721 case Dali::Actor::Property::COLOR_RED:
3727 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3728 case Dali::Actor::Property::ANCHOR_POINT_Y:
3729 case Dali::Actor::Property::SIZE_HEIGHT:
3730 case Dali::Actor::Property::POSITION_Y:
3731 case Dali::Actor::Property::WORLD_POSITION_Y:
3732 case Dali::Actor::Property::SCALE_Y:
3733 case Dali::Actor::Property::COLOR_GREEN:
3739 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3740 case Dali::Actor::Property::ANCHOR_POINT_Z:
3741 case Dali::Actor::Property::SIZE_DEPTH:
3742 case Dali::Actor::Property::POSITION_Z:
3743 case Dali::Actor::Property::WORLD_POSITION_Z:
3744 case Dali::Actor::Property::SCALE_Z:
3745 case Dali::Actor::Property::COLOR_BLUE:
3751 case Dali::Actor::Property::COLOR_ALPHA:
3752 case Dali::DevelActor::Property::OPACITY:
3766 return componentIndex;
3769 void Actor::SetParent( Actor* parent )
3773 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3777 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3780 // Instruct each actor to create a corresponding node in the scene graph
3781 ConnectToStage( parent->GetHierarchyDepth() );
3784 // Resolve the name and index for the child properties if any
3785 ResolveChildProperties();
3787 else // parent being set to NULL
3789 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3793 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3796 DALI_ASSERT_ALWAYS( mNode != NULL );
3800 // Disconnect the Node & its children from the scene-graph.
3801 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3804 // Instruct each actor to discard pointers to the scene-graph
3805 DisconnectFromStage();
3810 SceneGraph::Node* Actor::CreateNode() const
3815 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3818 Actor* actor = dynamic_cast< Actor* >( object );
3822 if( 0 == actionName.compare( ACTION_SHOW ) )
3824 actor->SetVisible( true );
3827 else if( 0 == actionName.compare( ACTION_HIDE ) )
3829 actor->SetVisible( false );
3837 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3839 bool valueSet = true;
3843 case Dali::Actor::Property::PARENT_ORIGIN:
3845 value = GetCurrentParentOrigin();
3849 case Dali::Actor::Property::PARENT_ORIGIN_X:
3851 value = GetCurrentParentOrigin().x;
3855 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3857 value = GetCurrentParentOrigin().y;
3861 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3863 value = GetCurrentParentOrigin().z;
3867 case Dali::Actor::Property::ANCHOR_POINT:
3869 value = GetCurrentAnchorPoint();
3873 case Dali::Actor::Property::ANCHOR_POINT_X:
3875 value = GetCurrentAnchorPoint().x;
3879 case Dali::Actor::Property::ANCHOR_POINT_Y:
3881 value = GetCurrentAnchorPoint().y;
3885 case Dali::Actor::Property::ANCHOR_POINT_Z:
3887 value = GetCurrentAnchorPoint().z;
3891 case Dali::Actor::Property::SIZE:
3893 value = GetTargetSize();
3897 case Dali::Actor::Property::SIZE_WIDTH:
3899 value = GetTargetSize().width;
3903 case Dali::Actor::Property::SIZE_HEIGHT:
3905 value = GetTargetSize().height;
3909 case Dali::Actor::Property::SIZE_DEPTH:
3911 value = GetTargetSize().depth;
3915 case Dali::Actor::Property::POSITION:
3917 value = GetTargetPosition();
3921 case Dali::Actor::Property::POSITION_X:
3923 value = GetTargetPosition().x;
3927 case Dali::Actor::Property::POSITION_Y:
3929 value = GetTargetPosition().y;
3933 case Dali::Actor::Property::POSITION_Z:
3935 value = GetTargetPosition().z;
3939 case Dali::Actor::Property::ORIENTATION:
3941 value = mTargetOrientation;
3945 case Dali::Actor::Property::SCALE:
3947 value = mTargetScale;
3951 case Dali::Actor::Property::SCALE_X:
3953 value = mTargetScale.x;
3957 case Dali::Actor::Property::SCALE_Y:
3959 value = mTargetScale.y;
3963 case Dali::Actor::Property::SCALE_Z:
3965 value = mTargetScale.z;
3969 case Dali::Actor::Property::VISIBLE:
3975 case Dali::Actor::Property::COLOR:
3977 value = mTargetColor;
3981 case Dali::Actor::Property::COLOR_RED:
3983 value = mTargetColor.r;
3987 case Dali::Actor::Property::COLOR_GREEN:
3989 value = mTargetColor.g;
3993 case Dali::Actor::Property::COLOR_BLUE:
3995 value = mTargetColor.b;
3999 case Dali::Actor::Property::COLOR_ALPHA:
4000 case Dali::DevelActor::Property::OPACITY:
4002 value = mTargetColor.a;
4006 case Dali::Actor::Property::NAME:
4012 case Dali::Actor::Property::SENSITIVE:
4014 value = IsSensitive();
4018 case Dali::Actor::Property::LEAVE_REQUIRED:
4020 value = GetLeaveRequired();
4024 case Dali::Actor::Property::INHERIT_POSITION:
4026 value = IsPositionInherited();
4030 case Dali::Actor::Property::INHERIT_ORIENTATION:
4032 value = IsOrientationInherited();
4036 case Dali::Actor::Property::INHERIT_SCALE:
4038 value = IsScaleInherited();
4042 case Dali::Actor::Property::COLOR_MODE:
4044 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4048 case Dali::Actor::Property::POSITION_INHERITANCE:
4050 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4054 case Dali::Actor::Property::DRAW_MODE:
4056 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4060 case Dali::Actor::Property::SIZE_MODE_FACTOR:
4062 value = GetSizeModeFactor();
4066 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4068 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4072 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4074 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4078 case Dali::Actor::Property::SIZE_SCALE_POLICY:
4080 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4084 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4086 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4090 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4092 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4096 case Dali::Actor::Property::PADDING:
4098 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4099 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4100 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4104 case Dali::Actor::Property::MINIMUM_SIZE:
4106 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4110 case Dali::Actor::Property::MAXIMUM_SIZE:
4112 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4116 case Dali::Actor::Property::CLIPPING_MODE:
4118 value = mClippingMode;
4122 case Dali::DevelActor::Property::SIBLING_ORDER:
4124 value = static_cast<int>( GetSiblingOrder() );
4128 case Dali::DevelActor::Property::SCREEN_POSITION:
4130 value = GetCurrentScreenPosition();
4134 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4136 value = mPositionUsesAnchorPoint;
4140 case Dali::DevelActor::Property::LAYOUT_DIRECTION:
4142 value = Scripting::GetLinearEnumerationName< DevelActor::LayoutDirection::Type >( mLayoutDirection, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT );
4146 case Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE:
4148 value = mLayoutDirectionInheritance;
4154 // Must be a scene-graph only property
4163 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
4165 bool valueSet = true;
4169 case Dali::Actor::Property::SIZE:
4171 value = GetCurrentSize();
4175 case Dali::Actor::Property::SIZE_WIDTH:
4177 value = GetCurrentSize().width;
4181 case Dali::Actor::Property::SIZE_HEIGHT:
4183 value = GetCurrentSize().height;
4187 case Dali::Actor::Property::SIZE_DEPTH:
4189 value = GetCurrentSize().depth;
4193 case Dali::Actor::Property::POSITION:
4195 value = GetCurrentPosition();
4199 case Dali::Actor::Property::POSITION_X:
4201 value = GetCurrentPosition().x;
4205 case Dali::Actor::Property::POSITION_Y:
4207 value = GetCurrentPosition().y;
4211 case Dali::Actor::Property::POSITION_Z:
4213 value = GetCurrentPosition().z;
4217 case Dali::Actor::Property::WORLD_POSITION:
4219 value = GetCurrentWorldPosition();
4223 case Dali::Actor::Property::WORLD_POSITION_X:
4225 value = GetCurrentWorldPosition().x;
4229 case Dali::Actor::Property::WORLD_POSITION_Y:
4231 value = GetCurrentWorldPosition().y;
4235 case Dali::Actor::Property::WORLD_POSITION_Z:
4237 value = GetCurrentWorldPosition().z;
4241 case Dali::Actor::Property::ORIENTATION:
4243 value = GetCurrentOrientation();
4247 case Dali::Actor::Property::WORLD_ORIENTATION:
4249 value = GetCurrentWorldOrientation();
4253 case Dali::Actor::Property::SCALE:
4255 value = GetCurrentScale();
4259 case Dali::Actor::Property::SCALE_X:
4261 value = GetCurrentScale().x;
4265 case Dali::Actor::Property::SCALE_Y:
4267 value = GetCurrentScale().y;
4271 case Dali::Actor::Property::SCALE_Z:
4273 value = GetCurrentScale().z;
4277 case Dali::Actor::Property::WORLD_SCALE:
4279 value = GetCurrentWorldScale();
4283 case Dali::Actor::Property::COLOR:
4285 value = GetCurrentColor();
4289 case Dali::Actor::Property::COLOR_RED:
4291 value = GetCurrentColor().r;
4295 case Dali::Actor::Property::COLOR_GREEN:
4297 value = GetCurrentColor().g;
4301 case Dali::Actor::Property::COLOR_BLUE:
4303 value = GetCurrentColor().b;
4307 case Dali::Actor::Property::COLOR_ALPHA:
4308 case Dali::DevelActor::Property::OPACITY:
4310 value = GetCurrentColor().a;
4314 case Dali::Actor::Property::WORLD_COLOR:
4316 value = GetCurrentWorldColor();
4320 case Dali::Actor::Property::WORLD_MATRIX:
4322 value = GetCurrentWorldMatrix();
4326 case Dali::Actor::Property::VISIBLE:
4328 value = IsVisible();
4334 // Must be an event-side only property
4343 void Actor::EnsureRelayoutData()
4345 // Assign relayout data.
4346 if( !mRelayoutData )
4348 mRelayoutData = new RelayoutData();
4352 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4354 // Check if actor is dependent on parent
4355 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4357 if( ( dimension & ( 1 << i ) ) )
4359 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4360 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4370 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4372 // Check if actor is dependent on children
4373 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4375 if( ( dimension & ( 1 << i ) ) )
4377 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4378 switch( resizePolicy )
4380 case ResizePolicy::FIT_TO_CHILDREN:
4381 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4397 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4399 return Actor::RelayoutDependentOnChildren( dimension );
4402 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4404 // Check each possible dimension and see if it is dependent on the input one
4405 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4407 if( dimension & ( 1 << i ) )
4409 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4416 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4418 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4420 if( dimension & ( 1 << i ) )
4422 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4427 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4429 // If more than one dimension is requested, just return the first one found
4430 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4432 if( ( dimension & ( 1 << i ) ) )
4434 return mRelayoutData->negotiatedDimensions[ i ];
4438 return 0.0f; // Default
4441 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4443 EnsureRelayoutData();
4445 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4447 if( dimension & ( 1 << i ) )
4449 mRelayoutData->dimensionPadding[ i ] = padding;
4454 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4456 if ( mRelayoutData )
4458 // If more than one dimension is requested, just return the first one found
4459 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4461 if( ( dimension & ( 1 << i ) ) )
4463 return mRelayoutData->dimensionPadding[ i ];
4468 return GetDefaultDimensionPadding();
4471 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4473 EnsureRelayoutData();
4475 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4477 if( dimension & ( 1 << i ) )
4479 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4484 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4486 if ( mRelayoutData )
4488 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4490 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4500 float Actor::GetHeightForWidthBase( float width )
4502 float height = 0.0f;
4504 const Vector3 naturalSize = GetNaturalSize();
4505 if( naturalSize.width > 0.0f )
4507 height = naturalSize.height * width / naturalSize.width;
4509 else // we treat 0 as 1:1 aspect ratio
4517 float Actor::GetWidthForHeightBase( float height )
4521 const Vector3 naturalSize = GetNaturalSize();
4522 if( naturalSize.height > 0.0f )
4524 width = naturalSize.width * height / naturalSize.height;
4526 else // we treat 0 as 1:1 aspect ratio
4534 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4536 // Fill to parent, taking size mode factor into account
4537 switch( child.GetResizePolicy( dimension ) )
4539 case ResizePolicy::FILL_TO_PARENT:
4541 return GetLatestSize( dimension );
4544 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4546 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4549 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4551 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4556 return GetLatestSize( dimension );
4561 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4563 // Can be overridden in derived class
4564 return CalculateChildSizeBase( child, dimension );
4567 float Actor::GetHeightForWidth( float width )
4569 // Can be overridden in derived class
4570 return GetHeightForWidthBase( width );
4573 float Actor::GetWidthForHeight( float height )
4575 // Can be overridden in derived class
4576 return GetWidthForHeightBase( height );
4579 float Actor::GetLatestSize( Dimension::Type dimension ) const
4581 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4584 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4586 Vector2 padding = GetPadding( dimension );
4588 return GetLatestSize( dimension ) + padding.x + padding.y;
4591 float Actor::NegotiateFromParent( Dimension::Type dimension )
4593 Actor* parent = GetParent();
4596 Vector2 padding( GetPadding( dimension ) );
4597 Vector2 parentPadding( parent->GetPadding( dimension ) );
4598 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4604 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4606 float maxDimensionPoint = 0.0f;
4608 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4610 ActorPtr child = GetChildAt( i );
4612 if( !child->RelayoutDependentOnParent( dimension ) )
4614 // Calculate the min and max points that the children range across
4615 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4616 float dimensionSize = child->GetRelayoutSize( dimension );
4617 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4621 return maxDimensionPoint;
4624 float Actor::GetSize( Dimension::Type dimension ) const
4626 return GetDimensionValue( mTargetSize, dimension );
4629 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4631 return GetDimensionValue( GetNaturalSize(), dimension );
4634 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4636 switch( GetResizePolicy( dimension ) )
4638 case ResizePolicy::USE_NATURAL_SIZE:
4640 return GetNaturalSize( dimension );
4643 case ResizePolicy::FIXED:
4645 return GetDimensionValue( GetPreferredSize(), dimension );
4648 case ResizePolicy::USE_ASSIGNED_SIZE:
4650 return GetDimensionValue( maximumSize, dimension );
4653 case ResizePolicy::FILL_TO_PARENT:
4654 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4655 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4657 return NegotiateFromParent( dimension );
4660 case ResizePolicy::FIT_TO_CHILDREN:
4662 return NegotiateFromChildren( dimension );
4665 case ResizePolicy::DIMENSION_DEPENDENCY:
4667 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4670 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4672 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4675 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4677 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4689 return 0.0f; // Default
4692 float Actor::ClampDimension( float size, Dimension::Type dimension )
4694 const float minSize = GetMinimumSize( dimension );
4695 const float maxSize = GetMaximumSize( dimension );
4697 return std::max( minSize, std::min( size, maxSize ) );
4700 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4702 // Check if it needs to be negotiated
4703 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4705 // Check that we havn't gotten into an infinite loop
4706 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4707 bool recursionFound = false;
4708 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4710 if( *it == searchActor )
4712 recursionFound = true;
4717 if( !recursionFound )
4719 // Record the path that we have taken
4720 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4722 // Dimension dependency check
4723 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4725 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4727 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4729 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4733 // Parent dependency check
4734 Actor* parent = GetParent();
4735 if( parent && RelayoutDependentOnParent( dimension ) )
4737 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4740 // Children dependency check
4741 if( RelayoutDependentOnChildren( dimension ) )
4743 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4745 ActorPtr child = GetChildAt( i );
4747 // Only relayout child first if it is not dependent on this actor
4748 if( !child->RelayoutDependentOnParent( dimension ) )
4750 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4755 // For deriving classes
4756 OnCalculateRelayoutSize( dimension );
4758 // All dependencies checked, calculate the size and set negotiated flag
4759 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4761 SetNegotiatedDimension( newSize, dimension );
4762 SetLayoutNegotiated( true, dimension );
4764 // For deriving classes
4765 OnLayoutNegotiated( newSize, dimension );
4767 // This actor has been successfully processed, pop it off the recursion stack
4768 recursionStack.pop_back();
4772 // TODO: Break infinite loop
4773 SetLayoutNegotiated( true, dimension );
4778 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4780 // Negotiate all dimensions that require it
4781 ActorDimensionStack recursionStack;
4783 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4785 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4788 NegotiateDimension( dimension, allocatedSize, recursionStack );
4792 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4794 switch( mRelayoutData->sizeSetPolicy )
4796 case SizeScalePolicy::USE_SIZE_SET:
4801 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4803 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4804 const Vector3 naturalSize = GetNaturalSize();
4805 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4807 const float sizeRatio = size.width / size.height;
4808 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4810 if( naturalSizeRatio < sizeRatio )
4812 return Vector2( naturalSizeRatio * size.height, size.height );
4814 else if( naturalSizeRatio > sizeRatio )
4816 return Vector2( size.width, size.width / naturalSizeRatio );
4827 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4829 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4830 const Vector3 naturalSize = GetNaturalSize();
4831 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4833 const float sizeRatio = size.width / size.height;
4834 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4836 if( naturalSizeRatio < sizeRatio )
4838 return Vector2( size.width, size.width / naturalSizeRatio );
4840 else if( naturalSizeRatio > sizeRatio )
4842 return Vector2( naturalSizeRatio * size.height, size.height );
4861 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4863 // Do the set actor size
4864 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4866 // Adjust for size set policy
4867 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4869 // Lock the flag to stop recursive relayouts on set size
4870 mRelayoutData->insideRelayout = true;
4871 SetSize( negotiatedSize );
4872 mRelayoutData->insideRelayout = false;
4874 // Clear flags for all dimensions
4875 SetLayoutDirty( false );
4877 // Give deriving classes a chance to respond
4878 OnRelayout( negotiatedSize, container );
4880 if( !mOnRelayoutSignal.Empty() )
4882 Dali::Actor handle( this );
4883 mOnRelayoutSignal.Emit( handle );
4887 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4889 // Force a size negotiation for actors that has assigned size during relayout
4890 // This is required as otherwise the flags that force a relayout will not
4891 // necessarilly be set. This will occur if the actor has already been laid out.
4892 // The dirty flags are then cleared. Then if the actor is added back into the
4893 // relayout container afterwards, the dirty flags would still be clear...
4894 // causing a relayout to be skipped. Here we force any actors added to the
4895 // container to be relayed out.
4896 DALI_LOG_TIMER_START( NegSizeTimer1 );
4898 if( GetUseAssignedSize(Dimension::WIDTH ) )
4900 SetLayoutNegotiated( false, Dimension::WIDTH );
4902 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4904 SetLayoutNegotiated( false, Dimension::HEIGHT );
4907 // Do the negotiation
4908 NegotiateDimensions( allocatedSize );
4910 // Set the actor size
4911 SetNegotiatedSize( container );
4913 // Negotiate down to children
4914 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4916 ActorPtr child = GetChildAt( i );
4918 // Forces children that have already been laid out to be relayed out
4919 // if they have assigned size during relayout.
4920 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4922 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4923 child->SetLayoutDirty(true, Dimension::WIDTH);
4926 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4928 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4929 child->SetLayoutDirty(true, Dimension::HEIGHT);
4932 // Only relayout if required
4933 if( child->RelayoutRequired() )
4935 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4938 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4941 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4945 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4947 if( dimension & ( 1 << i ) )
4949 mRelayoutData->useAssignedSize[ i ] = use;
4955 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4957 if ( mRelayoutData )
4959 // If more than one dimension is requested, just return the first one found
4960 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4962 if( dimension & ( 1 << i ) )
4964 return mRelayoutData->useAssignedSize[ i ];
4972 void Actor::RelayoutRequest( Dimension::Type dimension )
4974 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4975 if( relayoutController )
4977 Dali::Actor self( this );
4978 relayoutController->RequestRelayout( self, dimension );
4982 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4986 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4990 void Actor::SetPreferredSize( const Vector2& size )
4992 EnsureRelayoutData();
4994 if( size.width > 0.0f )
4996 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4999 if( size.height > 0.0f )
5001 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
5004 mRelayoutData->preferredSize = size;
5009 Vector2 Actor::GetPreferredSize() const
5011 if ( mRelayoutData )
5013 return Vector2( mRelayoutData->preferredSize );
5016 return GetDefaultPreferredSize();
5019 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
5021 EnsureRelayoutData();
5023 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5025 if( dimension & ( 1 << i ) )
5027 mRelayoutData->minimumSize[ i ] = size;
5034 float Actor::GetMinimumSize( Dimension::Type dimension ) const
5036 if ( mRelayoutData )
5038 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5040 if( dimension & ( 1 << i ) )
5042 return mRelayoutData->minimumSize[ i ];
5047 return 0.0f; // Default
5050 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5052 EnsureRelayoutData();
5054 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5056 if( dimension & ( 1 << i ) )
5058 mRelayoutData->maximumSize[ i ] = size;
5065 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5067 if ( mRelayoutData )
5069 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5071 if( dimension & ( 1 << i ) )
5073 return mRelayoutData->maximumSize[ i ];
5078 return FLT_MAX; // Default
5081 Object* Actor::GetParentObject() const
5086 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5088 if( mVisible != visible )
5090 if( sendMessage == SendMessage::TRUE && NULL != mNode )
5092 // mNode is being used in a separate thread; queue a message to set the value & base value
5093 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5098 // Emit the signal on this actor and all its children
5099 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5103 void Actor::SetSiblingOrder( unsigned int order )
5107 ActorContainer& siblings = *(mParent->mChildren);
5108 unsigned int currentOrder = GetSiblingOrder();
5110 if( order != currentOrder )
5116 else if( order < siblings.size() -1 )
5118 if( order > currentOrder )
5120 RaiseAbove( *siblings[order] );
5124 LowerBelow( *siblings[order] );
5135 unsigned int Actor::GetSiblingOrder() const
5137 unsigned int order = 0;
5141 ActorContainer& siblings = *(mParent->mChildren);
5142 for( size_t i=0; i<siblings.size(); ++i )
5144 if( siblings[i] == this )
5155 void Actor::RequestRebuildDepthTree()
5159 StagePtr stage = Stage::GetCurrent();
5162 stage->RequestRebuildDepthTree();
5171 ActorContainer& siblings = *(mParent->mChildren);
5172 if( siblings.back() != this ) // If not already at end
5174 for( size_t i=0; i<siblings.size(); ++i )
5176 if( siblings[i] == this )
5179 ActorPtr next = siblings[i+1];
5180 siblings[i+1] = this;
5186 RequestRebuildDepthTree();
5190 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5198 ActorContainer& siblings = *(mParent->mChildren);
5199 if( siblings.front() != this ) // If not already at beginning
5201 for( size_t i=0; i<siblings.size(); ++i )
5203 if( siblings[i] == this )
5205 // Swap with previous
5206 ActorPtr previous = siblings[i-1];
5207 siblings[i-1] = this;
5208 siblings[i] = previous;
5213 RequestRebuildDepthTree();
5217 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5221 void Actor::RaiseToTop()
5225 ActorContainer& siblings = *(mParent->mChildren);
5226 if( siblings.back() != this ) // If not already at end
5228 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5229 if( iter != siblings.end() )
5231 siblings.erase(iter);
5232 siblings.push_back(ActorPtr(this));
5235 RequestRebuildDepthTree();
5239 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5243 void Actor::LowerToBottom()
5247 ActorContainer& siblings = *(mParent->mChildren);
5248 if( siblings.front() != this ) // If not already at bottom,
5250 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5252 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5253 if( iter != siblings.end() )
5255 siblings.erase(iter);
5256 siblings.insert(siblings.begin(), thisPtr);
5259 RequestRebuildDepthTree();
5263 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5267 void Actor::RaiseAbove( Internal::Actor& target )
5271 ActorContainer& siblings = *(mParent->mChildren);
5272 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5274 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5276 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5277 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5278 if( thisIter < targetIter )
5280 siblings.erase(thisIter);
5281 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5282 // invalidate thisIter)
5283 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5285 siblings.insert(targetIter, thisPtr);
5287 RequestRebuildDepthTree();
5292 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5296 void Actor::LowerBelow( Internal::Actor& target )
5300 ActorContainer& siblings = *(mParent->mChildren);
5301 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5303 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5305 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5306 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5308 if( thisIter > targetIter )
5310 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5311 siblings.insert(targetIter, thisPtr);
5313 RequestRebuildDepthTree();
5318 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5322 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::DevelActor::LayoutDirection::Type direction )
5324 if( actor && actor->mLayoutDirectionInheritance )
5326 if( actor->mLayoutDirection != direction)
5328 actor->mLayoutDirection = direction;
5329 actor->RelayoutRequest();
5332 if( actor->GetChildCount() > 0 )
5334 ActorContainer& children = actor->GetChildrenInternal();
5335 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5337 InheritLayoutDirectionRecursively( *iter, direction );
5344 } // namespace Internal