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 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
2085 GetEventThreadServices().UnregisterObject( this );
2088 // Cleanup optional gesture data
2089 delete mGestureData;
2091 // Cleanup optional parent origin and anchor
2092 delete mParentOrigin;
2093 delete mAnchorPoint;
2095 // Delete optional relayout data
2096 delete mRelayoutData;
2099 void Actor::ConnectToStage( uint32_t parentDepth )
2101 // This container is used instead of walking the Actor hierarchy.
2102 // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
2103 ActorContainer connectionList;
2107 mScene->RequestRebuildDepthTree();
2110 // This stage is atomic i.e. not interrupted by user callbacks.
2111 RecursiveConnectToStage( connectionList, parentDepth + 1 );
2113 // Notify applications about the newly connected actors.
2114 const ActorIter endIter = connectionList.end();
2115 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2117 (*iter)->NotifyStageConnection();
2123 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t depth )
2125 DALI_ASSERT_ALWAYS( !OnStage() );
2128 mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
2130 ConnectToSceneGraph();
2132 // Notification for internal derived classes
2133 OnStageConnectionInternal();
2135 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2136 connectionList.push_back( ActorPtr( this ) );
2138 // Recursively connect children
2141 ActorConstIter endIter = mChildren->end();
2142 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2144 (*iter)->SetScene( *mScene );
2145 (*iter)->RecursiveConnectToStage( connectionList, depth + 1 );
2151 * This method is called when the Actor is connected to the Stage.
2152 * The parent must have added its Node to the scene-graph.
2153 * The child must connect its Node to the parent's Node.
2154 * This is recursive; the child calls ConnectToStage() for its children.
2156 void Actor::ConnectToSceneGraph()
2158 DALI_ASSERT_DEBUG( mParent != NULL);
2160 // Reparent Node in next Update
2161 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
2163 // Request relayout on all actors that are added to the scenegraph
2166 // Notification for Object::Observers
2170 void Actor::NotifyStageConnection()
2172 // Actors can be removed (in a callback), before the on-stage stage is reported.
2173 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2174 if( OnStage() && !mOnStageSignalled )
2176 // Notification for external (CustomActor) derived classes
2177 OnStageConnectionExternal( mDepth );
2179 if( !mOnStageSignal.Empty() )
2181 Dali::Actor handle( this );
2182 mOnStageSignal.Emit( handle );
2185 // Guard against Remove during callbacks
2188 mOnStageSignalled = true; // signal required next time Actor is removed
2193 void Actor::DisconnectFromStage()
2195 // This container is used instead of walking the Actor hierachy.
2196 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2197 ActorContainer disconnectionList;
2201 mScene->RequestRebuildDepthTree();
2204 // This stage is atomic i.e. not interrupted by user callbacks
2205 RecursiveDisconnectFromStage( disconnectionList );
2207 // Notify applications about the newly disconnected actors.
2208 const ActorIter endIter = disconnectionList.end();
2209 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2211 (*iter)->NotifyStageDisconnection();
2215 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2217 // need to change state first so that internals relying on IsOnStage() inside OnStageDisconnectionInternal() get the correct value
2220 // Recursively disconnect children
2223 ActorConstIter endIter = mChildren->end();
2224 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2226 (*iter)->RecursiveDisconnectFromStage( disconnectionList );
2230 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2231 disconnectionList.push_back( ActorPtr( this ) );
2233 // Notification for internal derived classes
2234 OnStageDisconnectionInternal();
2236 DisconnectFromSceneGraph();
2240 * This method is called by an actor or its parent, before a node removal message is sent.
2241 * This is recursive; the child calls DisconnectFromStage() for its children.
2243 void Actor::DisconnectFromSceneGraph()
2245 // Notification for Object::Observers
2246 OnSceneObjectRemove();
2249 void Actor::NotifyStageDisconnection()
2251 // Actors can be added (in a callback), before the off-stage state is reported.
2252 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2253 // only do this step if there is a stage, i.e. Core is not being shut down
2254 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2256 // Notification for external (CustomeActor) derived classes
2257 OnStageDisconnectionExternal();
2259 if( !mOffStageSignal.Empty() )
2261 Dali::Actor handle( this );
2262 mOffStageSignal.Emit( handle );
2265 // Guard against Add during callbacks
2268 mOnStageSignalled = false; // signal required next time Actor is added
2273 bool Actor::IsNodeConnected() const
2275 bool connected( false );
2279 if( IsRoot() || GetNode().GetParent() )
2288 // This method initiates traversal of the actor tree using depth-first
2289 // traversal to set a depth index based on traversal order. It sends a
2290 // single message to update manager to update all the actor's nodes in
2291 // this tree with the depth index. The sceneGraphNodeDepths vector's
2292 // elements are ordered by depth, and could be used to reduce sorting
2293 // in the update thread.
2294 void Actor::RebuildDepthTree()
2296 DALI_LOG_TIMER_START(depthTimer);
2298 // Vector of scene-graph nodes and their depths to send to UpdateManager
2299 // in a single message
2300 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
2302 int32_t depthIndex = 1;
2303 DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2305 SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
2306 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
2309 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
2311 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
2312 sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
2314 // Create/add to children of this node
2317 for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
2319 Actor* childActor = (*it).Get();
2321 childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
2326 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2330 case Dali::Actor::Property::PARENT_ORIGIN:
2332 Property::Type type = property.GetType();
2333 if( type == Property::VECTOR3 )
2335 SetParentOrigin( property.Get< Vector3 >() );
2337 else if ( type == Property::STRING )
2339 std::string parentOriginString;
2340 property.Get( parentOriginString );
2341 Vector3 parentOrigin;
2342 if( GetParentOriginConstant( parentOriginString, parentOrigin ) )
2344 SetParentOrigin( parentOrigin );
2350 case Dali::Actor::Property::PARENT_ORIGIN_X:
2352 SetParentOriginX( property.Get< float >() );
2356 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2358 SetParentOriginY( property.Get< float >() );
2362 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2364 SetParentOriginZ( property.Get< float >() );
2368 case Dali::Actor::Property::ANCHOR_POINT:
2370 Property::Type type = property.GetType();
2371 if( type == Property::VECTOR3 )
2373 SetAnchorPoint( property.Get< Vector3 >() );
2375 else if ( type == Property::STRING )
2377 std::string anchorPointString;
2378 property.Get( anchorPointString );
2380 if( GetAnchorPointConstant( anchorPointString, anchor ) )
2382 SetAnchorPoint( anchor );
2388 case Dali::Actor::Property::ANCHOR_POINT_X:
2390 SetAnchorPointX( property.Get< float >() );
2394 case Dali::Actor::Property::ANCHOR_POINT_Y:
2396 SetAnchorPointY( property.Get< float >() );
2400 case Dali::Actor::Property::ANCHOR_POINT_Z:
2402 SetAnchorPointZ( property.Get< float >() );
2406 case Dali::Actor::Property::SIZE:
2408 SetSize( property.Get< Vector3 >() );
2412 case Dali::Actor::Property::SIZE_WIDTH:
2414 SetWidth( property.Get< float >() );
2418 case Dali::Actor::Property::SIZE_HEIGHT:
2420 SetHeight( property.Get< float >() );
2424 case Dali::Actor::Property::SIZE_DEPTH:
2426 SetDepth( property.Get< float >() );
2430 case Dali::Actor::Property::POSITION:
2432 SetPosition( property.Get< Vector3 >() );
2436 case Dali::Actor::Property::POSITION_X:
2438 SetX( property.Get< float >() );
2442 case Dali::Actor::Property::POSITION_Y:
2444 SetY( property.Get< float >() );
2448 case Dali::Actor::Property::POSITION_Z:
2450 SetZ( property.Get< float >() );
2454 case Dali::Actor::Property::ORIENTATION:
2456 SetOrientation( property.Get< Quaternion >() );
2460 case Dali::Actor::Property::SCALE:
2462 SetScale( property.Get< Vector3 >() );
2466 case Dali::Actor::Property::SCALE_X:
2468 SetScaleX( property.Get< float >() );
2472 case Dali::Actor::Property::SCALE_Y:
2474 SetScaleY( property.Get< float >() );
2478 case Dali::Actor::Property::SCALE_Z:
2480 SetScaleZ( property.Get< float >() );
2484 case Dali::Actor::Property::VISIBLE:
2486 SetVisible( property.Get< bool >() );
2490 case Dali::Actor::Property::COLOR:
2492 SetColor( property.Get< Vector4 >() );
2496 case Dali::Actor::Property::COLOR_RED:
2498 SetColorRed( property.Get< float >() );
2502 case Dali::Actor::Property::COLOR_GREEN:
2504 SetColorGreen( property.Get< float >() );
2508 case Dali::Actor::Property::COLOR_BLUE:
2510 SetColorBlue( property.Get< float >() );
2514 case Dali::Actor::Property::COLOR_ALPHA:
2515 case Dali::DevelActor::Property::OPACITY:
2518 if( property.Get( value ) )
2520 SetOpacity( value );
2525 case Dali::Actor::Property::NAME:
2527 SetName( property.Get< std::string >() );
2531 case Dali::Actor::Property::SENSITIVE:
2533 SetSensitive( property.Get< bool >() );
2537 case Dali::Actor::Property::LEAVE_REQUIRED:
2539 SetLeaveRequired( property.Get< bool >() );
2543 case Dali::Actor::Property::INHERIT_POSITION:
2545 SetInheritPosition( property.Get< bool >() );
2549 case Dali::Actor::Property::INHERIT_ORIENTATION:
2551 SetInheritOrientation( property.Get< bool >() );
2555 case Dali::Actor::Property::INHERIT_SCALE:
2557 SetInheritScale( property.Get< bool >() );
2561 case Dali::Actor::Property::COLOR_MODE:
2563 ColorMode mode = mColorMode;
2564 if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) )
2566 SetColorMode( mode );
2571 case Dali::Actor::Property::DRAW_MODE:
2573 DrawMode::Type mode = mDrawMode;
2574 if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) )
2576 SetDrawMode( mode );
2581 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2583 SetSizeModeFactor( property.Get< Vector3 >() );
2587 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
2589 ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH );
2590 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2592 SetResizePolicy( type, Dimension::WIDTH );
2597 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
2599 ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT );
2600 if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) )
2602 SetResizePolicy( type, Dimension::HEIGHT );
2607 case Dali::Actor::Property::SIZE_SCALE_POLICY:
2609 SizeScalePolicy::Type type = GetSizeScalePolicy();
2610 if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) )
2612 SetSizeScalePolicy( type );
2617 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
2619 if( property.Get< bool >() )
2621 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH );
2626 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
2628 if( property.Get< bool >() )
2630 SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
2635 case Dali::Actor::Property::PADDING:
2637 Vector4 padding = property.Get< Vector4 >();
2638 SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH );
2639 SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT );
2643 case Dali::Actor::Property::MINIMUM_SIZE:
2645 Vector2 size = property.Get< Vector2 >();
2646 SetMinimumSize( size.x, Dimension::WIDTH );
2647 SetMinimumSize( size.y, Dimension::HEIGHT );
2651 case Dali::Actor::Property::MAXIMUM_SIZE:
2653 Vector2 size = property.Get< Vector2 >();
2654 SetMaximumSize( size.x, Dimension::WIDTH );
2655 SetMaximumSize( size.y, Dimension::HEIGHT );
2659 case Dali::DevelActor::Property::SIBLING_ORDER:
2663 if( property.Get( value ) )
2665 SetSiblingOrder( value );
2670 case Dali::Actor::Property::CLIPPING_MODE:
2672 ClippingMode::Type convertedValue = mClippingMode;
2673 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
2675 mClippingMode = convertedValue;
2676 SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode );
2681 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
2684 if( property.Get( value ) && value != mPositionUsesAnchorPoint )
2686 mPositionUsesAnchorPoint = value;
2687 SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint );
2692 case Dali::Actor::Property::LAYOUT_DIRECTION:
2694 Dali::LayoutDirection::Type direction = mLayoutDirection;
2695 mInheritLayoutDirection = false;
2697 if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
2699 InheritLayoutDirectionRecursively( this, direction, true );
2704 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
2707 if( property.Get( value ) )
2709 SetInheritLayoutDirection( value );
2716 // this can happen in the case of a non-animatable default property so just do nothing
2722 // TODO: This method needs to be removed
2723 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2725 switch( entry.GetType() )
2727 case Property::BOOLEAN:
2729 const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() );
2730 DALI_ASSERT_DEBUG( NULL != property );
2732 // property is being used in a separate thread; queue a message to set the property
2733 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2738 case Property::INTEGER:
2740 const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() );
2741 DALI_ASSERT_DEBUG( NULL != property );
2743 // property is being used in a separate thread; queue a message to set the property
2744 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2749 case Property::FLOAT:
2751 const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() );
2752 DALI_ASSERT_DEBUG( NULL != property );
2754 // property is being used in a separate thread; queue a message to set the property
2755 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2760 case Property::VECTOR2:
2762 const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() );
2763 DALI_ASSERT_DEBUG( NULL != property );
2765 // property is being used in a separate thread; queue a message to set the property
2766 if(entry.componentIndex == 0)
2768 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeX, value.Get<float>() );
2770 else if(entry.componentIndex == 1)
2772 SceneGraph::NodePropertyComponentMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::BakeY, value.Get<float>() );
2776 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2782 case Property::VECTOR3:
2784 const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() );
2785 DALI_ASSERT_DEBUG( NULL != property );
2787 // property is being used in a separate thread; queue a message to set the property
2788 if(entry.componentIndex == 0)
2790 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeX, value.Get<float>() );
2792 else if(entry.componentIndex == 1)
2794 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeY, value.Get<float>() );
2796 else if(entry.componentIndex == 2)
2798 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::BakeZ, value.Get<float>() );
2802 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2808 case Property::VECTOR4:
2810 const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() );
2811 DALI_ASSERT_DEBUG( NULL != property );
2813 // property is being used in a separate thread; queue a message to set the property
2814 if(entry.componentIndex == 0)
2816 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeX, value.Get<float>() );
2818 else if(entry.componentIndex == 1)
2820 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeY, value.Get<float>() );
2822 else if(entry.componentIndex == 2)
2824 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeZ, value.Get<float>() );
2826 else if(entry.componentIndex == 3)
2828 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::BakeW, value.Get<float>() );
2832 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2838 case Property::ROTATION:
2840 const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() );
2841 DALI_ASSERT_DEBUG( NULL != property );
2843 // property is being used in a separate thread; queue a message to set the property
2844 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2849 case Property::MATRIX:
2851 const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() );
2852 DALI_ASSERT_DEBUG( NULL != property );
2854 // property is being used in a separate thread; queue a message to set the property
2855 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2860 case Property::MATRIX3:
2862 const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() );
2863 DALI_ASSERT_DEBUG( NULL != property );
2865 // property is being used in a separate thread; queue a message to set the property
2866 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2873 // nothing to do for other types
2878 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2880 Property::Value value;
2882 if( ! GetCachedPropertyValue( index, value ) )
2884 // If property value is not stored in the event-side, then it must be a scene-graph only property
2885 GetCurrentPropertyValue( index, value );
2891 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
2893 Property::Value value;
2895 if( ! GetCurrentPropertyValue( index, value ) )
2897 // If unable to retrieve scene-graph property value, then it must be an event-side only property
2898 GetCachedPropertyValue( index, value );
2904 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
2906 switch( animationType )
2909 case Animation::BETWEEN:
2913 case Dali::Actor::Property::SIZE:
2915 if( value.Get( mTargetSize ) )
2917 // Notify deriving classes
2918 OnSizeAnimation( animation, mTargetSize );
2923 case Dali::Actor::Property::SIZE_WIDTH:
2925 if( value.Get( mTargetSize.width ) )
2927 // Notify deriving classes
2928 OnSizeAnimation( animation, mTargetSize );
2933 case Dali::Actor::Property::SIZE_HEIGHT:
2935 if( value.Get( mTargetSize.height ) )
2937 // Notify deriving classes
2938 OnSizeAnimation( animation, mTargetSize );
2943 case Dali::Actor::Property::SIZE_DEPTH:
2945 if( value.Get( mTargetSize.depth ) )
2947 // Notify deriving classes
2948 OnSizeAnimation( animation, mTargetSize );
2953 case Dali::Actor::Property::POSITION:
2955 value.Get( mTargetPosition );
2959 case Dali::Actor::Property::POSITION_X:
2961 value.Get( mTargetPosition.x );
2965 case Dali::Actor::Property::POSITION_Y:
2967 value.Get( mTargetPosition.y );
2971 case Dali::Actor::Property::POSITION_Z:
2973 value.Get( mTargetPosition.z );
2977 case Dali::Actor::Property::ORIENTATION:
2979 value.Get( mTargetOrientation );
2983 case Dali::Actor::Property::SCALE:
2985 value.Get( mTargetScale );
2989 case Dali::Actor::Property::SCALE_X:
2991 value.Get( mTargetScale.x );
2995 case Dali::Actor::Property::SCALE_Y:
2997 value.Get( mTargetScale.y );
3001 case Dali::Actor::Property::SCALE_Z:
3003 value.Get( mTargetScale.z );
3007 case Dali::Actor::Property::VISIBLE:
3009 SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
3013 case Dali::Actor::Property::COLOR:
3015 value.Get( mTargetColor );
3019 case Dali::Actor::Property::COLOR_RED:
3021 value.Get( mTargetColor.r );
3025 case Dali::Actor::Property::COLOR_GREEN:
3027 value.Get( mTargetColor.g );
3031 case Dali::Actor::Property::COLOR_BLUE:
3033 value.Get( mTargetColor.b );
3037 case Dali::Actor::Property::COLOR_ALPHA:
3038 case Dali::DevelActor::Property::OPACITY:
3040 value.Get( mTargetColor.a );
3046 // Not an animatable property. Do nothing.
3057 case Dali::Actor::Property::SIZE:
3059 if( AdjustValue< Vector3 >( mTargetSize, value ) )
3061 // Notify deriving classes
3062 OnSizeAnimation( animation, mTargetSize );
3067 case Dali::Actor::Property::SIZE_WIDTH:
3069 if( AdjustValue< float >( mTargetSize.width, value ) )
3071 // Notify deriving classes
3072 OnSizeAnimation( animation, mTargetSize );
3077 case Dali::Actor::Property::SIZE_HEIGHT:
3079 if( AdjustValue< float >( mTargetSize.height, value ) )
3081 // Notify deriving classes
3082 OnSizeAnimation( animation, mTargetSize );
3087 case Dali::Actor::Property::SIZE_DEPTH:
3089 if( AdjustValue< float >( mTargetSize.depth, value ) )
3091 // Notify deriving classes
3092 OnSizeAnimation( animation, mTargetSize );
3097 case Dali::Actor::Property::POSITION:
3099 AdjustValue< Vector3 >( mTargetPosition, value );
3103 case Dali::Actor::Property::POSITION_X:
3105 AdjustValue< float >( mTargetPosition.x, value );
3109 case Dali::Actor::Property::POSITION_Y:
3111 AdjustValue< float >( mTargetPosition.y, value );
3115 case Dali::Actor::Property::POSITION_Z:
3117 AdjustValue< float >( mTargetPosition.z, value );
3121 case Dali::Actor::Property::ORIENTATION:
3123 Quaternion relativeValue;
3124 if( value.Get( relativeValue ) )
3126 mTargetOrientation *= relativeValue;
3131 case Dali::Actor::Property::SCALE:
3133 AdjustValue< Vector3 >( mTargetScale, value );
3137 case Dali::Actor::Property::SCALE_X:
3139 AdjustValue< float >( mTargetScale.x, value );
3143 case Dali::Actor::Property::SCALE_Y:
3145 AdjustValue< float >( mTargetScale.y, value );
3149 case Dali::Actor::Property::SCALE_Z:
3151 AdjustValue< float >( mTargetScale.z, value );
3155 case Dali::Actor::Property::VISIBLE:
3157 bool relativeValue = false;
3158 if( value.Get( relativeValue ) )
3160 bool visible = mVisible || relativeValue;
3161 SetVisibleInternal( visible, SendMessage::FALSE );
3166 case Dali::Actor::Property::COLOR:
3168 AdjustValue< Vector4 >( mTargetColor, value );
3172 case Dali::Actor::Property::COLOR_RED:
3174 AdjustValue< float >( mTargetColor.r, value );
3178 case Dali::Actor::Property::COLOR_GREEN:
3180 AdjustValue< float >( mTargetColor.g, value );
3184 case Dali::Actor::Property::COLOR_BLUE:
3186 AdjustValue< float >( mTargetColor.b, value );
3190 case Dali::Actor::Property::COLOR_ALPHA:
3191 case Dali::DevelActor::Property::OPACITY:
3193 AdjustValue< float >( mTargetColor.a, value );
3199 // Not an animatable property. Do nothing.
3208 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3210 const PropertyBase* property( NULL );
3214 case Dali::Actor::Property::SIZE: // FALLTHROUGH
3215 case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH
3216 case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH
3217 case Dali::Actor::Property::SIZE_DEPTH:
3219 property = &GetNode().mSize;
3222 case Dali::Actor::Property::POSITION: // FALLTHROUGH
3223 case Dali::Actor::Property::POSITION_X: // FALLTHROUGH
3224 case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH
3225 case Dali::Actor::Property::POSITION_Z:
3227 property = &GetNode().mPosition;
3230 case Dali::Actor::Property::ORIENTATION:
3232 property = &GetNode().mOrientation;
3235 case Dali::Actor::Property::SCALE: // FALLTHROUGH
3236 case Dali::Actor::Property::SCALE_X: // FALLTHROUGH
3237 case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH
3238 case Dali::Actor::Property::SCALE_Z:
3240 property = &GetNode().mScale;
3243 case Dali::Actor::Property::VISIBLE:
3245 property = &GetNode().mVisible;
3248 case Dali::Actor::Property::COLOR: // FALLTHROUGH
3249 case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH
3250 case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH
3251 case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH
3252 case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH
3253 case Dali::DevelActor::Property::OPACITY:
3255 property = &GetNode().mColor;
3265 // not our property, ask base
3266 property = Object::GetSceneObjectAnimatableProperty( index );
3272 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3274 const PropertyInputImpl* property( NULL );
3278 case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH
3279 case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH
3280 case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH
3281 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3283 property = &GetNode().mParentOrigin;
3286 case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH
3287 case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH
3288 case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH
3289 case Dali::Actor::Property::ANCHOR_POINT_Z:
3291 property = &GetNode().mAnchorPoint;
3294 case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH
3295 case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH
3296 case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH
3297 case Dali::Actor::Property::WORLD_POSITION_Z:
3299 property = &GetNode().mWorldPosition;
3302 case Dali::Actor::Property::WORLD_ORIENTATION:
3304 property = &GetNode().mWorldOrientation;
3307 case Dali::Actor::Property::WORLD_SCALE:
3309 property = &GetNode().mWorldScale;
3312 case Dali::Actor::Property::WORLD_COLOR:
3314 property = &GetNode().mWorldColor;
3317 case Dali::Actor::Property::WORLD_MATRIX:
3319 property = &GetNode().mWorldMatrix;
3322 case Dali::DevelActor::Property::CULLED:
3324 property = &GetNode().mCulled;
3334 // reuse animatable property getter as animatable properties are inputs as well
3335 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
3336 property = GetSceneObjectAnimatableProperty( index );
3342 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
3344 int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
3348 case Dali::Actor::Property::PARENT_ORIGIN_X:
3349 case Dali::Actor::Property::ANCHOR_POINT_X:
3350 case Dali::Actor::Property::SIZE_WIDTH:
3351 case Dali::Actor::Property::POSITION_X:
3352 case Dali::Actor::Property::WORLD_POSITION_X:
3353 case Dali::Actor::Property::SCALE_X:
3354 case Dali::Actor::Property::COLOR_RED:
3360 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3361 case Dali::Actor::Property::ANCHOR_POINT_Y:
3362 case Dali::Actor::Property::SIZE_HEIGHT:
3363 case Dali::Actor::Property::POSITION_Y:
3364 case Dali::Actor::Property::WORLD_POSITION_Y:
3365 case Dali::Actor::Property::SCALE_Y:
3366 case Dali::Actor::Property::COLOR_GREEN:
3372 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3373 case Dali::Actor::Property::ANCHOR_POINT_Z:
3374 case Dali::Actor::Property::SIZE_DEPTH:
3375 case Dali::Actor::Property::POSITION_Z:
3376 case Dali::Actor::Property::WORLD_POSITION_Z:
3377 case Dali::Actor::Property::SCALE_Z:
3378 case Dali::Actor::Property::COLOR_BLUE:
3384 case Dali::Actor::Property::COLOR_ALPHA:
3385 case Dali::DevelActor::Property::OPACITY:
3397 if( Property::INVALID_COMPONENT_INDEX == componentIndex )
3400 componentIndex = Object::GetPropertyComponentIndex( index );
3403 return componentIndex;
3406 void Actor::SetParent( Actor* parent )
3410 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3414 mScene = parent->mScene;
3416 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3419 // Instruct each actor to create a corresponding node in the scene graph
3420 ConnectToStage( parent->GetHierarchyDepth() );
3423 // Resolve the name and index for the child properties if any
3424 ResolveChildProperties();
3426 else // parent being set to NULL
3428 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3432 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3435 // Disconnect the Node & its children from the scene-graph.
3436 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
3438 // Instruct each actor to discard pointers to the scene-graph
3439 DisconnectFromStage();
3446 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
3449 Actor* actor = dynamic_cast< Actor* >( object );
3453 if( 0 == actionName.compare( ACTION_SHOW ) )
3455 actor->SetVisible( true );
3458 else if( 0 == actionName.compare( ACTION_HIDE ) )
3460 actor->SetVisible( false );
3468 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
3470 bool valueSet = true;
3474 case Dali::Actor::Property::PARENT_ORIGIN:
3476 value = GetCurrentParentOrigin();
3480 case Dali::Actor::Property::PARENT_ORIGIN_X:
3482 value = GetCurrentParentOrigin().x;
3486 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3488 value = GetCurrentParentOrigin().y;
3492 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3494 value = GetCurrentParentOrigin().z;
3498 case Dali::Actor::Property::ANCHOR_POINT:
3500 value = GetCurrentAnchorPoint();
3504 case Dali::Actor::Property::ANCHOR_POINT_X:
3506 value = GetCurrentAnchorPoint().x;
3510 case Dali::Actor::Property::ANCHOR_POINT_Y:
3512 value = GetCurrentAnchorPoint().y;
3516 case Dali::Actor::Property::ANCHOR_POINT_Z:
3518 value = GetCurrentAnchorPoint().z;
3522 case Dali::Actor::Property::SIZE:
3524 value = GetTargetSize();
3528 case Dali::Actor::Property::SIZE_WIDTH:
3530 value = GetTargetSize().width;
3534 case Dali::Actor::Property::SIZE_HEIGHT:
3536 value = GetTargetSize().height;
3540 case Dali::Actor::Property::SIZE_DEPTH:
3542 value = GetTargetSize().depth;
3546 case Dali::Actor::Property::POSITION:
3548 value = GetTargetPosition();
3552 case Dali::Actor::Property::POSITION_X:
3554 value = GetTargetPosition().x;
3558 case Dali::Actor::Property::POSITION_Y:
3560 value = GetTargetPosition().y;
3564 case Dali::Actor::Property::POSITION_Z:
3566 value = GetTargetPosition().z;
3570 case Dali::Actor::Property::ORIENTATION:
3572 value = mTargetOrientation;
3576 case Dali::Actor::Property::SCALE:
3578 value = mTargetScale;
3582 case Dali::Actor::Property::SCALE_X:
3584 value = mTargetScale.x;
3588 case Dali::Actor::Property::SCALE_Y:
3590 value = mTargetScale.y;
3594 case Dali::Actor::Property::SCALE_Z:
3596 value = mTargetScale.z;
3600 case Dali::Actor::Property::VISIBLE:
3606 case Dali::Actor::Property::COLOR:
3608 value = mTargetColor;
3612 case Dali::Actor::Property::COLOR_RED:
3614 value = mTargetColor.r;
3618 case Dali::Actor::Property::COLOR_GREEN:
3620 value = mTargetColor.g;
3624 case Dali::Actor::Property::COLOR_BLUE:
3626 value = mTargetColor.b;
3630 case Dali::Actor::Property::COLOR_ALPHA:
3631 case Dali::DevelActor::Property::OPACITY:
3633 value = mTargetColor.a;
3637 case Dali::Actor::Property::NAME:
3643 case Dali::Actor::Property::SENSITIVE:
3645 value = IsSensitive();
3649 case Dali::Actor::Property::LEAVE_REQUIRED:
3651 value = GetLeaveRequired();
3655 case Dali::Actor::Property::INHERIT_POSITION:
3657 value = IsPositionInherited();
3661 case Dali::Actor::Property::INHERIT_ORIENTATION:
3663 value = IsOrientationInherited();
3667 case Dali::Actor::Property::INHERIT_SCALE:
3669 value = IsScaleInherited();
3673 case Dali::Actor::Property::COLOR_MODE:
3675 value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
3679 case Dali::Actor::Property::DRAW_MODE:
3681 value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
3685 case Dali::Actor::Property::SIZE_MODE_FACTOR:
3687 value = GetSizeModeFactor();
3691 case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
3693 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3697 case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
3699 value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
3703 case Dali::Actor::Property::SIZE_SCALE_POLICY:
3705 value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
3709 case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
3711 value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
3715 case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
3717 value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
3721 case Dali::Actor::Property::PADDING:
3723 Vector2 widthPadding = GetPadding( Dimension::WIDTH );
3724 Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
3725 value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
3729 case Dali::Actor::Property::MINIMUM_SIZE:
3731 value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
3735 case Dali::Actor::Property::MAXIMUM_SIZE:
3737 value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
3741 case Dali::Actor::Property::CLIPPING_MODE:
3743 value = mClippingMode;
3747 case Dali::DevelActor::Property::SIBLING_ORDER:
3749 value = static_cast<int>( GetSiblingOrder() );
3753 case Dali::DevelActor::Property::SCREEN_POSITION:
3755 value = GetCurrentScreenPosition();
3759 case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
3761 value = mPositionUsesAnchorPoint;
3765 case Dali::Actor::Property::LAYOUT_DIRECTION:
3767 value = mLayoutDirection;
3771 case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
3773 value = IsLayoutDirectionInherited();
3779 // Must be a scene-graph only property
3788 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
3790 bool valueSet = true;
3794 case Dali::Actor::Property::SIZE:
3796 value = GetCurrentSize();
3800 case Dali::Actor::Property::SIZE_WIDTH:
3802 value = GetCurrentSize().width;
3806 case Dali::Actor::Property::SIZE_HEIGHT:
3808 value = GetCurrentSize().height;
3812 case Dali::Actor::Property::SIZE_DEPTH:
3814 value = GetCurrentSize().depth;
3818 case Dali::Actor::Property::POSITION:
3820 value = GetCurrentPosition();
3824 case Dali::Actor::Property::POSITION_X:
3826 value = GetCurrentPosition().x;
3830 case Dali::Actor::Property::POSITION_Y:
3832 value = GetCurrentPosition().y;
3836 case Dali::Actor::Property::POSITION_Z:
3838 value = GetCurrentPosition().z;
3842 case Dali::Actor::Property::WORLD_POSITION:
3844 value = GetCurrentWorldPosition();
3848 case Dali::Actor::Property::WORLD_POSITION_X:
3850 value = GetCurrentWorldPosition().x;
3854 case Dali::Actor::Property::WORLD_POSITION_Y:
3856 value = GetCurrentWorldPosition().y;
3860 case Dali::Actor::Property::WORLD_POSITION_Z:
3862 value = GetCurrentWorldPosition().z;
3866 case Dali::Actor::Property::ORIENTATION:
3868 value = GetCurrentOrientation();
3872 case Dali::Actor::Property::WORLD_ORIENTATION:
3874 value = GetCurrentWorldOrientation();
3878 case Dali::Actor::Property::SCALE:
3880 value = GetCurrentScale();
3884 case Dali::Actor::Property::SCALE_X:
3886 value = GetCurrentScale().x;
3890 case Dali::Actor::Property::SCALE_Y:
3892 value = GetCurrentScale().y;
3896 case Dali::Actor::Property::SCALE_Z:
3898 value = GetCurrentScale().z;
3902 case Dali::Actor::Property::WORLD_SCALE:
3904 value = GetCurrentWorldScale();
3908 case Dali::Actor::Property::COLOR:
3910 value = GetCurrentColor();
3914 case Dali::Actor::Property::COLOR_RED:
3916 value = GetCurrentColor().r;
3920 case Dali::Actor::Property::COLOR_GREEN:
3922 value = GetCurrentColor().g;
3926 case Dali::Actor::Property::COLOR_BLUE:
3928 value = GetCurrentColor().b;
3932 case Dali::Actor::Property::COLOR_ALPHA:
3933 case Dali::DevelActor::Property::OPACITY:
3935 value = GetCurrentColor().a;
3939 case Dali::Actor::Property::WORLD_COLOR:
3941 value = GetCurrentWorldColor();
3945 case Dali::Actor::Property::WORLD_MATRIX:
3947 value = GetCurrentWorldMatrix();
3951 case Dali::Actor::Property::VISIBLE:
3953 value = IsVisible();
3957 case DevelActor::Property::CULLED:
3959 value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() );
3965 // Must be an event-side only property
3974 void Actor::EnsureRelayoutData()
3976 // Assign relayout data.
3977 if( !mRelayoutData )
3979 mRelayoutData = new RelayoutData();
3983 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
3985 // Check if actor is dependent on parent
3986 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
3988 if( ( dimension & ( 1 << i ) ) )
3990 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
3991 if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
4001 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
4003 // Check if actor is dependent on children
4004 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4006 if( ( dimension & ( 1 << i ) ) )
4008 const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
4009 switch( resizePolicy )
4011 case ResizePolicy::FIT_TO_CHILDREN:
4012 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
4028 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
4030 return Actor::RelayoutDependentOnChildren( dimension );
4033 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
4035 // Check each possible dimension and see if it is dependent on the input one
4036 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4038 if( dimension & ( 1 << i ) )
4040 return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
4047 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
4049 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4051 if( dimension & ( 1 << i ) )
4053 mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
4058 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
4060 // If more than one dimension is requested, just return the first one found
4061 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4063 if( ( dimension & ( 1 << i ) ) )
4065 return mRelayoutData->negotiatedDimensions[ i ];
4069 return 0.0f; // Default
4072 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
4074 EnsureRelayoutData();
4076 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4078 if( dimension & ( 1 << i ) )
4080 mRelayoutData->dimensionPadding[ i ] = padding;
4085 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
4087 if ( mRelayoutData )
4089 // If more than one dimension is requested, just return the first one found
4090 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4092 if( ( dimension & ( 1 << i ) ) )
4094 return mRelayoutData->dimensionPadding[ i ];
4099 return GetDefaultDimensionPadding();
4102 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
4104 EnsureRelayoutData();
4106 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4108 if( dimension & ( 1 << i ) )
4110 mRelayoutData->dimensionNegotiated[ i ] = negotiated;
4115 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
4117 if ( mRelayoutData )
4119 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4121 if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
4131 float Actor::GetHeightForWidthBase( float width )
4133 float height = 0.0f;
4135 const Vector3 naturalSize = GetNaturalSize();
4136 if( naturalSize.width > 0.0f )
4138 height = naturalSize.height * width / naturalSize.width;
4140 else // we treat 0 as 1:1 aspect ratio
4148 float Actor::GetWidthForHeightBase( float height )
4152 const Vector3 naturalSize = GetNaturalSize();
4153 if( naturalSize.height > 0.0f )
4155 width = naturalSize.width * height / naturalSize.height;
4157 else // we treat 0 as 1:1 aspect ratio
4165 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
4167 // Fill to parent, taking size mode factor into account
4168 switch( child.GetResizePolicy( dimension ) )
4170 case ResizePolicy::FILL_TO_PARENT:
4172 return GetLatestSize( dimension );
4175 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4177 return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
4180 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4182 return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
4187 return GetLatestSize( dimension );
4192 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
4194 // Can be overridden in derived class
4195 return CalculateChildSizeBase( child, dimension );
4198 float Actor::GetHeightForWidth( float width )
4200 // Can be overridden in derived class
4201 return GetHeightForWidthBase( width );
4204 float Actor::GetWidthForHeight( float height )
4206 // Can be overridden in derived class
4207 return GetWidthForHeightBase( height );
4210 float Actor::GetLatestSize( Dimension::Type dimension ) const
4212 return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
4215 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
4217 Vector2 padding = GetPadding( dimension );
4219 return GetLatestSize( dimension ) + padding.x + padding.y;
4222 float Actor::NegotiateFromParent( Dimension::Type dimension )
4224 Actor* parent = GetParent();
4227 Vector2 padding( GetPadding( dimension ) );
4228 Vector2 parentPadding( parent->GetPadding( dimension ) );
4229 return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
4235 float Actor::NegotiateFromChildren( Dimension::Type dimension )
4237 float maxDimensionPoint = 0.0f;
4239 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4241 ActorPtr child = GetChildAt( i );
4243 if( !child->RelayoutDependentOnParent( dimension ) )
4245 // Calculate the min and max points that the children range across
4246 float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
4247 float dimensionSize = child->GetRelayoutSize( dimension );
4248 maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
4252 return maxDimensionPoint;
4255 float Actor::GetSize( Dimension::Type dimension ) const
4257 return GetDimensionValue( mTargetSize, dimension );
4260 float Actor::GetNaturalSize( Dimension::Type dimension ) const
4262 return GetDimensionValue( GetNaturalSize(), dimension );
4265 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
4267 switch( GetResizePolicy( dimension ) )
4269 case ResizePolicy::USE_NATURAL_SIZE:
4271 return GetNaturalSize( dimension );
4274 case ResizePolicy::FIXED:
4276 return GetDimensionValue( GetPreferredSize(), dimension );
4279 case ResizePolicy::USE_ASSIGNED_SIZE:
4281 return GetDimensionValue( maximumSize, dimension );
4284 case ResizePolicy::FILL_TO_PARENT:
4285 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
4286 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
4288 return NegotiateFromParent( dimension );
4291 case ResizePolicy::FIT_TO_CHILDREN:
4293 return NegotiateFromChildren( dimension );
4296 case ResizePolicy::DIMENSION_DEPENDENCY:
4298 const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
4301 if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
4303 return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
4306 if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
4308 return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
4320 return 0.0f; // Default
4323 float Actor::ClampDimension( float size, Dimension::Type dimension )
4325 const float minSize = GetMinimumSize( dimension );
4326 const float maxSize = GetMaximumSize( dimension );
4328 return std::max( minSize, std::min( size, maxSize ) );
4331 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
4333 // Check if it needs to be negotiated
4334 if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
4336 // Check that we havn't gotten into an infinite loop
4337 ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
4338 bool recursionFound = false;
4339 for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
4341 if( *it == searchActor )
4343 recursionFound = true;
4348 if( !recursionFound )
4350 // Record the path that we have taken
4351 recursionStack.push_back( ActorDimensionPair( this, dimension ) );
4353 // Dimension dependency check
4354 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4356 Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
4358 if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
4360 NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
4364 // Parent dependency check
4365 Actor* parent = GetParent();
4366 if( parent && RelayoutDependentOnParent( dimension ) )
4368 parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
4371 // Children dependency check
4372 if( RelayoutDependentOnChildren( dimension ) )
4374 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4376 ActorPtr child = GetChildAt( i );
4378 // Only relayout child first if it is not dependent on this actor
4379 if( !child->RelayoutDependentOnParent( dimension ) )
4381 child->NegotiateDimension( dimension, allocatedSize, recursionStack );
4386 // For deriving classes
4387 OnCalculateRelayoutSize( dimension );
4389 // All dependencies checked, calculate the size and set negotiated flag
4390 const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension );
4392 SetNegotiatedDimension( newSize, dimension );
4393 SetLayoutNegotiated( true, dimension );
4395 // For deriving classes
4396 OnLayoutNegotiated( newSize, dimension );
4398 // This actor has been successfully processed, pop it off the recursion stack
4399 recursionStack.pop_back();
4403 // TODO: Break infinite loop
4404 SetLayoutNegotiated( true, dimension );
4409 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
4411 // Negotiate all dimensions that require it
4412 ActorDimensionStack recursionStack;
4414 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4416 const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
4419 NegotiateDimension( dimension, allocatedSize, recursionStack );
4423 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
4425 switch( mRelayoutData->sizeSetPolicy )
4427 case SizeScalePolicy::USE_SIZE_SET:
4432 case SizeScalePolicy::FIT_WITH_ASPECT_RATIO:
4434 // Scale size to fit within the original size bounds, keeping the natural size aspect ratio
4435 const Vector3 naturalSize = GetNaturalSize();
4436 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4438 const float sizeRatio = size.width / size.height;
4439 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4441 if( naturalSizeRatio < sizeRatio )
4443 return Vector2( naturalSizeRatio * size.height, size.height );
4445 else if( naturalSizeRatio > sizeRatio )
4447 return Vector2( size.width, size.width / naturalSizeRatio );
4458 case SizeScalePolicy::FILL_WITH_ASPECT_RATIO:
4460 // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds.
4461 const Vector3 naturalSize = GetNaturalSize();
4462 if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f )
4464 const float sizeRatio = size.width / size.height;
4465 const float naturalSizeRatio = naturalSize.width / naturalSize.height;
4467 if( naturalSizeRatio < sizeRatio )
4469 return Vector2( size.width, size.width / naturalSizeRatio );
4471 else if( naturalSizeRatio > sizeRatio )
4473 return Vector2( naturalSizeRatio * size.height, size.height );
4492 void Actor::SetNegotiatedSize( RelayoutContainer& container )
4494 // Do the set actor size
4495 Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
4497 // Adjust for size set policy
4498 negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
4500 // Lock the flag to stop recursive relayouts on set size
4501 mRelayoutData->insideRelayout = true;
4502 SetSize( negotiatedSize );
4503 mRelayoutData->insideRelayout = false;
4505 // Clear flags for all dimensions
4506 SetLayoutDirty( false );
4508 // Give deriving classes a chance to respond
4509 OnRelayout( negotiatedSize, container );
4511 if( !mOnRelayoutSignal.Empty() )
4513 Dali::Actor handle( this );
4514 mOnRelayoutSignal.Emit( handle );
4518 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
4520 // Force a size negotiation for actors that has assigned size during relayout
4521 // This is required as otherwise the flags that force a relayout will not
4522 // necessarilly be set. This will occur if the actor has already been laid out.
4523 // The dirty flags are then cleared. Then if the actor is added back into the
4524 // relayout container afterwards, the dirty flags would still be clear...
4525 // causing a relayout to be skipped. Here we force any actors added to the
4526 // container to be relayed out.
4527 DALI_LOG_TIMER_START( NegSizeTimer1 );
4529 if( GetUseAssignedSize(Dimension::WIDTH ) )
4531 SetLayoutNegotiated( false, Dimension::WIDTH );
4533 if( GetUseAssignedSize( Dimension::HEIGHT ) )
4535 SetLayoutNegotiated( false, Dimension::HEIGHT );
4538 // Do the negotiation
4539 NegotiateDimensions( allocatedSize );
4541 // Set the actor size
4542 SetNegotiatedSize( container );
4544 // Negotiate down to children
4545 for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
4547 ActorPtr child = GetChildAt( i );
4549 // Forces children that have already been laid out to be relayed out
4550 // if they have assigned size during relayout.
4551 if( child->GetUseAssignedSize(Dimension::WIDTH) )
4553 child->SetLayoutNegotiated(false, Dimension::WIDTH);
4554 child->SetLayoutDirty(true, Dimension::WIDTH);
4557 if( child->GetUseAssignedSize(Dimension::HEIGHT) )
4559 child->SetLayoutNegotiated(false, Dimension::HEIGHT);
4560 child->SetLayoutDirty(true, Dimension::HEIGHT);
4563 // Only relayout if required
4564 if( child->RelayoutRequired() )
4566 container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
4569 DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
4572 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
4576 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4578 if( dimension & ( 1 << i ) )
4580 mRelayoutData->useAssignedSize[ i ] = use;
4586 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
4588 if ( mRelayoutData )
4590 // If more than one dimension is requested, just return the first one found
4591 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4593 if( dimension & ( 1 << i ) )
4595 return mRelayoutData->useAssignedSize[ i ];
4603 void Actor::RelayoutRequest( Dimension::Type dimension )
4605 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
4606 if( relayoutController )
4608 Dali::Actor self( this );
4609 relayoutController->RequestRelayout( self, dimension );
4613 void Actor::OnCalculateRelayoutSize( Dimension::Type dimension )
4617 void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension )
4621 void Actor::SetPreferredSize( const Vector2& size )
4623 EnsureRelayoutData();
4625 if( size.width > 0.0f )
4627 SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
4630 if( size.height > 0.0f )
4632 SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
4635 mRelayoutData->preferredSize = size;
4640 Vector2 Actor::GetPreferredSize() const
4642 if ( mRelayoutData )
4644 return Vector2( mRelayoutData->preferredSize );
4647 return GetDefaultPreferredSize();
4650 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
4652 EnsureRelayoutData();
4654 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4656 if( dimension & ( 1 << i ) )
4658 mRelayoutData->minimumSize[ i ] = size;
4665 float Actor::GetMinimumSize( Dimension::Type dimension ) const
4667 if ( mRelayoutData )
4669 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4671 if( dimension & ( 1 << i ) )
4673 return mRelayoutData->minimumSize[ i ];
4678 return 0.0f; // Default
4681 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
4683 EnsureRelayoutData();
4685 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4687 if( dimension & ( 1 << i ) )
4689 mRelayoutData->maximumSize[ i ] = size;
4696 float Actor::GetMaximumSize( Dimension::Type dimension ) const
4698 if ( mRelayoutData )
4700 for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
4702 if( dimension & ( 1 << i ) )
4704 return mRelayoutData->maximumSize[ i ];
4709 return FLT_MAX; // Default
4712 Object* Actor::GetParentObject() const
4717 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
4719 if( mVisible != visible )
4721 if( sendMessage == SendMessage::TRUE )
4723 // node is being used in a separate thread; queue a message to set the value & base value
4724 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
4729 // Emit the signal on this actor and all its children
4730 EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
4734 void Actor::SetSiblingOrder( uint32_t order )
4738 ActorContainer& siblings = *(mParent->mChildren);
4739 uint32_t currentOrder = GetSiblingOrder();
4741 if( order != currentOrder )
4747 else if( order < siblings.size() -1 )
4749 if( order > currentOrder )
4751 RaiseAbove( *siblings[order] );
4755 LowerBelow( *siblings[order] );
4766 uint32_t Actor::GetSiblingOrder() const
4772 ActorContainer& siblings = *(mParent->mChildren);
4773 for( std::size_t i = 0; i < siblings.size(); ++i )
4775 if( siblings[i] == this )
4777 order = static_cast<uint32_t>( i );
4786 void Actor::RequestRebuildDepthTree()
4792 mScene->RequestRebuildDepthTree();
4801 ActorContainer& siblings = *(mParent->mChildren);
4802 if( siblings.back() != this ) // If not already at end
4804 for( std::size_t i=0; i<siblings.size(); ++i )
4806 if( siblings[i] == this )
4809 ActorPtr next = siblings[i+1];
4810 siblings[i+1] = this;
4817 Dali::Actor handle( this );
4818 mParent->mChildOrderChangedSignal.Emit( handle );
4820 RequestRebuildDepthTree();
4824 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4832 ActorContainer& siblings = *(mParent->mChildren);
4833 if( siblings.front() != this ) // If not already at beginning
4835 for( std::size_t i=1; i<siblings.size(); ++i )
4837 if( siblings[i] == this )
4839 // Swap with previous
4840 ActorPtr previous = siblings[i-1];
4841 siblings[i-1] = this;
4842 siblings[i] = previous;
4848 Dali::Actor handle( this );
4849 mParent->mChildOrderChangedSignal.Emit( handle );
4851 RequestRebuildDepthTree();
4855 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4859 void Actor::RaiseToTop()
4863 ActorContainer& siblings = *(mParent->mChildren);
4864 if( siblings.back() != this ) // If not already at end
4866 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4867 if( iter != siblings.end() )
4869 siblings.erase(iter);
4870 siblings.push_back(ActorPtr(this));
4874 Dali::Actor handle( this );
4875 mParent->mChildOrderChangedSignal.Emit( handle );
4877 RequestRebuildDepthTree();
4881 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4885 void Actor::LowerToBottom()
4889 ActorContainer& siblings = *(mParent->mChildren);
4890 if( siblings.front() != this ) // If not already at bottom,
4892 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4894 ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
4895 if( iter != siblings.end() )
4897 siblings.erase(iter);
4898 siblings.insert(siblings.begin(), thisPtr);
4902 Dali::Actor handle( this );
4903 mParent->mChildOrderChangedSignal.Emit( handle );
4905 RequestRebuildDepthTree();
4909 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4913 void Actor::RaiseAbove( Internal::Actor& target )
4917 ActorContainer& siblings = *(mParent->mChildren);
4918 if( siblings.back() != this && target.mParent == mParent ) // If not already at top
4920 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4922 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
4923 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
4924 if( thisIter < targetIter )
4926 siblings.erase(thisIter);
4927 // Erasing early invalidates the targetIter. (Conversely, inserting first may also
4928 // invalidate thisIter)
4929 targetIter = std::find( siblings.begin(), siblings.end(), &target );
4931 siblings.insert(targetIter, thisPtr);
4934 Dali::Actor handle( this );
4935 mParent->mChildOrderChangedSignal.Emit( handle );
4937 RequestRebuildDepthTree();
4942 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4946 void Actor::LowerBelow( Internal::Actor& target )
4950 ActorContainer& siblings = *(mParent->mChildren);
4951 if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
4953 ActorPtr thisPtr(this); // ensure this actor remains referenced.
4955 ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
4956 ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
4958 if( thisIter > targetIter )
4960 siblings.erase(thisIter); // this only invalidates iterators at or after this point.
4961 siblings.insert(targetIter, thisPtr);
4964 Dali::Actor handle( this );
4965 mParent->mChildOrderChangedSignal.Emit( handle );
4967 RequestRebuildDepthTree();
4972 DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
4976 void Actor::SetScene( Scene& scene )
4981 Scene& Actor::GetScene() const
4986 void Actor::SetInheritLayoutDirection( bool inherit )
4988 if( mInheritLayoutDirection != inherit )
4990 mInheritLayoutDirection = inherit;
4992 if( inherit && mParent )
4994 InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
4999 bool Actor::IsLayoutDirectionInherited() const
5001 return mInheritLayoutDirection;
5004 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
5006 if( actor && ( actor->mInheritLayoutDirection || set ) )
5008 if( actor->mLayoutDirection != direction )
5010 actor->mLayoutDirection = direction;
5011 actor->EmitLayoutDirectionChangedSignal( direction );
5012 actor->RelayoutRequest();
5015 if( actor->GetChildCount() > 0 )
5017 ActorContainer& children = actor->GetChildrenInternal();
5018 for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
5020 InheritLayoutDirectionRecursively( *iter, direction );
5026 } // namespace Internal