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/common/scene-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/animation/constraint-impl.h>
48 #include <dali/internal/event/common/projection.h>
49 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
50 #include <dali/internal/update/common/animatable-property.h>
51 #include <dali/internal/update/nodes/node-messages.h>
52 #include <dali/internal/update/nodes/node-declarations.h>
53 #include <dali/internal/update/animation/scene-graph-constraint.h>
54 #include <dali/internal/event/events/actor-gesture-data.h>
55 #include <dali/internal/common/message.h>
56 #include <dali/integration-api/debug.h>
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::PropertyBase;
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
64 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
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( uint32_t 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( "reservedProperty01", STRING, true, false, false, Dali::Actor::Property::RESERVED_PROPERTY_01 ) // This property was removed, but to keep binary compatibility and TypeRegister test app, remain it here.
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( "culled", BOOLEAN, false, false, true, Dali::DevelActor::Property::CULLED )
217 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
221 const char* const SIGNAL_TOUCHED = "touched";
222 const char* const SIGNAL_HOVERED = "hovered";
223 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
224 const char* const SIGNAL_ON_STAGE = "onStage";
225 const char* const SIGNAL_OFF_STAGE = "offStage";
226 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
227 const char* const SIGNAL_TOUCH = "touch";
228 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
229 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
230 const char* const SIGNAL_CHILD_ADDED = "childAdded";
231 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
235 const char* const ACTION_SHOW = "show";
236 const char* const ACTION_HIDE = "hide";
238 BaseHandle CreateActor()
240 return Dali::Actor::New();
243 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
245 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
246 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
247 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
248 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
249 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
250 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
251 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
252 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
253 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
254 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
255 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
257 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
258 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
263 const Vector3& value;
266 DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT )
267 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT )
268 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER )
269 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT )
270 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT )
271 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER )
272 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT )
273 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT )
274 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER )
275 DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT )
276 DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT )
278 DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE )
279 DALI_ENUM_TO_STRING( USE_OWN_COLOR )
280 DALI_ENUM_TO_STRING( USE_PARENT_COLOR )
281 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR )
282 DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA )
283 DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE )
285 DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE )
286 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL )
287 DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D )
288 DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE )
290 DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY )
291 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED )
292 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE )
293 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT )
294 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT )
295 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT )
296 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN )
297 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY )
298 DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE )
299 DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY )
301 DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY )
302 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET )
303 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
304 DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
305 DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
307 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
308 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
309 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
310 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
312 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
313 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
314 DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
315 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
317 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
319 for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
321 uint32_t sizeIgnored = 0;
322 if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
324 anchor = ANCHOR_CONSTANT_TABLE[ i ].value;
331 inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin )
333 // Values are the same so just use the same table as anchor-point
334 return GetAnchorPointConstant( value, parentOrigin );
338 * @brief Extract a given dimension from a Vector2
340 * @param[in] values The values to extract from
341 * @param[in] dimension The dimension to extract
342 * @return Return the value for the dimension
344 float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
348 case Dimension::WIDTH:
352 case Dimension::HEIGHT:
354 return values.height;
365 * @brief Extract a given dimension from a Vector3
367 * @param[in] values The values to extract from
368 * @param[in] dimension The dimension to extract
369 * @return Return the value for the dimension
371 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
373 return GetDimensionValue( values.GetVectorXY(), dimension );
377 * @brief Recursively emits the visibility-changed-signal on the actor tree.
378 * @param[in] actor The actor to emit the signal on
379 * @param[in] visible The new visibility of the actor
380 * @param[in] type Whether the actor's visible property has changed or a parent's
382 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
386 actor->EmitVisibilityChangedSignal( visible, type );
388 if( actor->GetChildCount() > 0 )
390 ActorContainer& children = actor->GetChildrenInternal();
391 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
393 EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
399 } // unnamed namespace
401 ActorPtr Actor::New()
403 // pass a reference to actor, actor does not own its node
404 ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
406 // Second-phase construction
412 const SceneGraph::Node* Actor::CreateNode()
414 // create node. Nodes are owned by the update manager
415 SceneGraph::Node* node = SceneGraph::Node::New();
416 OwnerPointer< SceneGraph::Node > transferOwnership( node );
417 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
418 AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
423 const std::string& Actor::GetName() const
428 void Actor::SetName( const std::string& name )
432 // ATTENTION: string for debug purposes is not thread safe.
433 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
436 uint32_t Actor::GetId() const
438 return GetNode().GetId();
441 bool Actor::OnStage() const
446 Dali::Layer Actor::GetLayer()
450 // Short-circuit for Layer derived actors
453 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
456 // Find the immediate Layer parent
457 for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
459 if( parent->IsLayer() )
461 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
468 void Actor::Add( Actor& child )
470 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
471 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
475 mChildren = new ActorContainer;
478 Actor* const oldParent( child.mParent );
480 // child might already be ours
481 if( this != oldParent )
483 // if we already have parent, unparent us first
486 oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
488 // Old parent may need to readjust to missing child
489 if( oldParent->RelayoutDependentOnChildren() )
491 oldParent->RelayoutRequest();
495 // Guard against Add() during previous OnChildRemove callback
498 // Do this first, since user callbacks from within SetParent() may need to remove child
499 mChildren->push_back( ActorPtr( &child ) );
501 // SetParent asserts that child can be added
502 child.SetParent( this );
504 // Notification for derived classes
506 EmitChildAddedSignal( child );
508 InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
510 // Only put in a relayout request if there is a suitable dependency
511 if( RelayoutDependentOnChildren() )
519 void Actor::Remove( Actor& child )
521 if( (this == &child) || (!mChildren) )
523 // no children or removing itself
529 // Find the child in mChildren, and unparent it
530 ActorIter end = mChildren->end();
531 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
533 ActorPtr actor = (*iter);
535 if( actor.Get() == &child )
537 // Keep handle for OnChildRemove notification
540 // Do this first, since user callbacks from within SetParent() may need to add the child
541 mChildren->erase( iter );
543 DALI_ASSERT_DEBUG( actor->GetParent() == this );
544 actor->SetParent( NULL );
552 // Only put in a relayout request if there is a suitable dependency
553 if( RelayoutDependentOnChildren() )
559 // Notification for derived classes
560 OnChildRemove( child );
561 EmitChildRemovedSignal( child );
564 void Actor::Unparent()
568 // Remove this actor from the parent. The remove will put a relayout request in for
569 // the parent if required
570 mParent->Remove( *this );
571 // mParent is now NULL!
575 uint32_t Actor::GetChildCount() const
577 return ( NULL != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
580 ActorPtr Actor::GetChildAt( uint32_t index ) const
582 DALI_ASSERT_ALWAYS( index < GetChildCount() );
584 return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
587 ActorPtr Actor::FindChildByName( const std::string& actorName )
590 if( actorName == mName )
596 ActorIter end = mChildren->end();
597 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
599 child = (*iter)->FindChildByName( actorName );
610 ActorPtr Actor::FindChildById( const uint32_t id )
619 ActorIter end = mChildren->end();
620 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
622 child = (*iter)->FindChildById( id );
633 void Actor::SetParentOrigin( const Vector3& origin )
635 // node is being used in a separate thread; queue a message to set the value & base value
636 SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
638 // Cache for event-thread access
641 // not allocated, check if different from default
642 if( ParentOrigin::DEFAULT != origin )
644 mParentOrigin = new Vector3( origin );
649 // check if different from current costs more than just set
650 *mParentOrigin = origin;
654 void Actor::SetParentOriginX( float x )
656 const Vector3& current = GetCurrentParentOrigin();
658 SetParentOrigin( Vector3( x, current.y, current.z ) );
661 void Actor::SetParentOriginY( float y )
663 const Vector3& current = GetCurrentParentOrigin();
665 SetParentOrigin( Vector3( current.x, y, current.z ) );
668 void Actor::SetParentOriginZ( float z )
670 const Vector3& current = GetCurrentParentOrigin();
672 SetParentOrigin( Vector3( current.x, current.y, z ) );
675 const Vector3& Actor::GetCurrentParentOrigin() const
677 // Cached for event-thread access
678 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
681 void Actor::SetAnchorPoint( const Vector3& anchor )
683 // node is being used in a separate thread; queue a message to set the value & base value
684 SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
686 // Cache for event-thread access
689 // not allocated, check if different from default
690 if( AnchorPoint::DEFAULT != anchor )
692 mAnchorPoint = new Vector3( anchor );
697 // check if different from current costs more than just set
698 *mAnchorPoint = anchor;
702 void Actor::SetAnchorPointX( float x )
704 const Vector3& current = GetCurrentAnchorPoint();
706 SetAnchorPoint( Vector3( x, current.y, current.z ) );
709 void Actor::SetAnchorPointY( float y )
711 const Vector3& current = GetCurrentAnchorPoint();
713 SetAnchorPoint( Vector3( current.x, y, current.z ) );
716 void Actor::SetAnchorPointZ( float z )
718 const Vector3& current = GetCurrentAnchorPoint();
720 SetAnchorPoint( Vector3( current.x, current.y, z ) );
723 const Vector3& Actor::GetCurrentAnchorPoint() const
725 // Cached for event-thread access
726 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
729 void Actor::SetPosition( float x, float y )
731 SetPosition( Vector3( x, y, 0.0f ) );
734 void Actor::SetPosition( float x, float y, float z )
736 SetPosition( Vector3( x, y, z ) );
739 void Actor::SetPosition( const Vector3& position )
741 mTargetPosition = position;
743 // node is being used in a separate thread; queue a message to set the value & base value
744 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
747 void Actor::SetX( float x )
749 mTargetPosition.x = x;
751 // node is being used in a separate thread; queue a message to set the value & base value
752 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
755 void Actor::SetY( float y )
757 mTargetPosition.y = y;
759 // node is being used in a separate thread; queue a message to set the value & base value
760 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
763 void Actor::SetZ( float z )
765 mTargetPosition.z = z;
767 // node is being used in a separate thread; queue a message to set the value & base value
768 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
771 void Actor::TranslateBy( const Vector3& distance )
773 mTargetPosition += distance;
775 // node is being used in a separate thread; queue a message to set the value & base value
776 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
779 const Vector3& Actor::GetCurrentPosition() const
781 // node is being used in a separate thread; copy the value from the previous update
782 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
785 const Vector3& Actor::GetTargetPosition() const
787 return mTargetPosition;
790 const Vector3& Actor::GetCurrentWorldPosition() const
792 // node is being used in a separate thread; copy the value from the previous update
793 return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
796 const Vector2 Actor::GetCurrentScreenPosition() const
798 if( mScene && OnStage() )
800 Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
801 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
802 worldPosition -= cameraPosition;
804 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
805 Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
806 Vector3 halfActorSize( actorSize * 0.5f );
807 Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
809 return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
810 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
813 return Vector2::ZERO;
816 void Actor::SetInheritPosition( bool inherit )
818 if( mInheritPosition != inherit )
820 // non animatable so keep local copy
821 mInheritPosition = inherit;
822 SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
826 bool Actor::IsPositionInherited() const
828 return mInheritPosition;
831 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
833 Vector3 normalizedAxis( axis.x, axis.y, axis.z );
834 normalizedAxis.Normalize();
836 Quaternion orientation( angle, normalizedAxis );
838 SetOrientation( orientation );
841 void Actor::SetOrientation( const Quaternion& orientation )
843 mTargetOrientation = orientation;
845 // node is being used in a separate thread; queue a message to set the value & base value
846 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
849 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
851 RotateBy( Quaternion(angle, axis) );
854 void Actor::RotateBy( const Quaternion& relativeRotation )
856 mTargetOrientation *= Quaternion( relativeRotation );
858 // node is being used in a separate thread; queue a message to set the value & base value
859 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
862 const Quaternion& Actor::GetCurrentOrientation() const
864 // node is being used in a separate thread; copy the value from the previous update
865 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
868 const Quaternion& Actor::GetCurrentWorldOrientation() const
870 // node is being used in a separate thread; copy the value from the previous update
871 return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
874 void Actor::SetScale( float scale )
876 SetScale( Vector3( scale, scale, scale ) );
879 void Actor::SetScale( float x, float y, float z )
881 SetScale( Vector3( x, y, z ) );
884 void Actor::SetScale( const Vector3& scale )
886 mTargetScale = scale;
888 // node is being used in a separate thread; queue a message to set the value & base value
889 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
892 void Actor::SetScaleX( float x )
896 // node is being used in a separate thread; queue a message to set the value & base value
897 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
900 void Actor::SetScaleY( float y )
904 // node is being used in a separate thread; queue a message to set the value & base value
905 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
908 void Actor::SetScaleZ( float z )
912 // node is being used in a separate thread; queue a message to set the value & base value
913 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
916 void Actor::ScaleBy(const Vector3& relativeScale)
918 mTargetScale *= relativeScale;
920 // node is being used in a separate thread; queue a message to set the value & base value
921 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
924 const Vector3& Actor::GetCurrentScale() const
926 // node is being used in a separate thread; copy the value from the previous update
927 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
930 const Vector3& Actor::GetCurrentWorldScale() const
932 // node is being used in a separate thread; copy the value from the previous update
933 return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
936 void Actor::SetInheritScale( bool inherit )
938 if( mInheritScale != inherit )
940 // non animatable so keep local copy
941 mInheritScale = inherit;
942 // node is being used in a separate thread; queue a message to set the value
943 SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
947 bool Actor::IsScaleInherited() const
949 return mInheritScale;
952 Matrix Actor::GetCurrentWorldMatrix() const
954 return GetNode().GetWorldMatrix(0);
957 void Actor::SetVisible( bool visible )
959 SetVisibleInternal( visible, SendMessage::TRUE );
962 bool Actor::IsVisible() const
964 // node is being used in a separate thread; copy the value from the previous update
965 return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
968 void Actor::SetOpacity( float opacity )
970 mTargetColor.a = opacity;
972 // node is being used in a separate thread; queue a message to set the value & base value
973 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
976 float Actor::GetCurrentOpacity() const
978 // node is being used in a separate thread; copy the value from the previous update
979 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
982 ClippingMode::Type Actor::GetClippingMode() const
984 return mClippingMode;
987 uint32_t Actor::GetSortingDepth()
992 const Vector4& Actor::GetCurrentWorldColor() const
994 return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
997 void Actor::SetColor( const Vector4& color )
999 mTargetColor = color;
1001 // node is being used in a separate thread; queue a message to set the value & base value
1002 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
1005 void Actor::SetColorRed( float red )
1007 mTargetColor.r = red;
1009 // node is being used in a separate thread; queue a message to set the value & base value
1010 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
1013 void Actor::SetColorGreen( float green )
1015 mTargetColor.g = green;
1017 // node is being used in a separate thread; queue a message to set the value & base value
1018 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green );
1021 void Actor::SetColorBlue( float blue )
1023 mTargetColor.b = blue;
1025 // node is being used in a separate thread; queue a message to set the value & base value
1026 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1029 const Vector4& Actor::GetCurrentColor() const
1031 // node is being used in a separate thread; copy the value from the previous update
1032 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
1035 void Actor::SetInheritOrientation( bool inherit )
1037 if( mInheritOrientation != inherit )
1039 // non animatable so keep local copy
1040 mInheritOrientation = inherit;
1041 // node is being used in a separate thread; queue a message to set the value
1042 SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
1046 bool Actor::IsOrientationInherited() const
1048 return mInheritOrientation;
1051 void Actor::SetSizeModeFactor( const Vector3& factor )
1053 EnsureRelayoutData();
1055 mRelayoutData->sizeModeFactor = factor;
1058 const Vector3& Actor::GetSizeModeFactor() const
1060 if ( mRelayoutData )
1062 return mRelayoutData->sizeModeFactor;
1065 return GetDefaultSizeModeFactor();
1068 void Actor::SetColorMode( ColorMode colorMode )
1070 // non animatable so keep local copy
1071 mColorMode = colorMode;
1072 // node is being used in a separate thread; queue a message to set the value
1073 SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
1076 ColorMode Actor::GetColorMode() const
1078 // we have cached copy
1082 void Actor::SetSize( float width, float height )
1084 SetSize( Vector2( width, height ) );
1087 void Actor::SetSize( float width, float height, float depth )
1089 SetSize( Vector3( width, height, depth ) );
1092 void Actor::SetSize( const Vector2& size )
1094 SetSize( Vector3( size.width, size.height, 0.f ) );
1097 void Actor::SetSizeInternal( const Vector2& size )
1099 SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
1102 void Actor::SetSize( const Vector3& size )
1104 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1106 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
1107 SetPreferredSize( size.GetVectorXY() );
1111 SetSizeInternal( size );
1115 void Actor::SetSizeInternal( const Vector3& size )
1117 // dont allow recursive loop
1118 DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
1119 // 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
1120 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
1121 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
1122 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) )
1126 // node is being used in a separate thread; queue a message to set the value & base value
1127 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
1129 // Notification for derived classes
1130 mInsideOnSizeSet = true;
1131 OnSizeSet( mTargetSize );
1132 mInsideOnSizeSet = false;
1134 // Raise a relayout request if the flag is not locked
1135 if( mRelayoutData && !mRelayoutData->insideRelayout )
1142 void Actor::SetWidth( float width )
1144 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1146 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
1147 mRelayoutData->preferredSize.width = width;
1151 mTargetSize.width = width;
1153 // node is being used in a separate thread; queue a message to set the value & base value
1154 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
1160 void Actor::SetHeight( float height )
1162 if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1164 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1165 mRelayoutData->preferredSize.height = height;
1169 mTargetSize.height = height;
1171 // node is being used in a separate thread; queue a message to set the value & base value
1172 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1178 void Actor::SetDepth( float depth )
1180 mTargetSize.depth = depth;
1182 // node is being used in a separate thread; queue a message to set the value & base value
1183 SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1186 Vector3 Actor::GetTargetSize() const
1188 Vector3 size = mTargetSize;
1190 // Should return preferred size if size is fixed as set by SetSize
1191 if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1193 size.width = GetPreferredSize().width;
1195 if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1197 size.height = GetPreferredSize().height;
1203 const Vector3& Actor::GetCurrentSize() const
1205 // node is being used in a separate thread; copy the value from the previous update
1206 return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1209 Vector3 Actor::GetNaturalSize() const
1211 // It is up to deriving classes to return the appropriate natural size
1212 return Vector3( 0.0f, 0.0f, 0.0f );
1215 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1217 EnsureRelayoutData();
1219 ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH);
1220 ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT);
1222 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1224 if( dimension & ( 1 << i ) )
1226 if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
1228 mRelayoutData->useAssignedSize[ i ] = true;
1232 mRelayoutData->resizePolicies[ i ] = policy;
1233 mRelayoutData->useAssignedSize[ i ] = false;
1238 if( policy == ResizePolicy::DIMENSION_DEPENDENCY )
1240 if( dimension & Dimension::WIDTH )
1242 SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT );
1245 if( dimension & Dimension::HEIGHT )
1247 SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH );
1251 // If calling SetResizePolicy, assume we want relayout enabled
1252 SetRelayoutEnabled( true );
1254 // If the resize policy is set to be FIXED, the preferred size
1255 // should be overrided by the target size. Otherwise the target
1256 // size should be overrided by the preferred size.
1258 if( dimension & Dimension::WIDTH )
1260 if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1262 mRelayoutData->preferredSize.width = mTargetSize.width;
1264 else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1266 mTargetSize.width = mRelayoutData->preferredSize.width;
1270 if( dimension & Dimension::HEIGHT )
1272 if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED )
1274 mRelayoutData->preferredSize.height = mTargetSize.height;
1276 else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED )
1278 mTargetSize.height = mRelayoutData->preferredSize.height;
1282 OnSetResizePolicy( policy, dimension );
1284 // Trigger relayout on this control
1288 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1290 if ( mRelayoutData )
1292 // If more than one dimension is requested, just return the first one found
1293 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1295 if( ( dimension & ( 1 << i ) ) )
1297 if( mRelayoutData->useAssignedSize[ i ] )
1299 return ResizePolicy::USE_ASSIGNED_SIZE;
1303 return mRelayoutData->resizePolicies[ i ];
1309 return ResizePolicy::DEFAULT;
1312 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1314 EnsureRelayoutData();
1316 mRelayoutData->sizeSetPolicy = policy;
1319 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1321 if ( mRelayoutData )
1323 return mRelayoutData->sizeSetPolicy;
1326 return DEFAULT_SIZE_SCALE_POLICY;
1329 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1331 EnsureRelayoutData();
1333 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1335 if( dimension & ( 1 << i ) )
1337 mRelayoutData->dimensionDependencies[ i ] = dependency;
1342 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1344 if ( mRelayoutData )
1346 // If more than one dimension is requested, just return the first one found
1347 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1349 if( ( dimension & ( 1 << i ) ) )
1351 return mRelayoutData->dimensionDependencies[ i ];
1356 return Dimension::ALL_DIMENSIONS; // Default
1359 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1361 // If relayout data has not been allocated yet and the client is requesting
1362 // to disable it, do nothing
1363 if( mRelayoutData || relayoutEnabled )
1365 EnsureRelayoutData();
1367 DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1369 mRelayoutData->relayoutEnabled = relayoutEnabled;
1373 bool Actor::IsRelayoutEnabled() const
1375 // Assume that if relayout data has not been allocated yet then
1376 // relayout is disabled
1377 return mRelayoutData && mRelayoutData->relayoutEnabled;
1380 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1382 EnsureRelayoutData();
1384 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1386 if( dimension & ( 1 << i ) )
1388 mRelayoutData->dimensionDirty[ i ] = dirty;
1393 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1395 if ( mRelayoutData )
1397 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1399 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
1409 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1411 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1414 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1416 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1419 uint32_t Actor::AddRenderer( Renderer& renderer )
1423 mRenderers = new RendererContainer;
1426 uint32_t index = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1427 RendererPtr rendererPtr = RendererPtr( &renderer );
1428 mRenderers->push_back( rendererPtr );
1429 AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1433 uint32_t Actor::GetRendererCount() const
1435 uint32_t rendererCount(0);
1438 rendererCount = static_cast<uint32_t>( mRenderers->size() ); // 4,294,967,295 renderers per actor
1441 return rendererCount;
1444 RendererPtr Actor::GetRendererAt( uint32_t index )
1446 RendererPtr renderer;
1447 if( index < GetRendererCount() )
1449 renderer = ( *mRenderers )[ index ];
1455 void Actor::RemoveRenderer( Renderer& renderer )
1459 RendererIter end = mRenderers->end();
1460 for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1462 if( (*iter).Get() == &renderer )
1464 mRenderers->erase( iter );
1465 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1472 void Actor::RemoveRenderer( uint32_t index )
1474 if( index < GetRendererCount() )
1476 RendererPtr renderer = ( *mRenderers )[ index ];
1477 DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1478 mRenderers->erase( mRenderers->begin()+index );
1482 bool Actor::IsOverlay() const
1484 return ( DrawMode::OVERLAY_2D == mDrawMode );
1487 void Actor::SetDrawMode( DrawMode::Type drawMode )
1489 // this flag is not animatable so keep the value
1490 mDrawMode = drawMode;
1492 // node is being used in a separate thread; queue a message to set the value
1493 SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1496 DrawMode::Type Actor::GetDrawMode() const
1501 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1503 // only valid when on-stage
1504 if( mScene && OnStage() )
1506 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1508 Vector2 converted( screenX, screenY );
1510 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1511 uint32_t taskCount = taskList.GetTaskCount();
1512 for( uint32_t i = taskCount; i > 0; --i )
1514 RenderTaskPtr task = taskList.GetTask( i - 1 );
1515 if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1517 // found a task where this conversion was ok so return
1525 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1527 bool retval = false;
1528 // only valid when on-stage
1531 CameraActor* camera = renderTask.GetCameraActor();
1535 renderTask.GetViewport( viewport );
1537 // need to translate coordinates to render tasks coordinate space
1538 Vector2 converted( screenX, screenY );
1539 if( renderTask.TranslateCoordinates( converted ) )
1541 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1548 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1550 // Early-out if not on stage
1556 // Get the ModelView matrix
1558 Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix );
1560 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1561 Matrix invertedMvp( false/*don't init*/);
1562 Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
1563 bool success = invertedMvp.Invert();
1565 // Convert to GL coordinates
1566 Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
1571 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
1578 success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
1584 if( XyPlaneIntersect( nearPos, farPos, local ) )
1586 Vector3 size = GetCurrentSize();
1587 localX = local.x + size.x * 0.5f;
1588 localY = local.y + size.y * 0.5f;
1599 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1602 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1604 Mathematical Formulation
1606 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1608 ( p - c ) dot ( p - c ) = r^2
1610 Given a ray with a point of origin 'o', and a direction vector 'd':
1612 ray(t) = o + td, t >= 0
1614 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1616 (o + td - c ) dot ( o + td - c ) = r^2
1618 To solve for t we first expand the above into a more recognisable quadratic equation form
1620 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1629 B = 2( o - c ) dot d
1630 C = ( o - c ) dot ( o - c ) - r^2
1632 which can be solved using a standard quadratic formula.
1634 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1636 Practical Simplification
1638 In a renderer, we often differentiate between world space and object space. In the object space
1639 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1640 into object space, the mathematical solution presented above can be simplified significantly.
1642 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1646 and we can find the t at which the (transformed) ray intersects the sphere by
1648 ( o + td ) dot ( o + td ) = r^2
1650 According to the reasoning above, we expand the above quadratic equation into the general form
1654 which now has coefficients:
1661 // Early-out if not on stage
1667 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1669 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1670 const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) );
1671 Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z );
1673 // Compute the radius is not needed, square radius it's enough.
1674 const Vector3& size( GetNode().GetSize( bufferIndex ) );
1676 // Scale the sphere.
1677 const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) );
1679 const float width = size.width * scale.width;
1680 const float height = size.height * scale.height;
1682 float squareSphereRadius = 0.5f * ( width * width + height * height );
1684 float a = rayDir.Dot( rayDir ); // a
1685 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1686 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1688 return ( b2 * b2 - a * c ) >= 0.f;
1691 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
1697 // Transforms the ray to the local reference system.
1698 // Calculate the inverse of Model matrix
1699 Matrix invModelMatrix( false/*don't init*/);
1701 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1702 invModelMatrix = GetNode().GetWorldMatrix(0);
1703 invModelMatrix.Invert();
1705 Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
1706 Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
1708 // Test with the actor's XY plane (Normal = 0 0 1 1).
1710 float a = -rayOriginLocal.z;
1711 float b = rayDirLocal.z;
1713 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1715 // Ray travels distance * rayDirLocal to intersect with plane.
1718 const Vector3& size = GetNode().GetSize( bufferIndex );
1720 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1721 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1723 // Test with the actor's geometry.
1724 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1731 void Actor::SetLeaveRequired( bool required )
1733 mLeaveRequired = required;
1736 bool Actor::GetLeaveRequired() const
1738 return mLeaveRequired;
1741 void Actor::SetKeyboardFocusable( bool focusable )
1743 mKeyboardFocusable = focusable;
1746 bool Actor::IsKeyboardFocusable() const
1748 return mKeyboardFocusable;
1751 bool Actor::GetTouchRequired() const
1753 return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
1756 bool Actor::GetHoverRequired() const
1758 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1761 bool Actor::GetWheelEventRequired() const
1763 return !mWheelEventSignal.Empty() || mDerivedRequiresWheelEvent;
1766 bool Actor::IsHittable() const
1768 return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
1771 ActorGestureData& Actor::GetGestureData()
1773 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1774 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1775 if( NULL == mGestureData )
1777 mGestureData = new ActorGestureData;
1779 return *mGestureData;
1782 bool Actor::IsGestureRequred( Gesture::Type type ) const
1784 return mGestureData && mGestureData->IsGestureRequred( type );
1787 bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
1789 bool consumed = false;
1791 if( !mTouchSignal.Empty() )
1793 Dali::Actor handle( this );
1794 consumed = mTouchSignal.Emit( handle, touch );
1797 if( !mTouchedSignal.Empty() )
1799 Dali::Actor handle( this );
1800 consumed |= mTouchedSignal.Emit( handle, event );
1805 // Notification for derived classes
1806 consumed = OnTouchEvent( event ); // TODO
1812 bool Actor::EmitHoverEventSignal( const HoverEvent& event )
1814 bool consumed = false;
1816 if( !mHoveredSignal.Empty() )
1818 Dali::Actor handle( this );
1819 consumed = mHoveredSignal.Emit( handle, event );
1824 // Notification for derived classes
1825 consumed = OnHoverEvent( event );
1831 bool Actor::EmitWheelEventSignal( const WheelEvent& event )
1833 bool consumed = false;
1835 if( !mWheelEventSignal.Empty() )
1837 Dali::Actor handle( this );
1838 consumed = mWheelEventSignal.Emit( handle, event );
1843 // Notification for derived classes
1844 consumed = OnWheelEvent( event );
1850 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1852 if( ! mVisibilityChangedSignal.Empty() )
1854 Dali::Actor handle( this );
1855 mVisibilityChangedSignal.Emit( handle, visible, type );
1859 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1861 if( ! mLayoutDirectionChangedSignal.Empty() )
1863 Dali::Actor handle( this );
1864 mLayoutDirectionChangedSignal.Emit( handle, type );
1868 void Actor::EmitChildAddedSignal( Actor& child )
1870 if( ! mChildAddedSignal.Empty() )
1872 Dali::Actor handle( &child );
1873 mChildAddedSignal.Emit( handle );
1877 void Actor::EmitChildRemovedSignal( Actor& child )
1879 if( ! mChildRemovedSignal.Empty() )
1881 Dali::Actor handle( &child );
1882 mChildRemovedSignal.Emit( handle );
1886 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1888 return mTouchedSignal;
1891 Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
1893 return mTouchSignal;
1896 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1898 return mHoveredSignal;
1901 Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal()
1903 return mWheelEventSignal;
1906 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1908 return mOnStageSignal;
1911 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1913 return mOffStageSignal;
1916 Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
1918 return mOnRelayoutSignal;
1921 DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
1923 return mVisibilityChangedSignal;
1926 Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
1928 return mLayoutDirectionChangedSignal;
1931 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1933 return mChildAddedSignal;
1936 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1938 return mChildRemovedSignal;
1941 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1943 return mChildOrderChangedSignal;
1946 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1948 bool connected( true );
1949 Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1951 if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1953 actor->TouchedSignal().Connect( tracker, functor );
1955 else if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1957 actor->HoveredSignal().Connect( tracker, functor );
1959 else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1961 actor->WheelEventSignal().Connect( tracker, functor );
1963 else if( 0 == signalName.compare( SIGNAL_ON_STAGE ) )
1965 actor->OnStageSignal().Connect( tracker, functor );
1967 else if( 0 == signalName.compare( SIGNAL_OFF_STAGE ) )
1969 actor->OffStageSignal().Connect( tracker, functor );
1971 else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1973 actor->OnRelayoutSignal().Connect( tracker, functor );
1975 else if( 0 == signalName.compare( SIGNAL_TOUCH ) )
1977 actor->TouchSignal().Connect( tracker, functor );
1979 else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
1981 actor->VisibilityChangedSignal().Connect( tracker, functor );
1983 else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
1985 actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
1987 else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
1989 actor->ChildAddedSignal().Connect( tracker, functor );
1991 else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
1993 actor->ChildRemovedSignal().Connect( tracker, functor );
1997 // signalName does not match any signal
2004 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
2010 mParentOrigin( NULL ),
2011 mAnchorPoint( NULL ),
2012 mRelayoutData( NULL ),
2013 mGestureData( NULL ),
2017 mWheelEventSignal(),
2020 mOnRelayoutSignal(),
2021 mVisibilityChangedSignal(),
2022 mLayoutDirectionChangedSignal(),
2023 mChildAddedSignal(),
2024 mChildRemovedSignal(),
2025 mChildOrderChangedSignal(),
2026 mTargetOrientation( Quaternion::IDENTITY ),
2027 mTargetColor( Color::WHITE ),
2028 mTargetSize( Vector3::ZERO ),
2029 mTargetPosition( Vector3::ZERO ),
2030 mTargetScale( Vector3::ONE ),
2034 mIsRoot( ROOT_LAYER == derivedType ),
2035 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2036 mIsOnStage( false ),
2038 mLeaveRequired( false ),
2039 mKeyboardFocusable( false ),
2040 mDerivedRequiresTouch( false ),
2041 mDerivedRequiresHover( false ),
2042 mDerivedRequiresWheelEvent( false ),
2043 mOnStageSignalled( false ),
2044 mInsideOnSizeSet( false ),
2045 mInheritPosition( true ),
2046 mInheritOrientation( true ),
2047 mInheritScale( true ),
2048 mPositionUsesAnchorPoint( true ),
2050 mInheritLayoutDirection( true ),
2051 mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
2052 mDrawMode( DrawMode::NORMAL ),
2053 mColorMode( Node::DEFAULT_COLOR_MODE ),
2054 mClippingMode( ClippingMode::DISABLED )
2058 void Actor::Initialize()
2062 GetEventThreadServices().RegisterObject( this );
2067 // Remove mParent pointers from children even if we're destroying core,
2068 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2071 ActorConstIter endIter = mChildren->end();
2072 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2074 (*iter)->SetParent( NULL );
2080 // Guard to allow handle destruction after Core has been destroyed
2081 if( EventThreadServices::IsCoreRunning() )
2083 // Root layer will destroy its node in its own destructor
2086 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2088 GetEventThreadServices().UnregisterObject( this );
2092 // Cleanup optional gesture data
2093 delete mGestureData;
2095 // Cleanup optional parent origin and anchor
2096 delete mParentOrigin;
2097 delete mAnchorPoint;
2099 // Delete optional relayout data
2100 delete mRelayoutData;
2103 void Actor::ConnectToStage( uint32_t parentDepth )
2105 // This container is used instead of walking the Actor hierarchy.
2106 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2107 ActorContainer connectionList;
2111 mScene->RequestRebuildDepthTree();
2114 // This stage is atomic i.e. not interrupted by user callbacks.
2115 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2117 // Notify applications about the newly connected actors.
2118 const ActorIter endIter = connectionList.end();
2119 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2121 (*iter)->NotifyStageConnection();
2127 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2129 DALI_ASSERT_ALWAYS( !OnStage() );
2132 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2134 ConnectToSceneGraph();
2136 // Notification for internal derived classes
2137 OnStageConnectionInternal();
2139 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2140 connectionList.push_back( ActorPtr( this ) );
2142 // Recursively connect children
2145 ActorConstIter endIter = mChildren->end();
2146 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2148 (*iter)->SetScene( *mScene );
2149 (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2155 * This method is called when the Actor is connected to the Stage.
2156 * The parent must have added its Node to the scene-graph.
2157 * The child must connect its Node to the parent's Node.
2158 * This is recursive; the child calls ConnectToStage() for its children.
2160 void Actor::ConnectToSceneGraph()
2162 DALI_ASSERT_DEBUG( mParent != NULL);
2164 // Reparent Node in next Update
2165 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2167 // Request relayout on all actors that are added to the scenegraph
2170 // Notification for Object::Observers
2174 void Actor::NotifyStageConnection()
2176 // Actors can be removed (in a callback), before the on-stage stage is reported.
2177 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2178 if( OnStage() && !mOnStageSignalled )
2180 // Notification for external (CustomActor) derived classes
2181 OnStageConnectionExternal( mDepth );
2183 if( !mOnStageSignal.Empty() )
2185 Dali::Actor handle( this );
2186 mOnStageSignal.Emit( handle );
2189 // Guard against Remove during callbacks
2192 mOnStageSignalled = true; // signal required next time Actor is removed
2197 void Actor::DisconnectFromStage()
2199 // This container is used instead of walking the Actor hierachy.
2200 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2201 ActorContainer disconnectionList;
2205 mScene->RequestRebuildDepthTree();
2208 // This stage is atomic i.e. not interrupted by user callbacks
2209 RecursiveDisconnectFromStage( disconnectionList );
2211 // Notify applications about the newly disconnected actors.
2212 const ActorIter endIter = disconnectionList.end();
2213 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2215 (*iter)->NotifyStageDisconnection();
2219 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2221 // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2224 // Recursively disconnect children
2227 ActorConstIter endIter = mChildren->end();
2228 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2230 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2234 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2235 disconnectionList.push_back( ActorPtr( this ) );
2237 // Notification for internal derived classes
2238 OnStageDisconnectionInternal();
2240 DisconnectFromSceneGraph();
2244 * This method is called by an actor or its parent, before a node removal message is sent.
2245 * This is recursive; the child calls DisconnectFromStage() for its children.
2247 void Actor::DisconnectFromSceneGraph()
2249 // Notification for Object::Observers
2250 OnSceneObjectRemove();
2253 void Actor::NotifyStageDisconnection()
2255 // Actors can be added (in a callback), before the off-stage state is reported.
2256 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2257 // only do this step if there is a stage, i.e. Core is not being shut down
2258 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2260 // Notification for external (CustomeActor) derived classes
2261 OnStageDisconnectionExternal();
2263 if( !mOffStageSignal.Empty() )
2265 Dali::Actor handle( this );
2266 mOffStageSignal.Emit( handle );
2269 // Guard against Add during callbacks
2272 mOnStageSignalled = false; // signal required next time Actor is added
2277 bool Actor::IsNodeConnected() const
2279 bool connected( false );
2283 if( IsRoot() || GetNode().GetParent() )
2292 // This method initiates traversal of the actor tree using depth-first
2293 // traversal to set a depth index based on traversal order. It sends a
2294 // single message to update manager to update all the actor's nodes in
2295 // this tree with the depth index. The sceneGraphNodeDepths vector's
2296 // elements are ordered by depth, and could be used to reduce sorting
2297 // in the update thread.
2298 void Actor::RebuildDepthTree()
2300 DALI_LOG_TIMER_START(depthTimer);
2302 // Vector of scene-graph nodes and their depths to send to UpdateManager
2303 // in a single message
2304 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2306 int32_t depthIndex = 1;
2307 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2309 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2310 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2313 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2315 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2316 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2318 // Create/add to children of this node
2321 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2323 Actor* childActor = (*it).Get();
2325 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2330 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2334 case Dali::Actor::Property::PARENT_ORIGIN:
2336 Property::Type type = property.GetType();
2337 if( type == Property::VECTOR3 )
2339 SetParentOrigin( property.Get< Vector3 >() );
2341 else if ( type == Property::STRING )
2343 std::string parentOriginString;
2344 property.Get( parentOriginString );
2345 Vector3 parentOrigin;
2346 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2348 SetParentOrigin( parentOrigin );
2354 case Dali::Actor::Property::PARENT_ORIGIN_X:
2356 SetParentOriginX( property.Get< float >() );
2360 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2362 SetParentOriginY( property.Get< float >() );
2366 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2368 SetParentOriginZ( property.Get< float >() );
2372 case Dali::Actor::Property::ANCHOR_POINT:
2374 Property::Type type = property.GetType();
2375 if( type == Property::VECTOR3 )
2377 SetAnchorPoint( property.Get< Vector3 >() );
2379 else if ( type == Property::STRING )
2381 std::string anchorPointString;
2382 property.Get( anchorPointString );
2384 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2386 SetAnchorPoint( anchor );
2392 case Dali::Actor::Property::ANCHOR_POINT_X:
2394 SetAnchorPointX( property.Get< float >() );
2398 case Dali::Actor::Property::ANCHOR_POINT_Y:
2400 SetAnchorPointY( property.Get< float >() );
2404 case Dali::Actor::Property::ANCHOR_POINT_Z:
2406 SetAnchorPointZ( property.Get< float >() );
2410 case Dali::Actor::Property::SIZE:
2412 SetSize( property.Get< Vector3 >() );
2416 case Dali::Actor::Property::SIZE_WIDTH:
2418 SetWidth( property.Get< float >() );
2422 case Dali::Actor::Property::SIZE_HEIGHT:
2424 SetHeight( property.Get< float >() );
2428 case Dali::Actor::Property::SIZE_DEPTH:
2430 SetDepth( property.Get< float >() );
2434 case Dali::Actor::Property::POSITION:
2436 SetPosition( property.Get< Vector3 >() );
2440 case Dali::Actor::Property::POSITION_X:
2442 SetX( property.Get< float >() );
2446 case Dali::Actor::Property::POSITION_Y:
2448 SetY( property.Get< float >() );
2452 case Dali::Actor::Property::POSITION_Z:
2454 SetZ( property.Get< float >() );
2458 case Dali::Actor::Property::ORIENTATION:
2460 SetOrientation( property.Get< Quaternion >() );
2464 case Dali::Actor::Property::SCALE:
2466 SetScale( property.Get< Vector3 >() );
2470 case Dali::Actor::Property::SCALE_X:
2472 SetScaleX( property.Get< float >() );
2476 case Dali::Actor::Property::SCALE_Y:
2478 SetScaleY( property.Get< float >() );
2482 case Dali::Actor::Property::SCALE_Z:
2484 SetScaleZ( property.Get< float >() );
2488 case Dali::Actor::Property::VISIBLE:
2490 SetVisible( property.Get< bool >() );
2494 case Dali::Actor::Property::COLOR:
2496 SetColor( property.Get< Vector4 >() );
2500 case Dali::Actor::Property::COLOR_RED:
2502 SetColorRed( property.Get< float >() );
2506 case Dali::Actor::Property::COLOR_GREEN:
2508 SetColorGreen( property.Get< float >() );
2512 case Dali::Actor::Property::COLOR_BLUE:
2514 SetColorBlue( property.Get< float >() );
2518 case Dali::Actor::Property::COLOR_ALPHA:
2519 case Dali::DevelActor::Property::OPACITY:
2522 if( property.Get( value ) )
2524 SetOpacity( value );
2529 case Dali::Actor::Property::NAME:
2531 SetName( property.Get< std::string >() );
2535 case Dali::Actor::Property::SENSITIVE:
2537 SetSensitive( property.Get< bool >() );
2541 case Dali::Actor::Property::LEAVE_REQUIRED:
2543 SetLeaveRequired( property.Get< bool >() );
2547 case Dali::Actor::Property::INHERIT_POSITION:
2549 SetInheritPosition( property.Get< bool >() );
2553 case Dali::Actor::Property::INHERIT_ORIENTATION:
2555 SetInheritOrientation( property.Get< bool >() );
2559 case Dali::Actor::Property::INHERIT_SCALE:
2561 SetInheritScale( property.Get< bool >() );
2565 case Dali::Actor::Property::COLOR_MODE:
2567 ColorMode mode = mColorMode;
2568 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2570 SetColorMode( mode );
2575 case Dali::Actor::Property::DRAW_MODE:
2577 DrawMode::Type mode = mDrawMode;
2578 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2580 SetDrawMode( mode );
2585 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2587 SetSizeModeFactor( property.Get< Vector3 >() );
2591 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2593 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2594 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2596 SetResizePolicy( type, Dimension::WIDTH );
2601 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2603 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2604 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2606 SetResizePolicy( type, Dimension::HEIGHT );
2611 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2613 SizeScalePolicy::Type type = GetSizeScalePolicy();
2614 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2616 SetSizeScalePolicy( type );
2621 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2623 if( property.Get< bool >() )
2625 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2630 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2632 if( property.Get< bool >() )
2634 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2639 case Dali::Actor::Property::PADDING:
2641 Vector4 padding = property.Get< Vector4 >();
2642 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2643 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2647 case Dali::Actor::Property::MINIMUM_SIZE:
2649 Vector2 size = property.Get< Vector2 >();
2650 SetMinimumSize( size.x, Dimension::WIDTH );
2651 SetMinimumSize( size.y, Dimension::HEIGHT );
2655 case Dali::Actor::Property::MAXIMUM_SIZE:
2657 Vector2 size = property.Get< Vector2 >();
2658 SetMaximumSize( size.x, Dimension::WIDTH );
2659 SetMaximumSize( size.y, Dimension::HEIGHT );
2663 case Dali::DevelActor::Property::SIBLING_ORDER:
2667 if( property.Get( value ) )
2669 SetSiblingOrder( value );
2674 case Dali::Actor::Property::CLIPPING_MODE:
2676 ClippingMode::Type convertedValue = mClippingMode;
2677 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2679 mClippingMode = convertedValue;
2680 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2685 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2688 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2690 mPositionUsesAnchorPoint = value;
2691 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2696 case Dali::Actor::Property::LAYOUT_DIRECTION:
2698 Dali::LayoutDirection::Type direction = mLayoutDirection;
2699 mInheritLayoutDirection = false;
2701 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2703 InheritLayoutDirectionRecursively( this, direction, true );
2708 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2711 if( property.Get( value ) )
2713 SetInheritLayoutDirection( value );
2720 // this can happen in the case of a non-animatable default property so just do nothing
2726 // TODO: This method needs to be removed
2727 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2729 switch( entry.GetType() )
2731 case Property::BOOLEAN:
2733 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2734 DALI_ASSERT_DEBUG( NULL != property );
2736 // property is being used in a separate thread; queue a message to set the property
2737 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2742 case Property::INTEGER:
2744 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2745 DALI_ASSERT_DEBUG( NULL != property );
2747 // property is being used in a separate thread; queue a message to set the property
2748 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2753 case Property::FLOAT:
2755 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2756 DALI_ASSERT_DEBUG( NULL != property );
2758 // property is being used in a separate thread; queue a message to set the property
2759 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2764 case Property::VECTOR2:
2766 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2767 DALI_ASSERT_DEBUG( NULL != property );
2769 // property is being used in a separate thread; queue a message to set the property
2770 if(entry.componentIndex == 0)
2772 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2774 else if(entry.componentIndex == 1)
2776 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2780 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2786 case Property::VECTOR3:
2788 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2789 DALI_ASSERT_DEBUG( NULL != property );
2791 // property is being used in a separate thread; queue a message to set the property
2792 if(entry.componentIndex == 0)
2794 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2796 else if(entry.componentIndex == 1)
2798 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2800 else if(entry.componentIndex == 2)
2802 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2806 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2812 case Property::VECTOR4:
2814 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2815 DALI_ASSERT_DEBUG( NULL != property );
2817 // property is being used in a separate thread; queue a message to set the property
2818 if(entry.componentIndex == 0)
2820 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2822 else if(entry.componentIndex == 1)
2824 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2826 else if(entry.componentIndex == 2)
2828 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2830 else if(entry.componentIndex == 3)
2832 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2836 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2842 case Property::ROTATION:
2844 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2845 DALI_ASSERT_DEBUG( NULL != property );
2847 // property is being used in a separate thread; queue a message to set the property
2848 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2853 case Property::MATRIX:
2855 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2856 DALI_ASSERT_DEBUG( NULL != property );
2858 // property is being used in a separate thread; queue a message to set the property
2859 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2864 case Property::MATRIX3:
2866 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2867 DALI_ASSERT_DEBUG( NULL != property );
2869 // property is being used in a separate thread; queue a message to set the property
2870 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2877 // nothing to do for other types
2882 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2884 Property::Value value;
2886 if( ! GetCachedPropertyValue( index, value ) )
2888 // If property value is not stored in the event-side, then it must be a scene-graph only property
2889 GetCurrentPropertyValue( index, value );
2895 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2897 Property::Value value;
2899 if( ! GetCurrentPropertyValue( index, value ) )
2901 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2902 GetCachedPropertyValue( index, value );
2908 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2910 switch( animationType )
2913 case Animation::BETWEEN:
2917 case Dali::Actor::Property::SIZE:
2919 if( value.Get( mTargetSize ) )
2921 // Notify deriving classes
2922 OnSizeAnimation( animation, mTargetSize );
2927 case Dali::Actor::Property::SIZE_WIDTH:
2929 if( value.Get( mTargetSize.width ) )
2931 // Notify deriving classes
2932 OnSizeAnimation( animation, mTargetSize );
2937 case Dali::Actor::Property::SIZE_HEIGHT:
2939 if( value.Get( mTargetSize.height ) )
2941 // Notify deriving classes
2942 OnSizeAnimation( animation, mTargetSize );
2947 case Dali::Actor::Property::SIZE_DEPTH:
2949 if( value.Get( mTargetSize.depth ) )
2951 // Notify deriving classes
2952 OnSizeAnimation( animation, mTargetSize );
2957 case Dali::Actor::Property::POSITION:
2959 value.Get( mTargetPosition );
2963 case Dali::Actor::Property::POSITION_X:
2965 value.Get( mTargetPosition.x );
2969 case Dali::Actor::Property::POSITION_Y:
2971 value.Get( mTargetPosition.y );
2975 case Dali::Actor::Property::POSITION_Z:
2977 value.Get( mTargetPosition.z );
2981 case Dali::Actor::Property::ORIENTATION:
2983 value.Get( mTargetOrientation );
2987 case Dali::Actor::Property::SCALE:
2989 value.Get( mTargetScale );
2993 case Dali::Actor::Property::SCALE_X:
2995 value.Get( mTargetScale.x );
2999 case Dali::Actor::Property::SCALE_Y:
3001 value.Get( mTargetScale.y );
3005 case Dali::Actor::Property::SCALE_Z:
3007 value.Get( mTargetScale.z );
3011 case Dali::Actor::Property::VISIBLE:
3013 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3017 case Dali::Actor::Property::COLOR:
3019 value.Get( mTargetColor );
3023 case Dali::Actor::Property::COLOR_RED:
3025 value.Get( mTargetColor.r );
3029 case Dali::Actor::Property::COLOR_GREEN:
3031 value.Get( mTargetColor.g );
3035 case Dali::Actor::Property::COLOR_BLUE:
3037 value.Get( mTargetColor.b );
3041 case Dali::Actor::Property::COLOR_ALPHA:
3042 case Dali::DevelActor::Property::OPACITY:
3044 value.Get( mTargetColor.a );
3050 // Not an animatable property. Do nothing.
3061 case Dali::Actor::Property::SIZE:
3063 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3065 // Notify deriving classes
3066 OnSizeAnimation( animation, mTargetSize );
3071 case Dali::Actor::Property::SIZE_WIDTH:
3073 if( AdjustValue< float >( mTargetSize.width, value ) )
3075 // Notify deriving classes
3076 OnSizeAnimation( animation, mTargetSize );
3081 case Dali::Actor::Property::SIZE_HEIGHT:
3083 if( AdjustValue< float >( mTargetSize.height, value ) )
3085 // Notify deriving classes
3086 OnSizeAnimation( animation, mTargetSize );
3091 case Dali::Actor::Property::SIZE_DEPTH:
3093 if( AdjustValue< float >( mTargetSize.depth, value ) )
3095 // Notify deriving classes
3096 OnSizeAnimation( animation, mTargetSize );
3101 case Dali::Actor::Property::POSITION:
3103 AdjustValue< Vector3 >( mTargetPosition, value );
3107 case Dali::Actor::Property::POSITION_X:
3109 AdjustValue< float >( mTargetPosition.x, value );
3113 case Dali::Actor::Property::POSITION_Y:
3115 AdjustValue< float >( mTargetPosition.y, value );
3119 case Dali::Actor::Property::POSITION_Z:
3121 AdjustValue< float >( mTargetPosition.z, value );
3125 case Dali::Actor::Property::ORIENTATION:
3127 Quaternion relativeValue;
3128 if( value.Get( relativeValue ) )
3130 mTargetOrientation *= relativeValue;
3135 case Dali::Actor::Property::SCALE:
3137 AdjustValue< Vector3 >( mTargetScale, value );
3141 case Dali::Actor::Property::SCALE_X:
3143 AdjustValue< float >( mTargetScale.x, value );
3147 case Dali::Actor::Property::SCALE_Y:
3149 AdjustValue< float >( mTargetScale.y, value );
3153 case Dali::Actor::Property::SCALE_Z:
3155 AdjustValue< float >( mTargetScale.z, value );
3159 case Dali::Actor::Property::VISIBLE:
3161 bool relativeValue = false;
3162 if( value.Get( relativeValue ) )
3164 bool visible = mVisible || relativeValue;
3165 SetVisibleInternal( visible, SendMessage::FALSE );
3170 case Dali::Actor::Property::COLOR:
3172 AdjustValue< Vector4 >( mTargetColor, value );
3176 case Dali::Actor::Property::COLOR_RED:
3178 AdjustValue< float >( mTargetColor.r, value );
3182 case Dali::Actor::Property::COLOR_GREEN:
3184 AdjustValue< float >( mTargetColor.g, value );
3188 case Dali::Actor::Property::COLOR_BLUE:
3190 AdjustValue< float >( mTargetColor.b, value );
3194 case Dali::Actor::Property::COLOR_ALPHA:
3195 case Dali::DevelActor::Property::OPACITY:
3197 AdjustValue< float >( mTargetColor.a, value );
3203 // Not an animatable property. Do nothing.
3212 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3214 const PropertyBase* property( NULL );
3218 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3219 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3220 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3221 case Dali::Actor::Property::SIZE_DEPTH:
3223 property = &GetNode().mSize;
3226 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3227 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3228 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3229 case Dali::Actor::Property::POSITION_Z:
3231 property = &GetNode().mPosition;
3234 case Dali::Actor::Property::ORIENTATION:
3236 property = &GetNode().mOrientation;
3239 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3240 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3241 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3242 case Dali::Actor::Property::SCALE_Z:
3244 property = &GetNode().mScale;
3247 case Dali::Actor::Property::VISIBLE:
3249 property = &GetNode().mVisible;
3252 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3253 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3254 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3255 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3256 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3257 case Dali::DevelActor::Property::OPACITY:
3259 property = &GetNode().mColor;
3269 // not our property, ask base
3270 property = Object::GetSceneObjectAnimatableProperty( index );
3276 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3278 const PropertyInputImpl* property( NULL );
3282 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3283 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3284 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3285 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3287 property = &GetNode().mParentOrigin;
3290 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3291 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3292 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3293 case Dali::Actor::Property::ANCHOR_POINT_Z:
3295 property = &GetNode().mAnchorPoint;
3298 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3299 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3300 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3301 case Dali::Actor::Property::WORLD_POSITION_Z:
3303 property = &GetNode().mWorldPosition;
3306 case Dali::Actor::Property::WORLD_ORIENTATION:
3308 property = &GetNode().mWorldOrientation;
3311 case Dali::Actor::Property::WORLD_SCALE:
3313 property = &GetNode().mWorldScale;
3316 case Dali::Actor::Property::WORLD_COLOR:
3318 property = &GetNode().mWorldColor;
3321 case Dali::Actor::Property::WORLD_MATRIX:
3323 property = &GetNode().mWorldMatrix;
3326 case Dali::DevelActor::Property::CULLED:
3328 property = &GetNode().mCulled;
3338 // reuse animatable property getter as animatable properties are inputs as well
3339 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3340 property = GetSceneObjectAnimatableProperty( index );
3346 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3348 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3352 case Dali::Actor::Property::PARENT_ORIGIN_X:
3353 case Dali::Actor::Property::ANCHOR_POINT_X:
3354 case Dali::Actor::Property::SIZE_WIDTH:
3355 case Dali::Actor::Property::POSITION_X:
3356 case Dali::Actor::Property::WORLD_POSITION_X:
3357 case Dali::Actor::Property::SCALE_X:
3358 case Dali::Actor::Property::COLOR_RED:
3364 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3365 case Dali::Actor::Property::ANCHOR_POINT_Y:
3366 case Dali::Actor::Property::SIZE_HEIGHT:
3367 case Dali::Actor::Property::POSITION_Y:
3368 case Dali::Actor::Property::WORLD_POSITION_Y:
3369 case Dali::Actor::Property::SCALE_Y:
3370 case Dali::Actor::Property::COLOR_GREEN:
3376 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3377 case Dali::Actor::Property::ANCHOR_POINT_Z:
3378 case Dali::Actor::Property::SIZE_DEPTH:
3379 case Dali::Actor::Property::POSITION_Z:
3380 case Dali::Actor::Property::WORLD_POSITION_Z:
3381 case Dali::Actor::Property::SCALE_Z:
3382 case Dali::Actor::Property::COLOR_BLUE:
3388 case Dali::Actor::Property::COLOR_ALPHA:
3389 case Dali::DevelActor::Property::OPACITY:
3401 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3404 componentIndex = Object::GetPropertyComponentIndex( index );
3407 return componentIndex;
3410 void Actor::SetParent( Actor* parent )
3414 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3418 mScene = parent->mScene;
3420 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3423 // Instruct each actor to create a corresponding node in the scene graph
3424 ConnectToStage( parent->GetHierarchyDepth() );
3427 // Resolve the name and index for the child properties if any
3428 ResolveChildProperties();
3430 else // parent being set to NULL
3432 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3436 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3439 // Disconnect the Node & its children from the scene-graph.
3440 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3442 // Instruct each actor to discard pointers to the scene-graph
3443 DisconnectFromStage();
3450 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3453 Actor* actor = dynamic_cast< Actor* >( object );
3457 if( 0 == actionName.compare( ACTION_SHOW ) )
3459 actor->SetVisible( true );
3462 else if( 0 == actionName.compare( ACTION_HIDE ) )
3464 actor->SetVisible( false );
3472 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3474 bool valueSet = true;
3478 case Dali::Actor::Property::PARENT_ORIGIN:
3480 value = GetCurrentParentOrigin();
3484 case Dali::Actor::Property::PARENT_ORIGIN_X:
3486 value = GetCurrentParentOrigin().x;
3490 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3492 value = GetCurrentParentOrigin().y;
3496 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3498 value = GetCurrentParentOrigin().z;
3502 case Dali::Actor::Property::ANCHOR_POINT:
3504 value = GetCurrentAnchorPoint();
3508 case Dali::Actor::Property::ANCHOR_POINT_X:
3510 value = GetCurrentAnchorPoint().x;
3514 case Dali::Actor::Property::ANCHOR_POINT_Y:
3516 value = GetCurrentAnchorPoint().y;
3520 case Dali::Actor::Property::ANCHOR_POINT_Z:
3522 value = GetCurrentAnchorPoint().z;
3526 case Dali::Actor::Property::SIZE:
3528 value = GetTargetSize();
3532 case Dali::Actor::Property::SIZE_WIDTH:
3534 value = GetTargetSize().width;
3538 case Dali::Actor::Property::SIZE_HEIGHT:
3540 value = GetTargetSize().height;
3544 case Dali::Actor::Property::SIZE_DEPTH:
3546 value = GetTargetSize().depth;
3550 case Dali::Actor::Property::POSITION:
3552 value = GetTargetPosition();
3556 case Dali::Actor::Property::POSITION_X:
3558 value = GetTargetPosition().x;
3562 case Dali::Actor::Property::POSITION_Y:
3564 value = GetTargetPosition().y;
3568 case Dali::Actor::Property::POSITION_Z:
3570 value = GetTargetPosition().z;
3574 case Dali::Actor::Property::ORIENTATION:
3576 value = mTargetOrientation;
3580 case Dali::Actor::Property::SCALE:
3582 value = mTargetScale;
3586 case Dali::Actor::Property::SCALE_X:
3588 value = mTargetScale.x;
3592 case Dali::Actor::Property::SCALE_Y:
3594 value = mTargetScale.y;
3598 case Dali::Actor::Property::SCALE_Z:
3600 value = mTargetScale.z;
3604 case Dali::Actor::Property::VISIBLE:
3610 case Dali::Actor::Property::COLOR:
3612 value = mTargetColor;
3616 case Dali::Actor::Property::COLOR_RED:
3618 value = mTargetColor.r;
3622 case Dali::Actor::Property::COLOR_GREEN:
3624 value = mTargetColor.g;
3628 case Dali::Actor::Property::COLOR_BLUE:
3630 value = mTargetColor.b;
3634 case Dali::Actor::Property::COLOR_ALPHA:
3635 case Dali::DevelActor::Property::OPACITY:
3637 value = mTargetColor.a;
3641 case Dali::Actor::Property::NAME:
3647 case Dali::Actor::Property::SENSITIVE:
3649 value = IsSensitive();
3653 case Dali::Actor::Property::LEAVE_REQUIRED:
3655 value = GetLeaveRequired();
3659 case Dali::Actor::Property::INHERIT_POSITION:
3661 value = IsPositionInherited();
3665 case Dali::Actor::Property::INHERIT_ORIENTATION:
3667 value = IsOrientationInherited();
3671 case Dali::Actor::Property::INHERIT_SCALE:
3673 value = IsScaleInherited();
3677 case Dali::Actor::Property::COLOR_MODE:
3679 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3683 case Dali::Actor::Property::DRAW_MODE:
3685 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3689 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3691 value = GetSizeModeFactor();
3695 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3697 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3701 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3703 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3707 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3709 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3713 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3715 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3719 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3721 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3725 case Dali::Actor::Property::PADDING:
3727 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3728 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3729 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3733 case Dali::Actor::Property::MINIMUM_SIZE:
3735 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3739 case Dali::Actor::Property::MAXIMUM_SIZE:
3741 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3745 case Dali::Actor::Property::CLIPPING_MODE:
3747 value = mClippingMode;
3751 case Dali::DevelActor::Property::SIBLING_ORDER:
3753 value = static_cast<int>( GetSiblingOrder() );
3757 case Dali::DevelActor::Property::SCREEN_POSITION:
3759 value = GetCurrentScreenPosition();
3763 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3765 value = mPositionUsesAnchorPoint;
3769 case Dali::Actor::Property::LAYOUT_DIRECTION:
3771 value = mLayoutDirection;
3775 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3777 value = IsLayoutDirectionInherited();
3783 // Must be a scene-graph only property
3792 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3794 bool valueSet = true;
3798 case Dali::Actor::Property::SIZE:
3800 value = GetCurrentSize();
3804 case Dali::Actor::Property::SIZE_WIDTH:
3806 value = GetCurrentSize().width;
3810 case Dali::Actor::Property::SIZE_HEIGHT:
3812 value = GetCurrentSize().height;
3816 case Dali::Actor::Property::SIZE_DEPTH:
3818 value = GetCurrentSize().depth;
3822 case Dali::Actor::Property::POSITION:
3824 value = GetCurrentPosition();
3828 case Dali::Actor::Property::POSITION_X:
3830 value = GetCurrentPosition().x;
3834 case Dali::Actor::Property::POSITION_Y:
3836 value = GetCurrentPosition().y;
3840 case Dali::Actor::Property::POSITION_Z:
3842 value = GetCurrentPosition().z;
3846 case Dali::Actor::Property::WORLD_POSITION:
3848 value = GetCurrentWorldPosition();
3852 case Dali::Actor::Property::WORLD_POSITION_X:
3854 value = GetCurrentWorldPosition().x;
3858 case Dali::Actor::Property::WORLD_POSITION_Y:
3860 value = GetCurrentWorldPosition().y;
3864 case Dali::Actor::Property::WORLD_POSITION_Z:
3866 value = GetCurrentWorldPosition().z;
3870 case Dali::Actor::Property::ORIENTATION:
3872 value = GetCurrentOrientation();
3876 case Dali::Actor::Property::WORLD_ORIENTATION:
3878 value = GetCurrentWorldOrientation();
3882 case Dali::Actor::Property::SCALE:
3884 value = GetCurrentScale();
3888 case Dali::Actor::Property::SCALE_X:
3890 value = GetCurrentScale().x;
3894 case Dali::Actor::Property::SCALE_Y:
3896 value = GetCurrentScale().y;
3900 case Dali::Actor::Property::SCALE_Z:
3902 value = GetCurrentScale().z;
3906 case Dali::Actor::Property::WORLD_SCALE:
3908 value = GetCurrentWorldScale();
3912 case Dali::Actor::Property::COLOR:
3914 value = GetCurrentColor();
3918 case Dali::Actor::Property::COLOR_RED:
3920 value = GetCurrentColor().r;
3924 case Dali::Actor::Property::COLOR_GREEN:
3926 value = GetCurrentColor().g;
3930 case Dali::Actor::Property::COLOR_BLUE:
3932 value = GetCurrentColor().b;
3936 case Dali::Actor::Property::COLOR_ALPHA:
3937 case Dali::DevelActor::Property::OPACITY:
3939 value = GetCurrentColor().a;
3943 case Dali::Actor::Property::WORLD_COLOR:
3945 value = GetCurrentWorldColor();
3949 case Dali::Actor::Property::WORLD_MATRIX:
3951 value = GetCurrentWorldMatrix();
3955 case Dali::Actor::Property::VISIBLE:
3957 value = IsVisible();
3961 case DevelActor::Property::CULLED:
3963 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
3969 // Must be an event-side only property
3978 void Actor::EnsureRelayoutData()
3980 // Assign relayout data.
3981 if( !mRelayoutData )
3983 mRelayoutData = new RelayoutData();
3987 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3989 // Check if actor is dependent on parent
3990 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3992 if( ( dimension & ( 1 << i ) ) )
3994 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3995 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4005 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4007 // Check if actor is dependent on children
4008 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4010 if( ( dimension & ( 1 << i ) ) )
4012 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4013 switch( resizePolicy )
4015 case ResizePolicy::FIT_TO_CHILDREN:
4016 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4032 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4034 return Actor::RelayoutDependentOnChildren( dimension );
4037 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4039 // Check each possible dimension and see if it is dependent on the input one
4040 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4042 if( dimension & ( 1 << i ) )
4044 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4051 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4053 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4055 if( dimension & ( 1 << i ) )
4057 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4062 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4064 // If more than one dimension is requested, just return the first one found
4065 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4067 if( ( dimension & ( 1 << i ) ) )
4069 return mRelayoutData->negotiatedDimensions[ i ];
4073 return 0.0f; // Default
4076 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4078 EnsureRelayoutData();
4080 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4082 if( dimension & ( 1 << i ) )
4084 mRelayoutData->dimensionPadding[ i ] = padding;
4089 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4091 if ( mRelayoutData )
4093 // If more than one dimension is requested, just return the first one found
4094 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4096 if( ( dimension & ( 1 << i ) ) )
4098 return mRelayoutData->dimensionPadding[ i ];
4103 return GetDefaultDimensionPadding();
4106 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4108 EnsureRelayoutData();
4110 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4112 if( dimension & ( 1 << i ) )
4114 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4119 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4121 if ( mRelayoutData )
4123 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4125 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4135 float Actor::GetHeightForWidthBase( float width )
4137 float height = 0.0f;
4139 const Vector3 naturalSize = GetNaturalSize();
4140 if( naturalSize.width > 0.0f )
4142 height = naturalSize.height * width / naturalSize.width;
4144 else // we treat 0 as 1:1 aspect ratio
4152 float Actor::GetWidthForHeightBase( float height )
4156 const Vector3 naturalSize = GetNaturalSize();
4157 if( naturalSize.height > 0.0f )
4159 width = naturalSize.width * height / naturalSize.height;
4161 else // we treat 0 as 1:1 aspect ratio
4169 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4171 // Fill to parent, taking size mode factor into account
4172 switch( child.GetResizePolicy( dimension ) )
4174 case ResizePolicy::FILL_TO_PARENT:
4176 return GetLatestSize( dimension );
4179 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4181 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4184 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4186 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4191 return GetLatestSize( dimension );
4196 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4198 // Can be overridden in derived class
4199 return CalculateChildSizeBase( child, dimension );
4202 float Actor::GetHeightForWidth( float width )
4204 // Can be overridden in derived class
4205 return GetHeightForWidthBase( width );
4208 float Actor::GetWidthForHeight( float height )
4210 // Can be overridden in derived class
4211 return GetWidthForHeightBase( height );
4214 float Actor::GetLatestSize( Dimension::Type dimension ) const
4216 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4219 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4221 Vector2 padding = GetPadding( dimension );
4223 return GetLatestSize( dimension ) + padding.x + padding.y;
4226 float Actor::NegotiateFromParent( Dimension::Type dimension )
4228 Actor* parent = GetParent();
4231 Vector2 padding( GetPadding( dimension ) );
4232 Vector2 parentPadding( parent->GetPadding( dimension ) );
4233 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4239 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4241 float maxDimensionPoint = 0.0f;
4243 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4245 ActorPtr child = GetChildAt( i );
4247 if( !child->RelayoutDependentOnParent( dimension ) )
4249 // Calculate the min and max points that the children range across
4250 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4251 float dimensionSize = child->GetRelayoutSize( dimension );
4252 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4256 return maxDimensionPoint;
4259 float Actor::GetSize( Dimension::Type dimension ) const
4261 return GetDimensionValue( mTargetSize, dimension );
4264 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4266 return GetDimensionValue( GetNaturalSize(), dimension );
4269 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4271 switch( GetResizePolicy( dimension ) )
4273 case ResizePolicy::USE_NATURAL_SIZE:
4275 return GetNaturalSize( dimension );
4278 case ResizePolicy::FIXED:
4280 return GetDimensionValue( GetPreferredSize(), dimension );
4283 case ResizePolicy::USE_ASSIGNED_SIZE:
4285 return GetDimensionValue( maximumSize, dimension );
4288 case ResizePolicy::FILL_TO_PARENT:
4289 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4290 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4292 return NegotiateFromParent( dimension );
4295 case ResizePolicy::FIT_TO_CHILDREN:
4297 return NegotiateFromChildren( dimension );
4300 case ResizePolicy::DIMENSION_DEPENDENCY:
4302 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4305 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4307 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4310 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4312 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4324 return 0.0f; // Default
4327 float Actor::ClampDimension( float size, Dimension::Type dimension )
4329 const float minSize = GetMinimumSize( dimension );
4330 const float maxSize = GetMaximumSize( dimension );
4332 return std::max( minSize, std::min( size, maxSize ) );
4335 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4337 // Check if it needs to be negotiated
4338 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4340 // Check that we havn't gotten into an infinite loop
4341 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4342 bool recursionFound = false;
4343 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4345 if( *it == searchActor )
4347 recursionFound = true;
4352 if( !recursionFound )
4354 // Record the path that we have taken
4355 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4357 // Dimension dependency check
4358 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4360 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4362 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4364 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4368 // Parent dependency check
4369 Actor* parent = GetParent();
4370 if( parent && RelayoutDependentOnParent( dimension ) )
4372 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4375 // Children dependency check
4376 if( RelayoutDependentOnChildren( dimension ) )
4378 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4380 ActorPtr child = GetChildAt( i );
4382 // Only relayout child first if it is not dependent on this actor
4383 if( !child->RelayoutDependentOnParent( dimension ) )
4385 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4390 // For deriving classes
4391 OnCalculateRelayoutSize( dimension );
4393 // All dependencies checked, calculate the size and set negotiated flag
4394 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4396 SetNegotiatedDimension( newSize, dimension );
4397 SetLayoutNegotiated( true, dimension );
4399 // For deriving classes
4400 OnLayoutNegotiated( newSize, dimension );
4402 // This actor has been successfully processed, pop it off the recursion stack
4403 recursionStack.pop_back();
4407 // TODO: Break infinite loop
4408 SetLayoutNegotiated( true, dimension );
4413 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4415 // Negotiate all dimensions that require it
4416 ActorDimensionStack recursionStack;
4418 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4420 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4423 NegotiateDimension( dimension, allocatedSize, recursionStack );
4427 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4429 switch( mRelayoutData->sizeSetPolicy )
4431 case SizeScalePolicy::USE_SIZE_SET:
4436 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4438 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4439 const Vector3 naturalSize = GetNaturalSize();
4440 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4442 const float sizeRatio = size.width / size.height;
4443 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4445 if( naturalSizeRatio < sizeRatio )
4447 return Vector2( naturalSizeRatio * size.height, size.height );
4449 else if( naturalSizeRatio > sizeRatio )
4451 return Vector2( size.width, size.width / naturalSizeRatio );
4462 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4464 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4465 const Vector3 naturalSize = GetNaturalSize();
4466 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4468 const float sizeRatio = size.width / size.height;
4469 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4471 if( naturalSizeRatio < sizeRatio )
4473 return Vector2( size.width, size.width / naturalSizeRatio );
4475 else if( naturalSizeRatio > sizeRatio )
4477 return Vector2( naturalSizeRatio * size.height, size.height );
4496 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4498 // Do the set actor size
4499 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4501 // Adjust for size set policy
4502 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4504 // Lock the flag to stop recursive relayouts on set size
4505 mRelayoutData->insideRelayout = true;
4506 SetSize( negotiatedSize );
4507 mRelayoutData->insideRelayout = false;
4509 // Clear flags for all dimensions
4510 SetLayoutDirty( false );
4512 // Give deriving classes a chance to respond
4513 OnRelayout( negotiatedSize, container );
4515 if( !mOnRelayoutSignal.Empty() )
4517 Dali::Actor handle( this );
4518 mOnRelayoutSignal.Emit( handle );
4522 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4524 // Force a size negotiation for actors that has assigned size during relayout
4525 // This is required as otherwise the flags that force a relayout will not
4526 // necessarilly be set. This will occur if the actor has already been laid out.
4527 // The dirty flags are then cleared. Then if the actor is added back into the
4528 // relayout container afterwards, the dirty flags would still be clear...
4529 // causing a relayout to be skipped. Here we force any actors added to the
4530 // container to be relayed out.
4531 DALI_LOG_TIMER_START( NegSizeTimer1 );
4533 if( GetUseAssignedSize(Dimension::WIDTH ) )
4535 SetLayoutNegotiated( false, Dimension::WIDTH );
4537 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4539 SetLayoutNegotiated( false, Dimension::HEIGHT );
4542 // Do the negotiation
4543 NegotiateDimensions( allocatedSize );
4545 // Set the actor size
4546 SetNegotiatedSize( container );
4548 // Negotiate down to children
4549 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4551 ActorPtr child = GetChildAt( i );
4553 // Forces children that have already been laid out to be relayed out
4554 // if they have assigned size during relayout.
4555 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4557 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4558 child->SetLayoutDirty(true, Dimension::WIDTH);
4561 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4563 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4564 child->SetLayoutDirty(true, Dimension::HEIGHT);
4567 // Only relayout if required
4568 if( child->RelayoutRequired() )
4570 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4573 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4576 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4580 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4582 if( dimension & ( 1 << i ) )
4584 mRelayoutData->useAssignedSize[ i ] = use;
4590 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4592 if ( mRelayoutData )
4594 // If more than one dimension is requested, just return the first one found
4595 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4597 if( dimension & ( 1 << i ) )
4599 return mRelayoutData->useAssignedSize[ i ];
4607 void Actor::RelayoutRequest( Dimension::Type dimension )
4609 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4610 if( relayoutController )
4612 Dali::Actor self( this );
4613 relayoutController->RequestRelayout( self, dimension );
4617 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4621 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4625 void Actor::SetPreferredSize( const Vector2& size )
4627 EnsureRelayoutData();
4629 if( size.width > 0.0f )
4631 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4634 if( size.height > 0.0f )
4636 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4639 mRelayoutData->preferredSize = size;
4644 Vector2 Actor::GetPreferredSize() const
4646 if ( mRelayoutData )
4648 return Vector2( mRelayoutData->preferredSize );
4651 return GetDefaultPreferredSize();
4654 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4656 EnsureRelayoutData();
4658 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4660 if( dimension & ( 1 << i ) )
4662 mRelayoutData->minimumSize[ i ] = size;
4669 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4671 if ( mRelayoutData )
4673 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4675 if( dimension & ( 1 << i ) )
4677 return mRelayoutData->minimumSize[ i ];
4682 return 0.0f; // Default
4685 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4687 EnsureRelayoutData();
4689 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4691 if( dimension & ( 1 << i ) )
4693 mRelayoutData->maximumSize[ i ] = size;
4700 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4702 if ( mRelayoutData )
4704 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4706 if( dimension & ( 1 << i ) )
4708 return mRelayoutData->maximumSize[ i ];
4713 return FLT_MAX; // Default
4716 Object* Actor::GetParentObject() const
4721 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4723 if( mVisible != visible )
4725 if( sendMessage == SendMessage::TRUE )
4727 // node is being used in a separate thread; queue a message to set the value & base value
4728 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4733 // Emit the signal on this actor and all its children
4734 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4738 void Actor::SetSiblingOrder( uint32_t order )
4742 ActorContainer& siblings = *(mParent->mChildren);
4743 uint32_t currentOrder = GetSiblingOrder();
4745 if( order != currentOrder )
4751 else if( order < siblings.size() -1 )
4753 if( order > currentOrder )
4755 RaiseAbove( *siblings[order] );
4759 LowerBelow( *siblings[order] );
4770 uint32_t Actor::GetSiblingOrder() const
4776 ActorContainer& siblings = *(mParent->mChildren);
4777 for( std::size_t i = 0; i < siblings.size(); ++i )
4779 if( siblings[i] == this )
4781 order = static_cast<uint32_t>( i );
4790 void Actor::RequestRebuildDepthTree()
4796 mScene->RequestRebuildDepthTree();
4805 ActorContainer& siblings = *(mParent->mChildren);
4806 if( siblings.back() != this ) // If not already at end
4808 for( std::size_t i=0; i<siblings.size(); ++i )
4810 if( siblings[i] == this )
4813 ActorPtr next = siblings[i+1];
4814 siblings[i+1] = this;
4821 Dali::Actor handle( this );
4822 mParent->mChildOrderChangedSignal.Emit( handle );
4824 RequestRebuildDepthTree();
4828 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4836 ActorContainer& siblings = *(mParent->mChildren);
4837 if( siblings.front() != this ) // If not already at beginning
4839 for( std::size_t i=1; i<siblings.size(); ++i )
4841 if( siblings[i] == this )
4843 // Swap with previous
4844 ActorPtr previous = siblings[i-1];
4845 siblings[i-1] = this;
4846 siblings[i] = previous;
4852 Dali::Actor handle( this );
4853 mParent->mChildOrderChangedSignal.Emit( handle );
4855 RequestRebuildDepthTree();
4859 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4863 void Actor::RaiseToTop()
4867 ActorContainer& siblings = *(mParent->mChildren);
4868 if( siblings.back() != this ) // If not already at end
4870 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4871 if( iter != siblings.end() )
4873 siblings.erase(iter);
4874 siblings.push_back(ActorPtr(this));
4878 Dali::Actor handle( this );
4879 mParent->mChildOrderChangedSignal.Emit( handle );
4881 RequestRebuildDepthTree();
4885 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4889 void Actor::LowerToBottom()
4893 ActorContainer& siblings = *(mParent->mChildren);
4894 if( siblings.front() != this ) // If not already at bottom,
4896 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4898 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4899 if( iter != siblings.end() )
4901 siblings.erase(iter);
4902 siblings.insert(siblings.begin(), thisPtr);
4906 Dali::Actor handle( this );
4907 mParent->mChildOrderChangedSignal.Emit( handle );
4909 RequestRebuildDepthTree();
4913 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4917 void Actor::RaiseAbove( Internal::Actor& target )
4921 ActorContainer& siblings = *(mParent->mChildren);
4922 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
4924 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4926 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
4927 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
4928 if( thisIter < targetIter )
4930 siblings.erase(thisIter);
4931 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
4932 // invalidate thisIter)
4933 targetIter = std::find( siblings.begin(), siblings.end(), &target );
4935 siblings.insert(targetIter, thisPtr);
4938 Dali::Actor handle( this );
4939 mParent->mChildOrderChangedSignal.Emit( handle );
4941 RequestRebuildDepthTree();
4946 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4950 void Actor::LowerBelow( Internal::Actor& target )
4954 ActorContainer& siblings = *(mParent->mChildren);
4955 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
4957 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4959 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
4960 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
4962 if( thisIter > targetIter )
4964 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
4965 siblings.insert(targetIter, thisPtr);
4968 Dali::Actor handle( this );
4969 mParent->mChildOrderChangedSignal.Emit( handle );
4971 RequestRebuildDepthTree();
4976 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4980 void Actor::SetScene( Scene& scene )
4985 Scene& Actor::GetScene() const
4990 void Actor::SetInheritLayoutDirection( bool inherit )
4992 if( mInheritLayoutDirection != inherit )
4994 mInheritLayoutDirection = inherit;
4996 if( inherit && mParent )
4998 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
5003 bool Actor::IsLayoutDirectionInherited() const
5005 return mInheritLayoutDirection;
5008 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5010 if( actor && ( actor->mInheritLayoutDirection || set ) )
5012 if( actor->mLayoutDirection != direction )
5014 actor->mLayoutDirection = direction;
5015 actor->EmitLayoutDirectionChangedSignal( direction );
5016 actor->RelayoutRequest();
5019 if( actor->GetChildCount() > 0 )
5021 ActorContainer& children = actor->GetChildrenInternal();
5022 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5024 InheritLayoutDirectionRecursively( *iter, direction );
5030 } // namespace Internal