2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/events/touch-data.h>
31 #include <dali/public-api/math/vector2.h>
32 #include <dali/public-api/math/vector3.h>
33 #include <dali/public-api/math/radian.h>
34 #include <dali/public-api/object/type-registry.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <dali/devel-api/scripting/scripting.h>
37 #include <dali/internal/common/internal-constants.h>
38 #include <dali/internal/event/common/event-thread-services.h>
39 #include <dali/internal/event/render-tasks/render-task-impl.h>
40 #include <dali/internal/event/actors/camera-actor-impl.h>
41 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/event/common/property-helper.h>
43 #include <dali/internal/event/common/stage-impl.h>
44 #include <dali/internal/event/common/type-info-impl.h>
45 #include <dali/internal/event/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/common/animatable-property.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/nodes/node-declarations.h>
51 #include <dali/internal/update/animation/scene-graph-constraint.h>
52 #include <dali/internal/event/events/actor-gesture-data.h>
53 #include <dali/internal/common/message.h>
54 #include <dali/integration-api/debug.h>
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::PropertyBase;
60 #if defined(DEBUG_ENABLED)
61 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
62 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
71 unsigned int Actor::mActorCounter = 0;
75 /// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet.
76 inline const Vector3& GetDefaultSizeModeFactor()
81 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
82 inline const Vector2& GetDefaultPreferredSize()
87 /// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet.
88 inline const Vector2& GetDefaultDimensionPadding()
93 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
95 } // unnamed namespace
98 * Struct to collect relayout variables
100 struct Actor::RelayoutData
103 : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false )
105 // Set size negotiation defaults
106 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
108 resizePolicies[ i ] = ResizePolicy::DEFAULT;
109 useAssignedSize[ i ] = false;
110 negotiatedDimensions[ i ] = 0.0f;
111 dimensionNegotiated[ i ] = false;
112 dimensionDirty[ i ] = false;
113 dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS;
114 dimensionPadding[ i ] = GetDefaultDimensionPadding();
115 minimumSize[ i ] = 0.0f;
116 maximumSize[ i ] = FLT_MAX;
120 ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
121 bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
123 Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
125 Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
127 float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor
129 float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be
130 float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be
132 bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated
133 bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not
135 Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
137 Vector2 preferredSize; ///< The preferred size of the actor
139 SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum
141 bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
142 bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set
145 namespace // unnamed namespace
151 * We want to discourage the use of property strings (minimize string comparisons),
152 * particularly for the default properties.
153 * Name Type writable animatable constraint-input enum for index-checking
155 DALI_PROPERTY_TABLE_BEGIN
156 DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
157 DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
158 DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
159 DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
160 DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
161 DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
162 DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
163 DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
164 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
165 DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
166 DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
167 DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
168 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
169 DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
170 DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
171 DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
172 DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
173 DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
174 DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
175 DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
176 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
177 DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
178 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
179 DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
180 DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
181 DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
182 DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
183 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
184 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
185 DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
186 DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
187 DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
188 DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
189 DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
190 DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
191 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
192 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
193 DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
194 DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
195 DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
196 DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
197 DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
198 DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
199 DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
200 DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
201 DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
202 DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
203 DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
204 DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
205 DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
206 DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
207 DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
208 DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
209 DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
210 DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
211 DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
212 DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
213 DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY )
214 DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
215 DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
216 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
220 const char* const SIGNAL_TOUCHED = "touched";
221 const char* const SIGNAL_HOVERED = "hovered";
222 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
223 const char* const SIGNAL_ON_STAGE = "onStage";
224 const char* const SIGNAL_OFF_STAGE = "offStage";
225 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
226 const char* const SIGNAL_TOUCH = "touch";
227 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
228 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
229 const char* const SIGNAL_CHILD_ADDED = "childAdded";
230 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
234 const char* const ACTION_SHOW = "show";
235 const char* const ACTION_HIDE = "hide";
237 BaseHandle CreateActor()
239 return Dali::Actor::New();
242 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
244 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
245 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
247 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
248 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
249 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
250 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
251 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
256 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
257 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
262 const Vector3& value;
265 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
266 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
267 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
268 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
269 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
270 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
275 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
277 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
278 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
279 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
280 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
281 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
282 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
284 DALI_ENUM_TO_STRING_TABLE_BEGIN( POSITION_INHERITANCE_MODE )
285 DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION )
286 DALI_ENUM_TO_STRING( USE_PARENT_POSITION )
287 DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION )
288 DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION )
289 DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_MODE )
291 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, STENCIL )
295 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
297 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
299 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
300 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
301 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
305 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
306 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
308 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
310 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
311 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
312 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
314 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
315 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
316 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
317 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
319 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
320 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
321 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
322 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
324 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
326 for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
328 size_t sizeIgnored = 0;
329 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
331 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
338 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
340 // Values are the same so just use the same table as anchor-point
341 return GetAnchorPointConstant( value, parentOrigin );
345 * @brief Extract a given dimension from a Vector2
347 * @param[in] values The values to extract from
348 * @param[in] dimension The dimension to extract
349 * @return Return the value for the dimension
351 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
355 case Dimension::WIDTH:
359 case Dimension::HEIGHT:
361 return values.height;
372 * @brief Extract a given dimension from a Vector3
374 * @param[in] values The values to extract from
375 * @param[in] dimension The dimension to extract
376 * @return Return the value for the dimension
378 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
380 return GetDimensionValue( values.GetVectorXY(), dimension );
384 * @brief Recursively emits the visibility-changed-signal on the actor tree.
385 * @param[in] actor The actor to emit the signal on
386 * @param[in] visible The new visibility of the actor
387 * @param[in] type Whether the actor's visible property has changed or a parent's
389 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
393 actor->EmitVisibilityChangedSignal( visible, type );
395 if( actor->GetChildCount() > 0 )
397 ActorContainer& children = actor->GetChildrenInternal();
398 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
400 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
406 } // unnamed namespace
408 ActorPtr Actor::New()
410 ActorPtr actor( new Actor( BASIC ) );
412 // Second-phase construction
418 const std::string& Actor::GetName() const
423 void Actor::SetName( const std::string& name )
429 // ATTENTION: string for debug purposes is not thread safe.
430 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
434 unsigned int Actor::GetId() const
439 bool Actor::OnStage() const
444 Dali::Layer Actor::GetLayer()
448 // Short-circuit for Layer derived actors
451 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
454 // Find the immediate Layer parent
455 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
457 if( parent->IsLayer() )
459 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
466 void Actor::Add( Actor& child )
468 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
469 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
473 mChildren = new ActorContainer;
476 Actor* const oldParent( child.mParent );
478 // child might already be ours
479 if( this != oldParent )
481 // if we already have parent, unparent us first
484 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
486 // Old parent may need to readjust to missing child
487 if( oldParent->RelayoutDependentOnChildren() )
489 oldParent->RelayoutRequest();
493 // Guard against Add() during previous OnChildRemove callback
496 // Do this first, since user callbacks from within SetParent() may need to remove child
497 mChildren->push_back( ActorPtr( &child ) );
499 // SetParent asserts that child can be added
500 child.SetParent( this );
502 // Notification for derived classes
504 EmitChildAddedSignal( child );
506 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
508 // Only put in a relayout request if there is a suitable dependency
509 if( RelayoutDependentOnChildren() )
517 void Actor::Remove( Actor& child )
519 if( (this == &child) || (!mChildren) )
521 // no children or removing itself
527 // Find the child in mChildren, and unparent it
528 ActorIter end = mChildren->end();
529 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
531 ActorPtr actor = (*iter);
533 if( actor.Get() == &child )
535 // Keep handle for OnChildRemove notification
538 // Do this first, since user callbacks from within SetParent() may need to add the child
539 mChildren->erase( iter );
541 DALI_ASSERT_DEBUG( actor->GetParent() == this );
542 actor->SetParent( NULL );
550 // Only put in a relayout request if there is a suitable dependency
551 if( RelayoutDependentOnChildren() )
557 // Notification for derived classes
558 OnChildRemove( child );
559 EmitChildRemovedSignal( child );
562 void Actor::Unparent()
566 // Remove this actor from the parent. The remove will put a relayout request in for
567 // the parent if required
568 mParent->Remove( *this );
569 // mParent is now NULL!
573 unsigned int Actor::GetChildCount() const
575 return ( NULL != mChildren ) ? mChildren->size() : 0;
578 ActorPtr Actor::GetChildAt( unsigned int index ) const
580 DALI_ASSERT_ALWAYS( index < GetChildCount() );
582 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
585 ActorPtr Actor::FindChildByName( const std::string& actorName )
588 if( actorName == mName )
594 ActorIter end = mChildren->end();
595 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
597 child = (*iter)->FindChildByName( actorName );
608 ActorPtr Actor::FindChildById( const unsigned int id )
617 ActorIter end = mChildren->end();
618 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
620 child = (*iter)->FindChildById( id );
631 void Actor::SetParentOrigin( const Vector3& origin )
635 // mNode is being used in a separate thread; queue a message to set the value & base value
636 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
639 // Cache for event-thread access
642 // not allocated, check if different from default
643 if( ParentOrigin::DEFAULT != origin )
645 mParentOrigin = new Vector3( origin );
650 // check if different from current costs more than just set
651 *mParentOrigin = origin;
655 void Actor::SetParentOriginX( float x )
657 const Vector3& current = GetCurrentParentOrigin();
659 SetParentOrigin( Vector3( x, current.y, current.z ) );
662 void Actor::SetParentOriginY( float y )
664 const Vector3& current = GetCurrentParentOrigin();
666 SetParentOrigin( Vector3( current.x, y, current.z ) );
669 void Actor::SetParentOriginZ( float z )
671 const Vector3& current = GetCurrentParentOrigin();
673 SetParentOrigin( Vector3( current.x, current.y, z ) );
676 const Vector3& Actor::GetCurrentParentOrigin() const
678 // Cached for event-thread access
679 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
682 void Actor::SetAnchorPoint( const Vector3& anchor )
686 // mNode is being used in a separate thread; queue a message to set the value & base value
687 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
690 // Cache for event-thread access
693 // not allocated, check if different from default
694 if( AnchorPoint::DEFAULT != anchor )
696 mAnchorPoint = new Vector3( anchor );
701 // check if different from current costs more than just set
702 *mAnchorPoint = anchor;
706 void Actor::SetAnchorPointX( float x )
708 const Vector3& current = GetCurrentAnchorPoint();
710 SetAnchorPoint( Vector3( x, current.y, current.z ) );
713 void Actor::SetAnchorPointY( float y )
715 const Vector3& current = GetCurrentAnchorPoint();
717 SetAnchorPoint( Vector3( current.x, y, current.z ) );
720 void Actor::SetAnchorPointZ( float z )
722 const Vector3& current = GetCurrentAnchorPoint();
724 SetAnchorPoint( Vector3( current.x, current.y, z ) );
727 const Vector3& Actor::GetCurrentAnchorPoint() const
729 // Cached for event-thread access
730 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
733 void Actor::SetPosition( float x, float y )
735 SetPosition( Vector3( x, y, 0.0f ) );
738 void Actor::SetPosition( float x, float y, float z )
740 SetPosition( Vector3( x, y, z ) );
743 void Actor::SetPosition( const Vector3& position )
745 mTargetPosition = position;
749 // mNode is being used in a separate thread; queue a message to set the value & base value
750 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
754 void Actor::SetX( float x )
756 mTargetPosition.x = x;
760 // mNode is being used in a separate thread; queue a message to set the value & base value
761 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
765 void Actor::SetY( float y )
767 mTargetPosition.y = y;
771 // mNode is being used in a separate thread; queue a message to set the value & base value
772 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
776 void Actor::SetZ( float z )
778 mTargetPosition.z = z;
782 // mNode is being used in a separate thread; queue a message to set the value & base value
783 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
787 void Actor::TranslateBy( const Vector3& distance )
789 mTargetPosition += distance;
793 // mNode is being used in a separate thread; queue a message to set the value & base value
794 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
798 const Vector3& Actor::GetCurrentPosition() const
802 // mNode is being used in a separate thread; copy the value from the previous update
803 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
806 return Vector3::ZERO;
809 const Vector3& Actor::GetTargetPosition() const
811 return mTargetPosition;
814 const Vector3& Actor::GetCurrentWorldPosition() const
818 // mNode is being used in a separate thread; copy the value from the previous update
819 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
822 return Vector3::ZERO;
825 const Vector2 Actor::GetCurrentScreenPosition() const
827 StagePtr stage = Stage::GetCurrent();
828 if( stage && OnStage() && NULL != mNode )
830 Vector3 worldPosition = mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
831 Vector3 cameraPosition = stage->GetDefaultCameraActor().mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
832 worldPosition -= cameraPosition;
834 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
835 Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
836 Vector3 halfActorSize( actorSize * 0.5f );
837 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
839 return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
840 halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
843 return Vector2::ZERO;
846 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
848 // this flag is not animatable so keep the value
849 mPositionInheritanceMode = mode;
852 // mNode is being used in a separate thread; queue a message to set the value
853 SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION );
857 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
859 // Cached for event-thread access
860 return mPositionInheritanceMode;
863 void Actor::SetInheritPosition( bool inherit )
865 if( mInheritPosition != inherit && NULL != mNode )
867 // non animateable so keep local copy
868 mInheritPosition = inherit;
869 SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit );
873 bool Actor::IsPositionInherited() const
875 return mInheritPosition;
878 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
880 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
881 normalizedAxis.Normalize();
883 Quaternion orientation( angle, normalizedAxis );
885 SetOrientation( orientation );
888 void Actor::SetOrientation( const Quaternion& orientation )
890 mTargetOrientation = orientation;
894 // mNode is being used in a separate thread; queue a message to set the value & base value
895 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
899 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
901 RotateBy( Quaternion(angle, axis) );
904 void Actor::RotateBy( const Quaternion& relativeRotation )
906 mTargetOrientation *= Quaternion( relativeRotation );
910 // mNode is being used in a separate thread; queue a message to set the value & base value
911 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
915 const Quaternion& Actor::GetCurrentOrientation() const
919 // mNode is being used in a separate thread; copy the value from the previous update
920 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
923 return Quaternion::IDENTITY;
926 const Quaternion& Actor::GetCurrentWorldOrientation() const
930 // mNode is being used in a separate thread; copy the value from the previous update
931 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
934 return Quaternion::IDENTITY;
937 void Actor::SetScale( float scale )
939 SetScale( Vector3( scale, scale, scale ) );
942 void Actor::SetScale( float x, float y, float z )
944 SetScale( Vector3( x, y, z ) );
947 void Actor::SetScale( const Vector3& scale )
949 mTargetScale = scale;
953 // mNode is being used in a separate thread; queue a message to set the value & base value
954 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
958 void Actor::SetScaleX( float x )
964 // mNode is being used in a separate thread; queue a message to set the value & base value
965 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
969 void Actor::SetScaleY( float y )
975 // mNode is being used in a separate thread; queue a message to set the value & base value
976 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
980 void Actor::SetScaleZ( float z )
986 // mNode is being used in a separate thread; queue a message to set the value & base value
987 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
991 void Actor::ScaleBy(const Vector3& relativeScale)
993 mTargetScale *= relativeScale;
997 // mNode is being used in a separate thread; queue a message to set the value & base value
998 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
1002 const Vector3& Actor::GetCurrentScale() const
1006 // mNode is being used in a separate thread; copy the value from the previous update
1007 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
1010 return Vector3::ONE;
1013 const Vector3& Actor::GetCurrentWorldScale() const
1017 // mNode is being used in a separate thread; copy the value from the previous update
1018 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
1021 return Vector3::ONE;
1024 void Actor::SetInheritScale( bool inherit )
1027 if( mInheritScale != inherit && NULL != mNode )
1029 // non animateable so keep local copy
1030 mInheritScale = inherit;
1031 // mNode is being used in a separate thread; queue a message to set the value
1032 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
1036 bool Actor::IsScaleInherited() const
1038 return mInheritScale;
1041 Matrix Actor::GetCurrentWorldMatrix() const
1045 return mNode->GetWorldMatrix(0);
1048 return Matrix::IDENTITY;
1051 void Actor::SetVisible( bool visible )
1053 SetVisibleInternal( visible, SendMessage::TRUE );
1056 bool Actor::IsVisible() const
1060 // mNode is being used in a separate thread; copy the value from the previous update
1061 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
1067 void Actor::SetOpacity( float opacity )
1069 mTargetColor.a = opacity;
1073 // mNode is being used in a separate thread; queue a message to set the value & base value
1074 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1078 float Actor::GetCurrentOpacity() const
1082 // mNode is being used in a separate thread; copy the value from the previous update
1083 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1089 ClippingMode::Type Actor::GetClippingMode() const
1091 return mClippingMode;
1094 unsigned int Actor::GetSortingDepth()
1096 return mSortedDepth;
1099 const Vector4& Actor::GetCurrentWorldColor() const
1103 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
1106 return Color::WHITE;
1109 void Actor::SetColor( const Vector4& color )
1111 mTargetColor = color;
1115 // mNode is being used in a separate thread; queue a message to set the value & base value
1116 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1120 void Actor::SetColorRed( float red )
1122 mTargetColor.r = red;
1126 // mNode is being used in a separate thread; queue a message to set the value & base value
1127 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1131 void Actor::SetColorGreen( float green )
1133 mTargetColor.g = green;
1137 // mNode is being used in a separate thread; queue a message to set the value & base value
1138 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1142 void Actor::SetColorBlue( float blue )
1144 mTargetColor.b = blue;
1148 // mNode is being used in a separate thread; queue a message to set the value & base value
1149 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1153 const Vector4& Actor::GetCurrentColor() const
1157 // mNode is being used in a separate thread; copy the value from the previous update
1158 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
1161 return Color::WHITE;
1164 void Actor::SetInheritOrientation( bool inherit )
1166 if( mInheritOrientation != inherit && NULL != mNode)
1168 // non animateable so keep local copy
1169 mInheritOrientation = inherit;
1170 // mNode is being used in a separate thread; queue a message to set the value
1171 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
1175 bool Actor::IsOrientationInherited() const
1177 return mInheritOrientation;
1180 void Actor::SetSizeModeFactor( const Vector3& factor )
1182 EnsureRelayoutData();
1184 mRelayoutData->sizeModeFactor = factor;
1187 const Vector3& Actor::GetSizeModeFactor() const
1189 if ( mRelayoutData )
1191 return mRelayoutData->sizeModeFactor;
1194 return GetDefaultSizeModeFactor();
1197 void Actor::SetColorMode( ColorMode colorMode )
1199 // non animateable so keep local copy
1200 mColorMode = colorMode;
1203 // mNode is being used in a separate thread; queue a message to set the value
1204 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1208 ColorMode Actor::GetColorMode() const
1210 // we have cached copy
1214 void Actor::SetSize( float width, float height )
1216 SetSize( Vector2( width, height ) );
1219 void Actor::SetSize( float width, float height, float depth )
1221 SetSize( Vector3( width, height, depth ) );
1224 void Actor::SetSize( const Vector2& size )
1226 SetSize( Vector3( size.width, size.height, 0.f ) );
1229 void Actor::SetSizeInternal( const Vector2& size )
1231 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1234 void Actor::SetSize( const Vector3& size )
1236 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1238 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1239 SetPreferredSize( size.GetVectorXY() );
1243 SetSizeInternal( size );
1247 void Actor::SetSizeInternal( const Vector3& size )
1249 // dont allow recursive loop
1250 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1251 // 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
1252 if( ( NULL != mNode )&&
1253 ( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1254 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1255 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) )
1259 // mNode is being used in a separate thread; queue a message to set the value & base value
1260 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1262 // Notification for derived classes
1263 mInsideOnSizeSet = true;
1264 OnSizeSet( mTargetSize );
1265 mInsideOnSizeSet = false;
1267 // Raise a relayout request if the flag is not locked
1268 if( mRelayoutData && !mRelayoutData->insideRelayout )
1275 void Actor::SetWidth( float width )
1277 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1279 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1280 mRelayoutData->preferredSize.width = width;
1284 mTargetSize.width = width;
1288 // mNode is being used in a separate thread; queue a message to set the value & base value
1289 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1296 void Actor::SetHeight( float height )
1298 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1300 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1301 mRelayoutData->preferredSize.height = height;
1305 mTargetSize.height = height;
1309 // mNode is being used in a separate thread; queue a message to set the value & base value
1310 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1317 void Actor::SetDepth( float depth )
1319 mTargetSize.depth = depth;
1323 // mNode is being used in a separate thread; queue a message to set the value & base value
1324 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1328 Vector3 Actor::GetTargetSize() const
1330 Vector3 size = mTargetSize;
1332 // Should return preferred size if size is fixed as set by SetSize
1333 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1335 size.width = GetPreferredSize().width;
1337 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1339 size.height = GetPreferredSize().height;
1345 const Vector3& Actor::GetCurrentSize() const
1349 // mNode is being used in a separate thread; copy the value from the previous update
1350 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1353 return Vector3::ZERO;
1356 Vector3 Actor::GetNaturalSize() const
1358 // It is up to deriving classes to return the appropriate natural size
1359 return Vector3( 0.0f, 0.0f, 0.0f );
1362 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1364 EnsureRelayoutData();
1366 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1367 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1369 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1371 if( dimension & ( 1 << i ) )
1373 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1375 mRelayoutData->useAssignedSize[ i ] = true;
1379 mRelayoutData->resizePolicies[ i ] = policy;
1380 mRelayoutData->useAssignedSize[ i ] = false;
1385 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1387 if( dimension & Dimension::WIDTH )
1389 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1392 if( dimension & Dimension::HEIGHT )
1394 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1398 // If calling SetResizePolicy, assume we want relayout enabled
1399 SetRelayoutEnabled( true );
1401 // If the resize policy is set to be FIXED, the preferred size
1402 // should be overrided by the target size. Otherwise the target
1403 // size should be overrided by the preferred size.
1405 if( dimension & Dimension::WIDTH )
1407 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1409 mRelayoutData->preferredSize.width = mTargetSize.width;
1411 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1413 mTargetSize.width = mRelayoutData->preferredSize.width;
1417 if( dimension & Dimension::HEIGHT )
1419 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1421 mRelayoutData->preferredSize.height = mTargetSize.height;
1423 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1425 mTargetSize.height = mRelayoutData->preferredSize.height;
1429 OnSetResizePolicy( policy, dimension );
1431 // Trigger relayout on this control
1435 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1437 if ( mRelayoutData )
1439 // If more than one dimension is requested, just return the first one found
1440 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1442 if( ( dimension & ( 1 << i ) ) )
1444 if( mRelayoutData->useAssignedSize[ i ] )
1446 return ResizePolicy::USE_ASSIGNED_SIZE;
1450 return mRelayoutData->resizePolicies[ i ];
1456 return ResizePolicy::DEFAULT;
1459 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1461 EnsureRelayoutData();
1463 mRelayoutData->sizeSetPolicy = policy;
1466 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1468 if ( mRelayoutData )
1470 return mRelayoutData->sizeSetPolicy;
1473 return DEFAULT_SIZE_SCALE_POLICY;
1476 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1478 EnsureRelayoutData();
1480 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1482 if( dimension & ( 1 << i ) )
1484 mRelayoutData->dimensionDependencies[ i ] = dependency;
1489 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1491 if ( mRelayoutData )
1493 // If more than one dimension is requested, just return the first one found
1494 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1496 if( ( dimension & ( 1 << i ) ) )
1498 return mRelayoutData->dimensionDependencies[ i ];
1503 return Dimension::ALL_DIMENSIONS; // Default
1506 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1508 // If relayout data has not been allocated yet and the client is requesting
1509 // to disable it, do nothing
1510 if( mRelayoutData || relayoutEnabled )
1512 EnsureRelayoutData();
1514 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1516 mRelayoutData->relayoutEnabled = relayoutEnabled;
1520 bool Actor::IsRelayoutEnabled() const
1522 // Assume that if relayout data has not been allocated yet then
1523 // relayout is disabled
1524 return mRelayoutData && mRelayoutData->relayoutEnabled;
1527 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1529 EnsureRelayoutData();
1531 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1533 if( dimension & ( 1 << i ) )
1535 mRelayoutData->dimensionDirty[ i ] = dirty;
1540 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1542 if ( mRelayoutData )
1544 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1546 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1556 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1558 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1561 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1563 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1566 unsigned int Actor::AddRenderer( Renderer& renderer )
1570 mRenderers = new RendererContainer;
1573 unsigned int index = mRenderers->size();
1574 RendererPtr rendererPtr = RendererPtr( &renderer );
1575 mRenderers->push_back( rendererPtr );
1576 AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1580 unsigned int Actor::GetRendererCount() const
1582 unsigned int rendererCount(0);
1585 rendererCount = mRenderers->size();
1588 return rendererCount;
1591 RendererPtr Actor::GetRendererAt( unsigned int index )
1593 RendererPtr renderer;
1594 if( index < GetRendererCount() )
1596 renderer = ( *mRenderers )[ index ];
1602 void Actor::RemoveRenderer( Renderer& renderer )
1606 RendererIter end = mRenderers->end();
1607 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1609 if( (*iter).Get() == &renderer )
1611 mRenderers->erase( iter );
1612 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() );
1619 void Actor::RemoveRenderer( unsigned int index )
1621 if( index < GetRendererCount() )
1623 RendererPtr renderer = ( *mRenderers )[ index ];
1624 RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() );
1625 mRenderers->erase( mRenderers->begin()+index );
1629 bool Actor::IsOverlay() const
1631 return ( DrawMode::OVERLAY_2D == mDrawMode );
1634 void Actor::SetDrawMode( DrawMode::Type drawMode )
1636 // this flag is not animatable so keep the value
1637 mDrawMode = drawMode;
1638 if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
1640 // mNode is being used in a separate thread; queue a message to set the value
1641 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1645 DrawMode::Type Actor::GetDrawMode() const
1650 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1652 // only valid when on-stage
1653 StagePtr stage = Stage::GetCurrent();
1654 if( stage && OnStage() )
1656 const RenderTaskList& taskList = stage->GetRenderTaskList();
1658 Vector2 converted( screenX, screenY );
1660 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1661 const int taskCount = taskList.GetTaskCount();
1662 for( int i = taskCount - 1; i >= 0; --i )
1664 Dali::RenderTask task = taskList.GetTask( i );
1665 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1667 // found a task where this conversion was ok so return
1675 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1677 bool retval = false;
1678 // only valid when on-stage
1681 CameraActor* camera = renderTask.GetCameraActor();
1685 renderTask.GetViewport( viewport );
1687 // need to translate coordinates to render tasks coordinate space
1688 Vector2 converted( screenX, screenY );
1689 if( renderTask.TranslateCoordinates( converted ) )
1691 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1698 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1700 // Early-out if mNode is NULL
1706 // Get the ModelView matrix
1708 Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix );
1710 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1711 Matrix invertedMvp( false/*don't init*/);
1712 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1713 bool success = invertedMvp.Invert();
1715 // Convert to GL coordinates
1716 Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
1721 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
1728 success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
1734 if( XyPlaneIntersect( nearPos, farPos, local ) )
1736 Vector3 size = GetCurrentSize();
1737 localX = local.x + size.x * 0.5f;
1738 localY = local.y + size.y * 0.5f;
1749 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1752 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1754 Mathematical Formulation
1756 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1758 ( p - c ) dot ( p - c ) = r^2
1760 Given a ray with a point of origin 'o', and a direction vector 'd':
1762 ray(t) = o + td, t >= 0
1764 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1766 (o + td - c ) dot ( o + td - c ) = r^2
1768 To solve for t we first expand the above into a more recognisable quadratic equation form
1770 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1779 B = 2( o - c ) dot d
1780 C = ( o - c ) dot ( o - c ) - r^2
1782 which can be solved using a standard quadratic formula.
1784 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1786 Practical Simplification
1788 In a renderer, we often differentiate between world space and object space. In the object space
1789 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1790 into object space, the mathematical solution presented above can be simplified significantly.
1792 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1796 and we can find the t at which the (transformed) ray intersects the sphere by
1798 ( o + td ) dot ( o + td ) = r^2
1800 According to the reasoning above, we expand the above quadratic equation into the general form
1804 which now has coefficients:
1811 // Early out if mNode is NULL
1817 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1819 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1820 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1821 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1823 // Compute the radius is not needed, square radius it's enough.
1824 const Vector3& size( mNode->GetSize( bufferIndex ) );
1826 // Scale the sphere.
1827 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1829 const float width = size.width * scale.width;
1830 const float height = size.height * scale.height;
1832 float squareSphereRadius = 0.5f * ( width * width + height * height );
1834 float a = rayDir.Dot( rayDir ); // a
1835 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1836 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1838 return ( b2 * b2 - a * c ) >= 0.f;
1841 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1845 if( OnStage() && NULL != mNode )
1847 // Transforms the ray to the local reference system.
1848 // Calculate the inverse of Model matrix
1849 Matrix invModelMatrix( false/*don't init*/);
1851 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1852 invModelMatrix = mNode->GetWorldMatrix(0);
1853 invModelMatrix.Invert();
1855 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1856 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1858 // Test with the actor's XY plane (Normal = 0 0 1 1).
1860 float a = -rayOriginLocal.z;
1861 float b = rayDirLocal.z;
1863 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1865 // Ray travels distance * rayDirLocal to intersect with plane.
1868 const Vector3& size = mNode->GetSize( bufferIndex );
1870 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1871 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1873 // Test with the actor's geometry.
1874 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1881 void Actor::SetLeaveRequired( bool required )
1883 mLeaveRequired = required;
1886 bool Actor::GetLeaveRequired() const
1888 return mLeaveRequired;
1891 void Actor::SetKeyboardFocusable( bool focusable )
1893 mKeyboardFocusable = focusable;
1896 bool Actor::IsKeyboardFocusable() const
1898 return mKeyboardFocusable;
1901 bool Actor::GetTouchRequired() const
1903 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1906 bool Actor::GetHoverRequired() const
1908 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1911 bool Actor::GetWheelEventRequired() const
1913 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1916 bool Actor::IsHittable() const
1918 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1921 ActorGestureData& Actor::GetGestureData()
1923 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1924 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1925 if( NULL == mGestureData )
1927 mGestureData = new ActorGestureData;
1929 return *mGestureData;
1932 bool Actor::IsGestureRequred( Gesture::Type type ) const
1934 return mGestureData && mGestureData->IsGestureRequred( type );
1937 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1939 bool consumed = false;
1941 if( !mTouchSignal.Empty() )
1943 Dali::Actor handle( this );
1944 consumed = mTouchSignal.Emit( handle, touch );
1947 if( !mTouchedSignal.Empty() )
1949 Dali::Actor handle( this );
1950 consumed |= mTouchedSignal.Emit( handle, event );
1955 // Notification for derived classes
1956 consumed = OnTouchEvent( event ); // TODO
1962 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1964 bool consumed = false;
1966 if( !mHoveredSignal.Empty() )
1968 Dali::Actor handle( this );
1969 consumed = mHoveredSignal.Emit( handle, event );
1974 // Notification for derived classes
1975 consumed = OnHoverEvent( event );
1981 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1983 bool consumed = false;
1985 if( !mWheelEventSignal.Empty() )
1987 Dali::Actor handle( this );
1988 consumed = mWheelEventSignal.Emit( handle, event );
1993 // Notification for derived classes
1994 consumed = OnWheelEvent( event );
2000 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
2002 if( ! mVisibilityChangedSignal.Empty() )
2004 Dali::Actor handle( this );
2005 mVisibilityChangedSignal.Emit( handle, visible, type );
2009 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
2011 if( ! mLayoutDirectionChangedSignal.Empty() )
2013 Dali::Actor handle( this );
2014 mLayoutDirectionChangedSignal.Emit( handle, type );
2018 void Actor::EmitChildAddedSignal( Actor& child )
2020 if( ! mChildAddedSignal.Empty() )
2022 Dali::Actor handle( &child );
2023 mChildAddedSignal.Emit( handle );
2027 void Actor::EmitChildRemovedSignal( Actor& child )
2029 if( ! mChildRemovedSignal.Empty() )
2031 Dali::Actor handle( &child );
2032 mChildRemovedSignal.Emit( handle );
2036 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
2038 return mTouchedSignal;
2041 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
2043 return mTouchSignal;
2046 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2048 return mHoveredSignal;
2051 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
2053 return mWheelEventSignal;
2056 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2058 return mOnStageSignal;
2061 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2063 return mOffStageSignal;
2066 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
2068 return mOnRelayoutSignal;
2071 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
2073 return mVisibilityChangedSignal;
2076 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
2078 return mLayoutDirectionChangedSignal;
2081 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
2083 return mChildAddedSignal;
2086 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
2088 return mChildRemovedSignal;
2091 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2093 bool connected( true );
2094 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
2096 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
2098 actor->TouchedSignal().Connect( tracker, functor );
2100 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
2102 actor->HoveredSignal().Connect( tracker, functor );
2104 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
2106 actor->WheelEventSignal().Connect( tracker, functor );
2108 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
2110 actor->OnStageSignal().Connect( tracker, functor );
2112 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
2114 actor->OffStageSignal().Connect( tracker, functor );
2116 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
2118 actor->OnRelayoutSignal().Connect( tracker, functor );
2120 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
2122 actor->TouchSignal().Connect( tracker, functor );
2124 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
2126 actor->VisibilityChangedSignal().Connect( tracker, functor );
2128 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
2130 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
2132 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
2134 actor->ChildAddedSignal().Connect( tracker, functor );
2136 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
2138 actor->ChildRemovedSignal().Connect( tracker, functor );
2142 // signalName does not match any signal
2149 Actor::Actor( DerivedType derivedType )
2154 mParentOrigin( NULL ),
2155 mAnchorPoint( NULL ),
2156 mRelayoutData( NULL ),
2157 mGestureData( NULL ),
2161 mWheelEventSignal(),
2164 mOnRelayoutSignal(),
2165 mVisibilityChangedSignal(),
2166 mLayoutDirectionChangedSignal(),
2167 mChildAddedSignal(),
2168 mChildRemovedSignal(),
2169 mTargetOrientation( Quaternion::IDENTITY ),
2170 mTargetColor( Color::WHITE ),
2171 mTargetSize( Vector3::ZERO ),
2172 mTargetPosition( Vector3::ZERO ),
2173 mTargetScale( Vector3::ONE ),
2175 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2178 mIsRoot( ROOT_LAYER == derivedType ),
2179 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2180 mIsOnStage( false ),
2182 mLeaveRequired( false ),
2183 mKeyboardFocusable( false ),
2184 mDerivedRequiresTouch( false ),
2185 mDerivedRequiresHover( false ),
2186 mDerivedRequiresWheelEvent( false ),
2187 mOnStageSignalled( false ),
2188 mInsideOnSizeSet( false ),
2189 mInheritPosition( true ),
2190 mInheritOrientation( true ),
2191 mInheritScale( true ),
2192 mPositionUsesAnchorPoint( true ),
2194 mInheritLayoutDirection( true ),
2195 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2196 mDrawMode( DrawMode::NORMAL ),
2197 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2198 mColorMode( Node::DEFAULT_COLOR_MODE ),
2199 mClippingMode( ClippingMode::DISABLED )
2203 void Actor::Initialize()
2205 // Node creation, keep raw-pointer to Node for messaging
2206 mNode = CreateNode();
2207 OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
2208 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
2212 GetEventThreadServices().RegisterObject( this );
2217 // Remove mParent pointers from children even if we're destroying core,
2218 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2221 ActorConstIter endIter = mChildren->end();
2222 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2224 (*iter)->SetParent( NULL );
2230 // Guard to allow handle destruction after Core has been destroyed
2231 if( EventThreadServices::IsCoreRunning() )
2235 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2236 mNode = NULL; // Node is about to be destroyed
2239 GetEventThreadServices().UnregisterObject( this );
2242 // Cleanup optional gesture data
2243 delete mGestureData;
2245 // Cleanup optional parent origin and anchor
2246 delete mParentOrigin;
2247 delete mAnchorPoint;
2249 // Delete optional relayout data
2252 delete mRelayoutData;
2256 void Actor::ConnectToStage( unsigned int parentDepth )
2258 // This container is used instead of walking the Actor hierarchy.
2259 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2260 ActorContainer connectionList;
2262 StagePtr stage = Stage::GetCurrent();
2265 stage->RequestRebuildDepthTree();
2268 // This stage is atomic i.e. not interrupted by user callbacks.
2269 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2271 // Notify applications about the newly connected actors.
2272 const ActorIter endIter = connectionList.end();
2273 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2275 (*iter)->NotifyStageConnection();
2281 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth )
2283 DALI_ASSERT_ALWAYS( !OnStage() );
2288 ConnectToSceneGraph();
2290 // Notification for internal derived classes
2291 OnStageConnectionInternal();
2293 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2294 connectionList.push_back( ActorPtr( this ) );
2296 // Recursively connect children
2299 ActorConstIter endIter = mChildren->end();
2300 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2302 (*iter)->RecursiveConnectToStage( connectionList, depth+1 );
2308 * This method is called when the Actor is connected to the Stage.
2309 * The parent must have added its Node to the scene-graph.
2310 * The child must connect its Node to the parent's Node.
2311 * This is recursive; the child calls ConnectToStage() for its children.
2313 void Actor::ConnectToSceneGraph()
2315 DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2319 // Reparent Node in next Update
2320 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode );
2323 // Request relayout on all actors that are added to the scenegraph
2326 // Notification for Object::Observers
2330 void Actor::NotifyStageConnection()
2332 // Actors can be removed (in a callback), before the on-stage stage is reported.
2333 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2334 if( OnStage() && !mOnStageSignalled )
2336 // Notification for external (CustomActor) derived classes
2337 OnStageConnectionExternal( mDepth );
2339 if( !mOnStageSignal.Empty() )
2341 Dali::Actor handle( this );
2342 mOnStageSignal.Emit( handle );
2345 // Guard against Remove during callbacks
2348 mOnStageSignalled = true; // signal required next time Actor is removed
2353 void Actor::DisconnectFromStage()
2355 // This container is used instead of walking the Actor hierachy.
2356 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2357 ActorContainer disconnectionList;
2359 StagePtr stage = Stage::GetCurrent();
2362 stage->RequestRebuildDepthTree();
2365 // This stage is atomic i.e. not interrupted by user callbacks
2366 RecursiveDisconnectFromStage( disconnectionList );
2368 // Notify applications about the newly disconnected actors.
2369 const ActorIter endIter = disconnectionList.end();
2370 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2372 (*iter)->NotifyStageDisconnection();
2376 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2378 DALI_ASSERT_ALWAYS( OnStage() );
2380 // Recursively disconnect children
2383 ActorConstIter endIter = mChildren->end();
2384 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2386 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2390 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2391 disconnectionList.push_back( ActorPtr( this ) );
2393 // Notification for internal derived classes
2394 OnStageDisconnectionInternal();
2396 DisconnectFromSceneGraph();
2402 * This method is called by an actor or its parent, before a node removal message is sent.
2403 * This is recursive; the child calls DisconnectFromStage() for its children.
2405 void Actor::DisconnectFromSceneGraph()
2407 // Notification for Object::Observers
2408 OnSceneObjectRemove();
2411 void Actor::NotifyStageDisconnection()
2413 // Actors can be added (in a callback), before the off-stage state is reported.
2414 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2415 // only do this step if there is a stage, i.e. Core is not being shut down
2416 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2418 // Notification for external (CustomeActor) derived classes
2419 OnStageDisconnectionExternal();
2421 if( !mOffStageSignal.Empty() )
2423 Dali::Actor handle( this );
2424 mOffStageSignal.Emit( handle );
2427 // Guard against Add during callbacks
2430 mOnStageSignalled = false; // signal required next time Actor is added
2435 bool Actor::IsNodeConnected() const
2437 bool connected( false );
2439 if( OnStage() && ( NULL != mNode ) )
2441 if( IsRoot() || mNode->GetParent() )
2450 // This method initiates traversal of the actor tree using depth-first
2451 // traversal to set a depth index based on traversal order. It sends a
2452 // single message to update manager to update all the actor's nodes in
2453 // this tree with the depth index. The sceneGraphNodeDepths vector's
2454 // elements are ordered by depth, and could be used to reduce sorting
2455 // in the update thread.
2456 void Actor::RebuildDepthTree()
2458 DALI_LOG_TIMER_START(depthTimer);
2460 // Vector of scene-graph nodes and their depths to send to UpdateManager
2461 // in a single message
2462 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2465 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2467 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2468 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2471 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
2473 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2474 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
2476 // Create/add to children of this node
2479 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2481 Actor* childActor = (*it).Get();
2483 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2488 unsigned int Actor::GetDefaultPropertyCount() const
2490 return DEFAULT_PROPERTY_COUNT;
2493 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2495 indices.Reserve( DEFAULT_PROPERTY_COUNT );
2497 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2499 indices.PushBack( i );
2503 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2505 if( index < DEFAULT_PROPERTY_COUNT )
2507 return DEFAULT_PROPERTY_DETAILS[ index ].name;
2513 Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
2515 Property::Index index = Property::INVALID_INDEX;
2517 // Look for name in default properties
2518 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2520 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2521 if( 0 == name.compare( property->name ) )
2531 bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
2533 if( index < DEFAULT_PROPERTY_COUNT )
2535 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
2541 bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
2543 if( index < DEFAULT_PROPERTY_COUNT )
2545 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
2551 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2553 if( index < DEFAULT_PROPERTY_COUNT )
2555 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
2561 Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
2563 if( index < DEFAULT_PROPERTY_COUNT )
2565 return DEFAULT_PROPERTY_DETAILS[ index ].type;
2568 // index out of range...return Property::NONE
2569 return Property::NONE;
2572 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2576 case Dali::Actor::Property::PARENT_ORIGIN:
2578 Property::Type type = property.GetType();
2579 if( type == Property::VECTOR3 )
2581 SetParentOrigin( property.Get< Vector3 >() );
2583 else if ( type == Property::STRING )
2585 std::string parentOriginString;
2586 property.Get( parentOriginString );
2587 Vector3 parentOrigin;
2588 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2590 SetParentOrigin( parentOrigin );
2596 case Dali::Actor::Property::PARENT_ORIGIN_X:
2598 SetParentOriginX( property.Get< float >() );
2602 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2604 SetParentOriginY( property.Get< float >() );
2608 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2610 SetParentOriginZ( property.Get< float >() );
2614 case Dali::Actor::Property::ANCHOR_POINT:
2616 Property::Type type = property.GetType();
2617 if( type == Property::VECTOR3 )
2619 SetAnchorPoint( property.Get< Vector3 >() );
2621 else if ( type == Property::STRING )
2623 std::string anchorPointString;
2624 property.Get( anchorPointString );
2626 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2628 SetAnchorPoint( anchor );
2634 case Dali::Actor::Property::ANCHOR_POINT_X:
2636 SetAnchorPointX( property.Get< float >() );
2640 case Dali::Actor::Property::ANCHOR_POINT_Y:
2642 SetAnchorPointY( property.Get< float >() );
2646 case Dali::Actor::Property::ANCHOR_POINT_Z:
2648 SetAnchorPointZ( property.Get< float >() );
2652 case Dali::Actor::Property::SIZE:
2654 SetSize( property.Get< Vector3 >() );
2658 case Dali::Actor::Property::SIZE_WIDTH:
2660 SetWidth( property.Get< float >() );
2664 case Dali::Actor::Property::SIZE_HEIGHT:
2666 SetHeight( property.Get< float >() );
2670 case Dali::Actor::Property::SIZE_DEPTH:
2672 SetDepth( property.Get< float >() );
2676 case Dali::Actor::Property::POSITION:
2678 SetPosition( property.Get< Vector3 >() );
2682 case Dali::Actor::Property::POSITION_X:
2684 SetX( property.Get< float >() );
2688 case Dali::Actor::Property::POSITION_Y:
2690 SetY( property.Get< float >() );
2694 case Dali::Actor::Property::POSITION_Z:
2696 SetZ( property.Get< float >() );
2700 case Dali::Actor::Property::ORIENTATION:
2702 SetOrientation( property.Get< Quaternion >() );
2706 case Dali::Actor::Property::SCALE:
2708 SetScale( property.Get< Vector3 >() );
2712 case Dali::Actor::Property::SCALE_X:
2714 SetScaleX( property.Get< float >() );
2718 case Dali::Actor::Property::SCALE_Y:
2720 SetScaleY( property.Get< float >() );
2724 case Dali::Actor::Property::SCALE_Z:
2726 SetScaleZ( property.Get< float >() );
2730 case Dali::Actor::Property::VISIBLE:
2732 SetVisible( property.Get< bool >() );
2736 case Dali::Actor::Property::COLOR:
2738 SetColor( property.Get< Vector4 >() );
2742 case Dali::Actor::Property::COLOR_RED:
2744 SetColorRed( property.Get< float >() );
2748 case Dali::Actor::Property::COLOR_GREEN:
2750 SetColorGreen( property.Get< float >() );
2754 case Dali::Actor::Property::COLOR_BLUE:
2756 SetColorBlue( property.Get< float >() );
2760 case Dali::Actor::Property::COLOR_ALPHA:
2761 case Dali::DevelActor::Property::OPACITY:
2764 if( property.Get( value ) )
2766 SetOpacity( value );
2771 case Dali::Actor::Property::NAME:
2773 SetName( property.Get< std::string >() );
2777 case Dali::Actor::Property::SENSITIVE:
2779 SetSensitive( property.Get< bool >() );
2783 case Dali::Actor::Property::LEAVE_REQUIRED:
2785 SetLeaveRequired( property.Get< bool >() );
2789 case Dali::Actor::Property::INHERIT_POSITION:
2791 SetInheritPosition( property.Get< bool >() );
2795 case Dali::Actor::Property::INHERIT_ORIENTATION:
2797 SetInheritOrientation( property.Get< bool >() );
2801 case Dali::Actor::Property::INHERIT_SCALE:
2803 SetInheritScale( property.Get< bool >() );
2807 case Dali::Actor::Property::COLOR_MODE:
2809 ColorMode mode = mColorMode;
2810 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2812 SetColorMode( mode );
2817 case Dali::Actor::Property::POSITION_INHERITANCE:
2819 PositionInheritanceMode mode = mPositionInheritanceMode;
2820 if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) )
2822 SetPositionInheritanceMode( mode );
2827 case Dali::Actor::Property::DRAW_MODE:
2829 DrawMode::Type mode = mDrawMode;
2830 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2832 SetDrawMode( mode );
2837 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2839 SetSizeModeFactor( property.Get< Vector3 >() );
2843 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2845 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2846 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2848 SetResizePolicy( type, Dimension::WIDTH );
2853 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2855 ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set.
2856 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2858 SetResizePolicy( type, Dimension::HEIGHT );
2863 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2865 SizeScalePolicy::Type type;
2866 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2868 SetSizeScalePolicy( type );
2873 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2875 if( property.Get< bool >() )
2877 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2882 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2884 if( property.Get< bool >() )
2886 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2891 case Dali::Actor::Property::PADDING:
2893 Vector4 padding = property.Get< Vector4 >();
2894 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2895 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2899 case Dali::Actor::Property::MINIMUM_SIZE:
2901 Vector2 size = property.Get< Vector2 >();
2902 SetMinimumSize( size.x, Dimension::WIDTH );
2903 SetMinimumSize( size.y, Dimension::HEIGHT );
2907 case Dali::Actor::Property::MAXIMUM_SIZE:
2909 Vector2 size = property.Get< Vector2 >();
2910 SetMaximumSize( size.x, Dimension::WIDTH );
2911 SetMaximumSize( size.y, Dimension::HEIGHT );
2915 case Dali::DevelActor::Property::SIBLING_ORDER:
2919 if( property.Get( value ) )
2921 SetSiblingOrder( value );
2926 case Dali::Actor::Property::CLIPPING_MODE:
2928 ClippingMode::Type convertedValue = mClippingMode;
2929 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2931 mClippingMode = convertedValue;
2934 SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
2940 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2943 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2945 mPositionUsesAnchorPoint = value;
2948 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint );
2954 case Dali::Actor::Property::LAYOUT_DIRECTION:
2956 Dali::LayoutDirection::Type direction = mLayoutDirection;
2957 mInheritLayoutDirection = false;
2959 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2961 InheritLayoutDirectionRecursively( this, direction, true );
2966 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2969 if( property.Get( value ) )
2971 SetInheritLayoutDirection( value );
2978 // this can happen in the case of a non-animatable default property so just do nothing
2984 // TODO: This method needs to be removed
2985 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2987 switch( entry.GetType() )
2989 case Property::BOOLEAN:
2991 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2992 DALI_ASSERT_DEBUG( NULL != property );
2994 // property is being used in a separate thread; queue a message to set the property
2995 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
3000 case Property::INTEGER:
3002 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
3003 DALI_ASSERT_DEBUG( NULL != property );
3005 // property is being used in a separate thread; queue a message to set the property
3006 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
3011 case Property::FLOAT:
3013 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
3014 DALI_ASSERT_DEBUG( NULL != property );
3016 // property is being used in a separate thread; queue a message to set the property
3017 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
3022 case Property::VECTOR2:
3024 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( 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 if(entry.componentIndex == 0)
3030 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
3032 else if(entry.componentIndex == 1)
3034 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
3038 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
3044 case Property::VECTOR3:
3046 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( 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 if(entry.componentIndex == 0)
3052 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
3054 else if(entry.componentIndex == 1)
3056 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
3058 else if(entry.componentIndex == 2)
3060 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
3064 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
3070 case Property::VECTOR4:
3072 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
3073 DALI_ASSERT_DEBUG( NULL != property );
3075 // property is being used in a separate thread; queue a message to set the property
3076 if(entry.componentIndex == 0)
3078 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
3080 else if(entry.componentIndex == 1)
3082 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
3084 else if(entry.componentIndex == 2)
3086 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
3088 else if(entry.componentIndex == 3)
3090 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
3094 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
3100 case Property::ROTATION:
3102 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
3103 DALI_ASSERT_DEBUG( NULL != property );
3105 // property is being used in a separate thread; queue a message to set the property
3106 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
3111 case Property::MATRIX:
3113 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
3114 DALI_ASSERT_DEBUG( NULL != property );
3116 // property is being used in a separate thread; queue a message to set the property
3117 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
3122 case Property::MATRIX3:
3124 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
3125 DALI_ASSERT_DEBUG( NULL != property );
3127 // property is being used in a separate thread; queue a message to set the property
3128 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
3135 // nothing to do for other types
3140 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
3142 Property::Value value;
3144 if( ! GetCachedPropertyValue( index, value ) )
3146 // If property value is not stored in the event-side, then it must be a scene-graph only property
3147 GetCurrentPropertyValue( index, value );
3153 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
3155 Property::Value value;
3157 if( ! GetCurrentPropertyValue( index, value ) )
3159 // If unable to retrieve scene-graph property value, then it must be an event-side only property
3160 GetCachedPropertyValue( index, value );
3166 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
3168 switch( animationType )
3171 case Animation::BETWEEN:
3175 case Dali::Actor::Property::SIZE:
3177 if( value.Get( mTargetSize ) )
3179 // Notify deriving classes
3180 OnSizeAnimation( animation, mTargetSize );
3185 case Dali::Actor::Property::SIZE_WIDTH:
3187 if( value.Get( mTargetSize.width ) )
3189 // Notify deriving classes
3190 OnSizeAnimation( animation, mTargetSize );
3195 case Dali::Actor::Property::SIZE_HEIGHT:
3197 if( value.Get( mTargetSize.height ) )
3199 // Notify deriving classes
3200 OnSizeAnimation( animation, mTargetSize );
3205 case Dali::Actor::Property::SIZE_DEPTH:
3207 if( value.Get( mTargetSize.depth ) )
3209 // Notify deriving classes
3210 OnSizeAnimation( animation, mTargetSize );
3215 case Dali::Actor::Property::POSITION:
3217 value.Get( mTargetPosition );
3221 case Dali::Actor::Property::POSITION_X:
3223 value.Get( mTargetPosition.x );
3227 case Dali::Actor::Property::POSITION_Y:
3229 value.Get( mTargetPosition.y );
3233 case Dali::Actor::Property::POSITION_Z:
3235 value.Get( mTargetPosition.z );
3239 case Dali::Actor::Property::ORIENTATION:
3241 value.Get( mTargetOrientation );
3245 case Dali::Actor::Property::SCALE:
3247 value.Get( mTargetScale );
3251 case Dali::Actor::Property::SCALE_X:
3253 value.Get( mTargetScale.x );
3257 case Dali::Actor::Property::SCALE_Y:
3259 value.Get( mTargetScale.y );
3263 case Dali::Actor::Property::SCALE_Z:
3265 value.Get( mTargetScale.z );
3269 case Dali::Actor::Property::VISIBLE:
3271 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3275 case Dali::Actor::Property::COLOR:
3277 value.Get( mTargetColor );
3281 case Dali::Actor::Property::COLOR_RED:
3283 value.Get( mTargetColor.r );
3287 case Dali::Actor::Property::COLOR_GREEN:
3289 value.Get( mTargetColor.g );
3293 case Dali::Actor::Property::COLOR_BLUE:
3295 value.Get( mTargetColor.b );
3299 case Dali::Actor::Property::COLOR_ALPHA:
3300 case Dali::DevelActor::Property::OPACITY:
3302 value.Get( mTargetColor.a );
3308 // Not an animatable property. Do nothing.
3319 case Dali::Actor::Property::SIZE:
3321 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3323 // Notify deriving classes
3324 OnSizeAnimation( animation, mTargetSize );
3329 case Dali::Actor::Property::SIZE_WIDTH:
3331 if( AdjustValue< float >( mTargetSize.width, value ) )
3333 // Notify deriving classes
3334 OnSizeAnimation( animation, mTargetSize );
3339 case Dali::Actor::Property::SIZE_HEIGHT:
3341 if( AdjustValue< float >( mTargetSize.height, value ) )
3343 // Notify deriving classes
3344 OnSizeAnimation( animation, mTargetSize );
3349 case Dali::Actor::Property::SIZE_DEPTH:
3351 if( AdjustValue< float >( mTargetSize.depth, value ) )
3353 // Notify deriving classes
3354 OnSizeAnimation( animation, mTargetSize );
3359 case Dali::Actor::Property::POSITION:
3361 AdjustValue< Vector3 >( mTargetPosition, value );
3365 case Dali::Actor::Property::POSITION_X:
3367 AdjustValue< float >( mTargetPosition.x, value );
3371 case Dali::Actor::Property::POSITION_Y:
3373 AdjustValue< float >( mTargetPosition.y, value );
3377 case Dali::Actor::Property::POSITION_Z:
3379 AdjustValue< float >( mTargetPosition.z, value );
3383 case Dali::Actor::Property::ORIENTATION:
3385 Quaternion relativeValue;
3386 if( value.Get( relativeValue ) )
3388 mTargetOrientation *= relativeValue;
3393 case Dali::Actor::Property::SCALE:
3395 AdjustValue< Vector3 >( mTargetScale, value );
3399 case Dali::Actor::Property::SCALE_X:
3401 AdjustValue< float >( mTargetScale.x, value );
3405 case Dali::Actor::Property::SCALE_Y:
3407 AdjustValue< float >( mTargetScale.y, value );
3411 case Dali::Actor::Property::SCALE_Z:
3413 AdjustValue< float >( mTargetScale.z, value );
3417 case Dali::Actor::Property::VISIBLE:
3419 bool relativeValue = false;
3420 if( value.Get( relativeValue ) )
3422 bool visible = mVisible || relativeValue;
3423 SetVisibleInternal( visible, SendMessage::FALSE );
3428 case Dali::Actor::Property::COLOR:
3430 AdjustValue< Vector4 >( mTargetColor, value );
3434 case Dali::Actor::Property::COLOR_RED:
3436 AdjustValue< float >( mTargetColor.r, value );
3440 case Dali::Actor::Property::COLOR_GREEN:
3442 AdjustValue< float >( mTargetColor.g, value );
3446 case Dali::Actor::Property::COLOR_BLUE:
3448 AdjustValue< float >( mTargetColor.b, value );
3452 case Dali::Actor::Property::COLOR_ALPHA:
3453 case Dali::DevelActor::Property::OPACITY:
3455 AdjustValue< float >( mTargetColor.a, value );
3461 // Not an animatable property. Do nothing.
3470 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3475 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3477 // This method should only return an object connected to the scene-graph
3478 return OnStage() ? mNode : NULL;
3481 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3483 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
3485 const PropertyBase* property( NULL );
3487 // This method should only return a property of an object connected to the scene-graph
3493 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3495 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3496 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3498 property = animatable->GetSceneGraphProperty();
3500 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3501 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3503 CustomPropertyMetadata* custom = FindCustomProperty( index );
3504 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3506 property = custom->GetSceneGraphProperty();
3508 else if( NULL != mNode )
3512 case Dali::Actor::Property::SIZE:
3513 property = &mNode->mSize;
3516 case Dali::Actor::Property::SIZE_WIDTH:
3517 property = &mNode->mSize;
3520 case Dali::Actor::Property::SIZE_HEIGHT:
3521 property = &mNode->mSize;
3524 case Dali::Actor::Property::SIZE_DEPTH:
3525 property = &mNode->mSize;
3528 case Dali::Actor::Property::POSITION:
3529 property = &mNode->mPosition;
3532 case Dali::Actor::Property::POSITION_X:
3533 property = &mNode->mPosition;
3536 case Dali::Actor::Property::POSITION_Y:
3537 property = &mNode->mPosition;
3540 case Dali::Actor::Property::POSITION_Z:
3541 property = &mNode->mPosition;
3544 case Dali::Actor::Property::ORIENTATION:
3545 property = &mNode->mOrientation;
3548 case Dali::Actor::Property::SCALE:
3549 property = &mNode->mScale;
3552 case Dali::Actor::Property::SCALE_X:
3553 property = &mNode->mScale;
3556 case Dali::Actor::Property::SCALE_Y:
3557 property = &mNode->mScale;
3560 case Dali::Actor::Property::SCALE_Z:
3561 property = &mNode->mScale;
3564 case Dali::Actor::Property::VISIBLE:
3565 property = &mNode->mVisible;
3568 case Dali::Actor::Property::COLOR:
3569 property = &mNode->mColor;
3572 case Dali::Actor::Property::COLOR_RED:
3573 property = &mNode->mColor;
3576 case Dali::Actor::Property::COLOR_GREEN:
3577 property = &mNode->mColor;
3580 case Dali::Actor::Property::COLOR_BLUE:
3581 property = &mNode->mColor;
3584 case Dali::Actor::Property::COLOR_ALPHA:
3585 case Dali::DevelActor::Property::OPACITY:
3586 property = &mNode->mColor;
3597 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3599 const PropertyInputImpl* property( NULL );
3601 // This method should only return a property of an object connected to the scene-graph
3607 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3609 AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
3610 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3612 property = animatable->GetSceneGraphProperty();
3614 else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
3615 ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
3617 CustomPropertyMetadata* custom = FindCustomProperty( index );
3618 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3619 property = custom->GetSceneGraphProperty();
3621 else if( NULL != mNode )
3625 case Dali::Actor::Property::PARENT_ORIGIN:
3626 property = &mNode->mParentOrigin;
3629 case Dali::Actor::Property::PARENT_ORIGIN_X:
3630 property = &mNode->mParentOrigin;
3633 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3634 property = &mNode->mParentOrigin;
3637 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3638 property = &mNode->mParentOrigin;
3641 case Dali::Actor::Property::ANCHOR_POINT:
3642 property = &mNode->mAnchorPoint;
3645 case Dali::Actor::Property::ANCHOR_POINT_X:
3646 property = &mNode->mAnchorPoint;
3649 case Dali::Actor::Property::ANCHOR_POINT_Y:
3650 property = &mNode->mAnchorPoint;
3653 case Dali::Actor::Property::ANCHOR_POINT_Z:
3654 property = &mNode->mAnchorPoint;
3657 case Dali::Actor::Property::SIZE:
3658 property = &mNode->mSize;
3661 case Dali::Actor::Property::SIZE_WIDTH:
3662 property = &mNode->mSize;
3665 case Dali::Actor::Property::SIZE_HEIGHT:
3666 property = &mNode->mSize;
3669 case Dali::Actor::Property::SIZE_DEPTH:
3670 property = &mNode->mSize;
3673 case Dali::Actor::Property::POSITION:
3674 property = &mNode->mPosition;
3677 case Dali::Actor::Property::POSITION_X:
3678 property = &mNode->mPosition;
3681 case Dali::Actor::Property::POSITION_Y:
3682 property = &mNode->mPosition;
3685 case Dali::Actor::Property::POSITION_Z:
3686 property = &mNode->mPosition;
3689 case Dali::Actor::Property::WORLD_POSITION:
3690 property = &mNode->mWorldPosition;
3693 case Dali::Actor::Property::WORLD_POSITION_X:
3694 property = &mNode->mWorldPosition;
3697 case Dali::Actor::Property::WORLD_POSITION_Y:
3698 property = &mNode->mWorldPosition;
3701 case Dali::Actor::Property::WORLD_POSITION_Z:
3702 property = &mNode->mWorldPosition;
3705 case Dali::Actor::Property::ORIENTATION:
3706 property = &mNode->mOrientation;
3709 case Dali::Actor::Property::WORLD_ORIENTATION:
3710 property = &mNode->mWorldOrientation;
3713 case Dali::Actor::Property::SCALE:
3714 property = &mNode->mScale;
3717 case Dali::Actor::Property::SCALE_X:
3718 property = &mNode->mScale;
3721 case Dali::Actor::Property::SCALE_Y:
3722 property = &mNode->mScale;
3725 case Dali::Actor::Property::SCALE_Z:
3726 property = &mNode->mScale;
3729 case Dali::Actor::Property::WORLD_SCALE:
3730 property = &mNode->mWorldScale;
3733 case Dali::Actor::Property::VISIBLE:
3734 property = &mNode->mVisible;
3737 case Dali::Actor::Property::COLOR:
3738 property = &mNode->mColor;
3741 case Dali::Actor::Property::COLOR_RED:
3742 property = &mNode->mColor;
3745 case Dali::Actor::Property::COLOR_GREEN:
3746 property = &mNode->mColor;
3749 case Dali::Actor::Property::COLOR_BLUE:
3750 property = &mNode->mColor;
3753 case Dali::Actor::Property::COLOR_ALPHA:
3754 case Dali::DevelActor::Property::OPACITY:
3756 property = &mNode->mColor;
3760 case Dali::Actor::Property::WORLD_COLOR:
3761 property = &mNode->mWorldColor;
3764 case Dali::Actor::Property::WORLD_MATRIX:
3765 property = &mNode->mWorldMatrix;
3776 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3778 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3780 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
3782 // check whether the animatable property is registered already, if not then register one.
3783 AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
3784 if( animatableProperty )
3786 componentIndex = animatableProperty->componentIndex;
3793 case Dali::Actor::Property::PARENT_ORIGIN_X:
3794 case Dali::Actor::Property::ANCHOR_POINT_X:
3795 case Dali::Actor::Property::SIZE_WIDTH:
3796 case Dali::Actor::Property::POSITION_X:
3797 case Dali::Actor::Property::WORLD_POSITION_X:
3798 case Dali::Actor::Property::SCALE_X:
3799 case Dali::Actor::Property::COLOR_RED:
3805 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3806 case Dali::Actor::Property::ANCHOR_POINT_Y:
3807 case Dali::Actor::Property::SIZE_HEIGHT:
3808 case Dali::Actor::Property::POSITION_Y:
3809 case Dali::Actor::Property::WORLD_POSITION_Y:
3810 case Dali::Actor::Property::SCALE_Y:
3811 case Dali::Actor::Property::COLOR_GREEN:
3817 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3818 case Dali::Actor::Property::ANCHOR_POINT_Z:
3819 case Dali::Actor::Property::SIZE_DEPTH:
3820 case Dali::Actor::Property::POSITION_Z:
3821 case Dali::Actor::Property::WORLD_POSITION_Z:
3822 case Dali::Actor::Property::SCALE_Z:
3823 case Dali::Actor::Property::COLOR_BLUE:
3829 case Dali::Actor::Property::COLOR_ALPHA:
3830 case Dali::DevelActor::Property::OPACITY:
3844 return componentIndex;
3847 void Actor::SetParent( Actor* parent )
3851 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3855 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3858 // Instruct each actor to create a corresponding node in the scene graph
3859 ConnectToStage( parent->GetHierarchyDepth() );
3862 // Resolve the name and index for the child properties if any
3863 ResolveChildProperties();
3865 else // parent being set to NULL
3867 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3871 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3874 DALI_ASSERT_ALWAYS( mNode != NULL );
3878 // Disconnect the Node & its children from the scene-graph.
3879 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3882 // Instruct each actor to discard pointers to the scene-graph
3883 DisconnectFromStage();
3888 SceneGraph::Node* Actor::CreateNode() const
3893 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3896 Actor* actor = dynamic_cast< Actor* >( object );
3900 if( 0 == actionName.compare( ACTION_SHOW ) )
3902 actor->SetVisible( true );
3905 else if( 0 == actionName.compare( ACTION_HIDE ) )
3907 actor->SetVisible( false );
3915 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3917 bool valueSet = true;
3921 case Dali::Actor::Property::PARENT_ORIGIN:
3923 value = GetCurrentParentOrigin();
3927 case Dali::Actor::Property::PARENT_ORIGIN_X:
3929 value = GetCurrentParentOrigin().x;
3933 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3935 value = GetCurrentParentOrigin().y;
3939 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3941 value = GetCurrentParentOrigin().z;
3945 case Dali::Actor::Property::ANCHOR_POINT:
3947 value = GetCurrentAnchorPoint();
3951 case Dali::Actor::Property::ANCHOR_POINT_X:
3953 value = GetCurrentAnchorPoint().x;
3957 case Dali::Actor::Property::ANCHOR_POINT_Y:
3959 value = GetCurrentAnchorPoint().y;
3963 case Dali::Actor::Property::ANCHOR_POINT_Z:
3965 value = GetCurrentAnchorPoint().z;
3969 case Dali::Actor::Property::SIZE:
3971 value = GetTargetSize();
3975 case Dali::Actor::Property::SIZE_WIDTH:
3977 value = GetTargetSize().width;
3981 case Dali::Actor::Property::SIZE_HEIGHT:
3983 value = GetTargetSize().height;
3987 case Dali::Actor::Property::SIZE_DEPTH:
3989 value = GetTargetSize().depth;
3993 case Dali::Actor::Property::POSITION:
3995 value = GetTargetPosition();
3999 case Dali::Actor::Property::POSITION_X:
4001 value = GetTargetPosition().x;
4005 case Dali::Actor::Property::POSITION_Y:
4007 value = GetTargetPosition().y;
4011 case Dali::Actor::Property::POSITION_Z:
4013 value = GetTargetPosition().z;
4017 case Dali::Actor::Property::ORIENTATION:
4019 value = mTargetOrientation;
4023 case Dali::Actor::Property::SCALE:
4025 value = mTargetScale;
4029 case Dali::Actor::Property::SCALE_X:
4031 value = mTargetScale.x;
4035 case Dali::Actor::Property::SCALE_Y:
4037 value = mTargetScale.y;
4041 case Dali::Actor::Property::SCALE_Z:
4043 value = mTargetScale.z;
4047 case Dali::Actor::Property::VISIBLE:
4053 case Dali::Actor::Property::COLOR:
4055 value = mTargetColor;
4059 case Dali::Actor::Property::COLOR_RED:
4061 value = mTargetColor.r;
4065 case Dali::Actor::Property::COLOR_GREEN:
4067 value = mTargetColor.g;
4071 case Dali::Actor::Property::COLOR_BLUE:
4073 value = mTargetColor.b;
4077 case Dali::Actor::Property::COLOR_ALPHA:
4078 case Dali::DevelActor::Property::OPACITY:
4080 value = mTargetColor.a;
4084 case Dali::Actor::Property::NAME:
4090 case Dali::Actor::Property::SENSITIVE:
4092 value = IsSensitive();
4096 case Dali::Actor::Property::LEAVE_REQUIRED:
4098 value = GetLeaveRequired();
4102 case Dali::Actor::Property::INHERIT_POSITION:
4104 value = IsPositionInherited();
4108 case Dali::Actor::Property::INHERIT_ORIENTATION:
4110 value = IsOrientationInherited();
4114 case Dali::Actor::Property::INHERIT_SCALE:
4116 value = IsScaleInherited();
4120 case Dali::Actor::Property::COLOR_MODE:
4122 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
4126 case Dali::Actor::Property::POSITION_INHERITANCE:
4128 value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
4132 case Dali::Actor::Property::DRAW_MODE:
4134 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
4138 case Dali::Actor::Property::SIZE_MODE_FACTOR:
4140 value = GetSizeModeFactor();
4144 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
4146 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4150 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
4152 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
4156 case Dali::Actor::Property::SIZE_SCALE_POLICY:
4158 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
4162 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
4164 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
4168 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
4170 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
4174 case Dali::Actor::Property::PADDING:
4176 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
4177 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
4178 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
4182 case Dali::Actor::Property::MINIMUM_SIZE:
4184 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
4188 case Dali::Actor::Property::MAXIMUM_SIZE:
4190 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
4194 case Dali::Actor::Property::CLIPPING_MODE:
4196 value = mClippingMode;
4200 case Dali::DevelActor::Property::SIBLING_ORDER:
4202 value = static_cast<int>( GetSiblingOrder() );
4206 case Dali::DevelActor::Property::SCREEN_POSITION:
4208 value = GetCurrentScreenPosition();
4212 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
4214 value = mPositionUsesAnchorPoint;
4218 case Dali::Actor::Property::LAYOUT_DIRECTION:
4220 value = mLayoutDirection;
4224 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
4226 value = IsLayoutDirectionInherited();
4232 // Must be a scene-graph only property
4241 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
4243 bool valueSet = true;
4247 case Dali::Actor::Property::SIZE:
4249 value = GetCurrentSize();
4253 case Dali::Actor::Property::SIZE_WIDTH:
4255 value = GetCurrentSize().width;
4259 case Dali::Actor::Property::SIZE_HEIGHT:
4261 value = GetCurrentSize().height;
4265 case Dali::Actor::Property::SIZE_DEPTH:
4267 value = GetCurrentSize().depth;
4271 case Dali::Actor::Property::POSITION:
4273 value = GetCurrentPosition();
4277 case Dali::Actor::Property::POSITION_X:
4279 value = GetCurrentPosition().x;
4283 case Dali::Actor::Property::POSITION_Y:
4285 value = GetCurrentPosition().y;
4289 case Dali::Actor::Property::POSITION_Z:
4291 value = GetCurrentPosition().z;
4295 case Dali::Actor::Property::WORLD_POSITION:
4297 value = GetCurrentWorldPosition();
4301 case Dali::Actor::Property::WORLD_POSITION_X:
4303 value = GetCurrentWorldPosition().x;
4307 case Dali::Actor::Property::WORLD_POSITION_Y:
4309 value = GetCurrentWorldPosition().y;
4313 case Dali::Actor::Property::WORLD_POSITION_Z:
4315 value = GetCurrentWorldPosition().z;
4319 case Dali::Actor::Property::ORIENTATION:
4321 value = GetCurrentOrientation();
4325 case Dali::Actor::Property::WORLD_ORIENTATION:
4327 value = GetCurrentWorldOrientation();
4331 case Dali::Actor::Property::SCALE:
4333 value = GetCurrentScale();
4337 case Dali::Actor::Property::SCALE_X:
4339 value = GetCurrentScale().x;
4343 case Dali::Actor::Property::SCALE_Y:
4345 value = GetCurrentScale().y;
4349 case Dali::Actor::Property::SCALE_Z:
4351 value = GetCurrentScale().z;
4355 case Dali::Actor::Property::WORLD_SCALE:
4357 value = GetCurrentWorldScale();
4361 case Dali::Actor::Property::COLOR:
4363 value = GetCurrentColor();
4367 case Dali::Actor::Property::COLOR_RED:
4369 value = GetCurrentColor().r;
4373 case Dali::Actor::Property::COLOR_GREEN:
4375 value = GetCurrentColor().g;
4379 case Dali::Actor::Property::COLOR_BLUE:
4381 value = GetCurrentColor().b;
4385 case Dali::Actor::Property::COLOR_ALPHA:
4386 case Dali::DevelActor::Property::OPACITY:
4388 value = GetCurrentColor().a;
4392 case Dali::Actor::Property::WORLD_COLOR:
4394 value = GetCurrentWorldColor();
4398 case Dali::Actor::Property::WORLD_MATRIX:
4400 value = GetCurrentWorldMatrix();
4404 case Dali::Actor::Property::VISIBLE:
4406 value = IsVisible();
4412 // Must be an event-side only property
4421 void Actor::EnsureRelayoutData()
4423 // Assign relayout data.
4424 if( !mRelayoutData )
4426 mRelayoutData = new RelayoutData();
4430 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
4432 // Check if actor is dependent on parent
4433 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4435 if( ( dimension & ( 1 << i ) ) )
4437 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4438 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4448 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4450 // Check if actor is dependent on children
4451 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4453 if( ( dimension & ( 1 << i ) ) )
4455 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4456 switch( resizePolicy )
4458 case ResizePolicy::FIT_TO_CHILDREN:
4459 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4475 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4477 return Actor::RelayoutDependentOnChildren( dimension );
4480 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4482 // Check each possible dimension and see if it is dependent on the input one
4483 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4485 if( dimension & ( 1 << i ) )
4487 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4494 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4496 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4498 if( dimension & ( 1 << i ) )
4500 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4505 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4507 // If more than one dimension is requested, just return the first one found
4508 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4510 if( ( dimension & ( 1 << i ) ) )
4512 return mRelayoutData->negotiatedDimensions[ i ];
4516 return 0.0f; // Default
4519 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4521 EnsureRelayoutData();
4523 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4525 if( dimension & ( 1 << i ) )
4527 mRelayoutData->dimensionPadding[ i ] = padding;
4532 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4534 if ( mRelayoutData )
4536 // If more than one dimension is requested, just return the first one found
4537 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4539 if( ( dimension & ( 1 << i ) ) )
4541 return mRelayoutData->dimensionPadding[ i ];
4546 return GetDefaultDimensionPadding();
4549 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4551 EnsureRelayoutData();
4553 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4555 if( dimension & ( 1 << i ) )
4557 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4562 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4564 if ( mRelayoutData )
4566 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4568 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4578 float Actor::GetHeightForWidthBase( float width )
4580 float height = 0.0f;
4582 const Vector3 naturalSize = GetNaturalSize();
4583 if( naturalSize.width > 0.0f )
4585 height = naturalSize.height * width / naturalSize.width;
4587 else // we treat 0 as 1:1 aspect ratio
4595 float Actor::GetWidthForHeightBase( float height )
4599 const Vector3 naturalSize = GetNaturalSize();
4600 if( naturalSize.height > 0.0f )
4602 width = naturalSize.width * height / naturalSize.height;
4604 else // we treat 0 as 1:1 aspect ratio
4612 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4614 // Fill to parent, taking size mode factor into account
4615 switch( child.GetResizePolicy( dimension ) )
4617 case ResizePolicy::FILL_TO_PARENT:
4619 return GetLatestSize( dimension );
4622 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4624 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4627 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4629 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4634 return GetLatestSize( dimension );
4639 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4641 // Can be overridden in derived class
4642 return CalculateChildSizeBase( child, dimension );
4645 float Actor::GetHeightForWidth( float width )
4647 // Can be overridden in derived class
4648 return GetHeightForWidthBase( width );
4651 float Actor::GetWidthForHeight( float height )
4653 // Can be overridden in derived class
4654 return GetWidthForHeightBase( height );
4657 float Actor::GetLatestSize( Dimension::Type dimension ) const
4659 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4662 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4664 Vector2 padding = GetPadding( dimension );
4666 return GetLatestSize( dimension ) + padding.x + padding.y;
4669 float Actor::NegotiateFromParent( Dimension::Type dimension )
4671 Actor* parent = GetParent();
4674 Vector2 padding( GetPadding( dimension ) );
4675 Vector2 parentPadding( parent->GetPadding( dimension ) );
4676 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4682 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4684 float maxDimensionPoint = 0.0f;
4686 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4688 ActorPtr child = GetChildAt( i );
4690 if( !child->RelayoutDependentOnParent( dimension ) )
4692 // Calculate the min and max points that the children range across
4693 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4694 float dimensionSize = child->GetRelayoutSize( dimension );
4695 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4699 return maxDimensionPoint;
4702 float Actor::GetSize( Dimension::Type dimension ) const
4704 return GetDimensionValue( mTargetSize, dimension );
4707 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4709 return GetDimensionValue( GetNaturalSize(), dimension );
4712 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4714 switch( GetResizePolicy( dimension ) )
4716 case ResizePolicy::USE_NATURAL_SIZE:
4718 return GetNaturalSize( dimension );
4721 case ResizePolicy::FIXED:
4723 return GetDimensionValue( GetPreferredSize(), dimension );
4726 case ResizePolicy::USE_ASSIGNED_SIZE:
4728 return GetDimensionValue( maximumSize, dimension );
4731 case ResizePolicy::FILL_TO_PARENT:
4732 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4733 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4735 return NegotiateFromParent( dimension );
4738 case ResizePolicy::FIT_TO_CHILDREN:
4740 return NegotiateFromChildren( dimension );
4743 case ResizePolicy::DIMENSION_DEPENDENCY:
4745 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4748 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4750 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4753 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4755 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4767 return 0.0f; // Default
4770 float Actor::ClampDimension( float size, Dimension::Type dimension )
4772 const float minSize = GetMinimumSize( dimension );
4773 const float maxSize = GetMaximumSize( dimension );
4775 return std::max( minSize, std::min( size, maxSize ) );
4778 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4780 // Check if it needs to be negotiated
4781 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4783 // Check that we havn't gotten into an infinite loop
4784 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4785 bool recursionFound = false;
4786 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4788 if( *it == searchActor )
4790 recursionFound = true;
4795 if( !recursionFound )
4797 // Record the path that we have taken
4798 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4800 // Dimension dependency check
4801 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4803 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4805 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4807 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4811 // Parent dependency check
4812 Actor* parent = GetParent();
4813 if( parent && RelayoutDependentOnParent( dimension ) )
4815 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4818 // Children dependency check
4819 if( RelayoutDependentOnChildren( dimension ) )
4821 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4823 ActorPtr child = GetChildAt( i );
4825 // Only relayout child first if it is not dependent on this actor
4826 if( !child->RelayoutDependentOnParent( dimension ) )
4828 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4833 // For deriving classes
4834 OnCalculateRelayoutSize( dimension );
4836 // All dependencies checked, calculate the size and set negotiated flag
4837 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4839 SetNegotiatedDimension( newSize, dimension );
4840 SetLayoutNegotiated( true, dimension );
4842 // For deriving classes
4843 OnLayoutNegotiated( newSize, dimension );
4845 // This actor has been successfully processed, pop it off the recursion stack
4846 recursionStack.pop_back();
4850 // TODO: Break infinite loop
4851 SetLayoutNegotiated( true, dimension );
4856 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4858 // Negotiate all dimensions that require it
4859 ActorDimensionStack recursionStack;
4861 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4863 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4866 NegotiateDimension( dimension, allocatedSize, recursionStack );
4870 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4872 switch( mRelayoutData->sizeSetPolicy )
4874 case SizeScalePolicy::USE_SIZE_SET:
4879 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4881 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4882 const Vector3 naturalSize = GetNaturalSize();
4883 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4885 const float sizeRatio = size.width / size.height;
4886 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4888 if( naturalSizeRatio < sizeRatio )
4890 return Vector2( naturalSizeRatio * size.height, size.height );
4892 else if( naturalSizeRatio > sizeRatio )
4894 return Vector2( size.width, size.width / naturalSizeRatio );
4905 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4907 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4908 const Vector3 naturalSize = GetNaturalSize();
4909 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4911 const float sizeRatio = size.width / size.height;
4912 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4914 if( naturalSizeRatio < sizeRatio )
4916 return Vector2( size.width, size.width / naturalSizeRatio );
4918 else if( naturalSizeRatio > sizeRatio )
4920 return Vector2( naturalSizeRatio * size.height, size.height );
4939 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4941 // Do the set actor size
4942 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4944 // Adjust for size set policy
4945 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4947 // Lock the flag to stop recursive relayouts on set size
4948 mRelayoutData->insideRelayout = true;
4949 SetSize( negotiatedSize );
4950 mRelayoutData->insideRelayout = false;
4952 // Clear flags for all dimensions
4953 SetLayoutDirty( false );
4955 // Give deriving classes a chance to respond
4956 OnRelayout( negotiatedSize, container );
4958 if( !mOnRelayoutSignal.Empty() )
4960 Dali::Actor handle( this );
4961 mOnRelayoutSignal.Emit( handle );
4965 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4967 // Force a size negotiation for actors that has assigned size during relayout
4968 // This is required as otherwise the flags that force a relayout will not
4969 // necessarilly be set. This will occur if the actor has already been laid out.
4970 // The dirty flags are then cleared. Then if the actor is added back into the
4971 // relayout container afterwards, the dirty flags would still be clear...
4972 // causing a relayout to be skipped. Here we force any actors added to the
4973 // container to be relayed out.
4974 DALI_LOG_TIMER_START( NegSizeTimer1 );
4976 if( GetUseAssignedSize(Dimension::WIDTH ) )
4978 SetLayoutNegotiated( false, Dimension::WIDTH );
4980 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4982 SetLayoutNegotiated( false, Dimension::HEIGHT );
4985 // Do the negotiation
4986 NegotiateDimensions( allocatedSize );
4988 // Set the actor size
4989 SetNegotiatedSize( container );
4991 // Negotiate down to children
4992 for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
4994 ActorPtr child = GetChildAt( i );
4996 // Forces children that have already been laid out to be relayed out
4997 // if they have assigned size during relayout.
4998 if( child->GetUseAssignedSize(Dimension::WIDTH) )
5000 child->SetLayoutNegotiated(false, Dimension::WIDTH);
5001 child->SetLayoutDirty(true, Dimension::WIDTH);
5004 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
5006 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
5007 child->SetLayoutDirty(true, Dimension::HEIGHT);
5010 // Only relayout if required
5011 if( child->RelayoutRequired() )
5013 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
5016 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
5019 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
5023 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5025 if( dimension & ( 1 << i ) )
5027 mRelayoutData->useAssignedSize[ i ] = use;
5033 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
5035 if ( mRelayoutData )
5037 // If more than one dimension is requested, just return the first one found
5038 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5040 if( dimension & ( 1 << i ) )
5042 return mRelayoutData->useAssignedSize[ i ];
5050 void Actor::RelayoutRequest( Dimension::Type dimension )
5052 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
5053 if( relayoutController )
5055 Dali::Actor self( this );
5056 relayoutController->RequestRelayout( self, dimension );
5060 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
5064 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
5068 void Actor::SetPreferredSize( const Vector2& size )
5070 EnsureRelayoutData();
5072 if( size.width > 0.0f )
5074 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
5077 if( size.height > 0.0f )
5079 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
5082 mRelayoutData->preferredSize = size;
5087 Vector2 Actor::GetPreferredSize() const
5089 if ( mRelayoutData )
5091 return Vector2( mRelayoutData->preferredSize );
5094 return GetDefaultPreferredSize();
5097 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
5099 EnsureRelayoutData();
5101 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5103 if( dimension & ( 1 << i ) )
5105 mRelayoutData->minimumSize[ i ] = size;
5112 float Actor::GetMinimumSize( Dimension::Type dimension ) const
5114 if ( mRelayoutData )
5116 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5118 if( dimension & ( 1 << i ) )
5120 return mRelayoutData->minimumSize[ i ];
5125 return 0.0f; // Default
5128 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
5130 EnsureRelayoutData();
5132 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5134 if( dimension & ( 1 << i ) )
5136 mRelayoutData->maximumSize[ i ] = size;
5143 float Actor::GetMaximumSize( Dimension::Type dimension ) const
5145 if ( mRelayoutData )
5147 for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
5149 if( dimension & ( 1 << i ) )
5151 return mRelayoutData->maximumSize[ i ];
5156 return FLT_MAX; // Default
5159 Object* Actor::GetParentObject() const
5164 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
5166 if( mVisible != visible )
5168 if( sendMessage == SendMessage::TRUE && NULL != mNode )
5170 // mNode is being used in a separate thread; queue a message to set the value & base value
5171 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
5176 // Emit the signal on this actor and all its children
5177 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
5181 void Actor::SetSiblingOrder( unsigned int order )
5185 ActorContainer& siblings = *(mParent->mChildren);
5186 unsigned int currentOrder = GetSiblingOrder();
5188 if( order != currentOrder )
5194 else if( order < siblings.size() -1 )
5196 if( order > currentOrder )
5198 RaiseAbove( *siblings[order] );
5202 LowerBelow( *siblings[order] );
5213 unsigned int Actor::GetSiblingOrder() const
5215 unsigned int order = 0;
5219 ActorContainer& siblings = *(mParent->mChildren);
5220 for( size_t i=0; i<siblings.size(); ++i )
5222 if( siblings[i] == this )
5233 void Actor::RequestRebuildDepthTree()
5237 StagePtr stage = Stage::GetCurrent();
5240 stage->RequestRebuildDepthTree();
5249 ActorContainer& siblings = *(mParent->mChildren);
5250 if( siblings.back() != this ) // If not already at end
5252 for( size_t i=0; i<siblings.size(); ++i )
5254 if( siblings[i] == this )
5257 ActorPtr next = siblings[i+1];
5258 siblings[i+1] = this;
5264 RequestRebuildDepthTree();
5268 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5276 ActorContainer& siblings = *(mParent->mChildren);
5277 if( siblings.front() != this ) // If not already at beginning
5279 for( size_t i=1; i<siblings.size(); ++i )
5281 if( siblings[i] == this )
5283 // Swap with previous
5284 ActorPtr previous = siblings[i-1];
5285 siblings[i-1] = this;
5286 siblings[i] = previous;
5291 RequestRebuildDepthTree();
5295 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5299 void Actor::RaiseToTop()
5303 ActorContainer& siblings = *(mParent->mChildren);
5304 if( siblings.back() != this ) // If not already at end
5306 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5307 if( iter != siblings.end() )
5309 siblings.erase(iter);
5310 siblings.push_back(ActorPtr(this));
5313 RequestRebuildDepthTree();
5317 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5321 void Actor::LowerToBottom()
5325 ActorContainer& siblings = *(mParent->mChildren);
5326 if( siblings.front() != this ) // If not already at bottom,
5328 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5330 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
5331 if( iter != siblings.end() )
5333 siblings.erase(iter);
5334 siblings.insert(siblings.begin(), thisPtr);
5337 RequestRebuildDepthTree();
5341 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5345 void Actor::RaiseAbove( Internal::Actor& target )
5349 ActorContainer& siblings = *(mParent->mChildren);
5350 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
5352 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5354 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5355 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5356 if( thisIter < targetIter )
5358 siblings.erase(thisIter);
5359 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
5360 // invalidate thisIter)
5361 targetIter = std::find( siblings.begin(), siblings.end(), &target );
5363 siblings.insert(targetIter, thisPtr);
5365 RequestRebuildDepthTree();
5370 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5374 void Actor::LowerBelow( Internal::Actor& target )
5378 ActorContainer& siblings = *(mParent->mChildren);
5379 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
5381 ActorPtr thisPtr(this); // ensure this actor remains referenced.
5383 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
5384 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
5386 if( thisIter > targetIter )
5388 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
5389 siblings.insert(targetIter, thisPtr);
5391 RequestRebuildDepthTree();
5396 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
5400 void Actor::SetInheritLayoutDirection( bool inherit )
5402 if( mInheritLayoutDirection != inherit )
5404 mInheritLayoutDirection = inherit;
5406 if( inherit && mParent )
5408 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5413 bool Actor::IsLayoutDirectionInherited() const
5415 return mInheritLayoutDirection;
5418 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5420 if( actor && ( actor->mInheritLayoutDirection || set ) )
5422 if( actor->mLayoutDirection != direction)
5424 actor->mLayoutDirection = direction;
5425 actor->EmitLayoutDirectionChangedSignal( direction );
5426 actor->RelayoutRequest();
5429 if( actor->GetChildCount() > 0 )
5431 ActorContainer& children = actor->GetChildrenInternal();
5432 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5434 InheritLayoutDirectionRecursively( *iter, direction );
5440 } // namespace Internal