-#ifndef __DALI_INTERNAL_ACTOR_H__
-#define __DALI_INTERNAL_ACTOR_H__
+#ifndef DALI_INTERNAL_ACTOR_H
+#define DALI_INTERNAL_ACTOR_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// INTERNAL INCLUDES
#include <dali/public-api/actors/actor.h>
+#include <dali/devel-api/actors/actor-devel.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/events/gesture.h>
#include <dali/public-api/math/viewport.h>
#include <dali/public-api/object/ref-object.h>
#include <dali/public-api/size-negotiation/relayout-container.h>
+#include <dali/internal/common/memory-pool-object-allocator.h>
#include <dali/internal/event/actors/actor-declarations.h>
-#include <dali/internal/event/actor-attachments/actor-attachment-declarations.h>
#include <dali/internal/event/common/object-impl.h>
#include <dali/internal/event/common/stage-def.h>
#include <dali/internal/event/rendering/renderer-impl.h>
{
struct KeyEvent;
-struct TouchEvent;
+class TouchData;
struct HoverEvent;
struct WheelEvent;
typedef std::vector< RendererPtr > RendererContainer;
typedef RendererContainer::iterator RendererIter;
+class ActorDepthTreeNode;
+typedef Dali::Internal::MemoryPoolObjectAllocator< ActorDepthTreeNode > DepthNodeMemoryPool;
+
/**
* Actor is the primary object which Dali applications interact with.
* UI controls can be built by combining multiple actors.
* Multi-Touch events are received through signals emitted by the actor tree.
*
* An Actor is a proxy for a Node in the scene graph.
- * When an Actor is added to the Stage, it creates a node and attaches it to the scene graph.
- * The scene-graph can be updated in a separate thread, so the attachment is done using an asynchronous message.
+ * When an Actor is added to the Stage, it creates a node and connects it to the scene graph.
+ * The scene-graph can be updated in a separate thread, so the connection is done using an asynchronous message.
* When a tree of Actors is detached from the Stage, a message is sent to destroy the associated nodes.
*/
class Actor : public Object
*/
unsigned int GetId() const;
- // Attachments
-
- /**
- * Attach an object to an actor.
- * @pre The actor does not already have an attachment.
- * @param[in] attachment The object to attach.
- */
- void Attach( ActorAttachment& attachment );
-
- /**
- * Retreive the object attached to an actor.
- * @return The attachment.
- */
- ActorAttachmentPtr GetAttachment();
-
// Containment
/**
* Retrieve a reference to Actor's children.
* @note Not for public use.
* @return A reference to the container of children.
+ * @note The internal container is lazily initialized so ensure you check the child count before using the value returned by this method.
*/
ActorContainer& GetChildrenInternal()
{
/**
* Sets the size of an actor.
- * ActorAttachments attached to the actor, can be scaled to fit within this area.
* This does not interfere with the actors scale factor.
* @param [in] width The new width.
* @param [in] height The new height.
/**
* Sets the size of an actor.
- * ActorAttachments attached to the actor, can be scaled to fit within this area.
* This does not interfere with the actors scale factor.
* @param [in] width The size of the actor along the x-axis.
* @param [in] height The size of the actor along the y-axis.
/**
* Sets the size of an actor.
- * ActorAttachments attached to the actor, can be scaled to fit within this area.
* This does not interfere with the actors scale factor.
* @param [in] size The new size.
*/
/**
* Sets the size of an actor.
- * ActorAttachments attached to the actor, can be scaled to fit within this area.
* This does not interfere with the actors scale factor.
* @param [in] size The new size.
*/
* This size will be the size set or if animating then the target size.
* @return The Actor's size.
*/
- const Vector3& GetTargetSize() const;
+ Vector3 GetTargetSize() const;
/**
* Retrieve the Actor's size from update side.
PositionInheritanceMode GetPositionInheritanceMode() const;
/**
+ * @copydoc Dali::Actor::SetInheritPosition()
+ */
+ void SetInheritPosition( bool inherit );
+
+ /**
+ * @copydoc Dali::Actor::IsPositionInherited()
+ */
+ bool IsPositionInherited() const;
+
+ /**
* Sets the orientation of the Actor.
* @param [in] angleRadians The new orientation angle in radians.
* @param [in] axis The new axis of orientation.
/**
* Sets the visibility flag of an actor.
- * @param [in] visible The new visibility flag.
+ * @param[in] visible The new visibility flag.
*/
void SetVisible( bool visible );
float GetCurrentOpacity() const;
/**
+ * Retrieve the actor's clipping mode.
+ * @return The actor's clipping mode (cached)
+ */
+ ClippingMode::Type GetClippingMode() const;
+
+ /**
* Sets whether an actor should emit touch or hover signals; see SignalTouch() and SignalHover().
* An actor is sensitive by default, which means that as soon as an application connects to the SignalTouch(),
* the touch event signal will be emitted, and as soon as an application connects to the SignalHover(), the
DrawMode::Type GetDrawMode() const;
/**
- * @copydoc Dali::Actor::SetOverlay
- */
- void SetOverlay( bool enable );
-
- /**
* @copydoc Dali::Actor::IsOverlay
*/
bool IsOverlay() const;
/**
* @copydoc Dali::Actor::GetHierarchyDepth()
*/
- int GetHierarchyDepth() const
+ inline int GetHierarchyDepth() const
{
if( mIsOnStage )
{
return -1;
}
+ /**
+ * Get the actor's sorting depth
+ *
+ * @return The depth used for hit-testing and renderer sorting
+ */
+ unsigned int GetSortingDepth();
+
public:
// Size negotiation virtual functions
void NegotiateSize( const Vector2& size, RelayoutContainer& container );
/**
+ * @brief Set whether size negotiation should use the assigned size of the actor
+ * during relayout for the given dimension(s)
+ *
+ * @param[in] use Whether the assigned size of the actor should be used
+ * @param[in] dimension The dimension(s) to set. Can be a bitfield of multiple dimensions
+ */
+ void SetUseAssignedSize( bool use, Dimension::Type dimension = Dimension::ALL_DIMENSIONS );
+
+ /**
+ * @brief Returns whether size negotiation should use the assigned size of the actor
+ * during relayout for a single dimension
+ *
+ * @param[in] dimension The dimension to get
+ * @return Return whether the assigned size of the actor should be used. If more than one dimension is requested, just return the first one found
+ */
+ bool GetUseAssignedSize( Dimension::Type dimension ) const;
+
+ /**
* @copydoc Dali::Actor::SetResizePolicy()
*/
void SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension = Dimension::ALL_DIMENSIONS );
* @copydoc Dali::Actor::GetMaximumSize
*/
float GetMaximumSize( Dimension::Type dimension ) const;
-
+
/**
* @copydoc Dali::Actor::AddRenderer()
*/
* @param[in] screenY The screen Y-coordinate.
* @return True if the conversion succeeded.
*/
- bool ScreenToLocal( RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const;
+ bool ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const;
/**
* Converts from the actor's coordinate system to screen coordinates.
*/
bool RayActorTest( const Vector4& rayOrigin,
const Vector4& rayDir,
- Vector4& hitPointLocal,
+ Vector2& hitPointLocal,
float& distance ) const;
/**
/**
* Used by the EventProcessor to emit touch event signals.
- * @param[in] event The touch event.
+ * @param[in] event The touch event (Old API).
+ * @param[in] touch The touch data.
* @return True if the event was consumed.
*/
- bool EmitTouchEventSignal( const TouchEvent& event );
+ bool EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch );
/**
* Used by the EventProcessor to emit hover event signals.
bool EmitWheelEventSignal( const WheelEvent& event );
/**
+ * @brief Emits the visibility change signal for this actor and all its children.
+ * @param[in] visible Whether the actor has become visible or not.
+ * @param[in] type Whether the actor's visible property has changed or a parent's.
+ */
+ void EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type );
+
+ /**
* @copydoc Dali::Actor::TouchedSignal()
*/
Dali::Actor::TouchSignalType& TouchedSignal();
/**
+ * @copydoc Dali::Actor::TouchEventSignal()
+ */
+ Dali::Actor::TouchDataSignalType& TouchSignal();
+
+ /**
* @copydoc Dali::Actor::HoveredSignal()
*/
Dali::Actor::HoverSignalType& HoveredSignal();
Dali::Actor::OnRelayoutSignalType& OnRelayoutSignal();
/**
+ * @copydoc DevelActor::VisibilityChangedSignal
+ */
+ DevelActor::VisibilityChangedSignalType& VisibilityChangedSignal();
+
+ /**
* Connects a callback function with the object's signals.
* @param[in] object The object providing the signal.
* @param[in] tracker Used to disconnect the signal.
// For Animation
/**
- * This should only be called by Animation, when the actors SIZE property is animated.
- *
- * @param[in] animation The animation that resized the actor
- * @param[in] targetSize The new target size of the actor
- */
- void NotifySizeAnimation( Animation& animation, const Vector3& targetSize );
-
- /**
- * This should only be called by Animation, when the actors SIZE_WIDTH or SIZE_HEIGHT property is animated.
- *
- * @param[in] animation The animation that resized the actor
- * @param[in] targetSize The new target size of the actor
- */
- void NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property );
-
- /**
* For use in derived classes.
* This should only be called by Animation, when the actor is resized using Animation::Resize().
*/
bool IsNodeConnected() const;
public:
+ /**
+ * Trigger a rebuild of the actor depth tree from this root
+ * If a Layer3D is encountered, then this doesn't descend any further.
+ * The mSortedDepth of each actor is set appropriately.
+ */
+ void RebuildDepthTree();
+
+protected:
+
+ /**
+ * Traverse the actor tree, inserting actors into the depth tree in sibling order.
+ * For all actors that share a sibling order, they also share a depth tree, for
+ * optimal render performance.
+ * @param[in] nodeMemoryPool The memory pool used to allocate depth nodes
+ * @param[in,out] depthTreeNode The depth tree node to which to add this actor's children
+ * @return The count of actors in this depth tree
+ */
+ int BuildDepthTree( DepthNodeMemoryPool& nodeMemoryPool, ActorDepthTreeNode* depthTreeNode );
+
+public:
// Default property extensions from Object
virtual Property::Value GetDefaultProperty( Property::Index index ) const;
/**
+ * @copydoc Dali::Internal::Object::GetDefaultPropertyCurrentValue()
+ */
+ virtual Property::Value GetDefaultPropertyCurrentValue( Property::Index index ) const;
+
+ /**
+ * @copydoc Dali::Internal::Object::OnNotifyDefaultPropertyAnimation()
+ */
+ virtual void OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value );
+
+ /**
* @copydoc Dali::Internal::Object::GetPropertyOwner()
*/
virtual const SceneGraph::PropertyOwner* GetPropertyOwner() const;
*/
virtual int GetPropertyComponentIndex( Property::Index index ) const;
+ /**
+ * @copydoc Dali::DevelActor::Raise()
+ */
+ void Raise();
+
+ /**
+ * @copydoc Dali::DevelActor::Lower()
+ */
+ void Lower();
+
+ /**
+ * @copydoc Dali::DevelActor::RaiseToTop()
+ */
+ void RaiseToTop();
+
+ /**
+ * @copydoc Dali::DevelActor::LowerToBottom()
+ */
+ void LowerToBottom();
+
+ /**
+ * @copydoc Dali::DevelActor::RaiseAbove()
+ */
+ void RaiseAbove( Internal::Actor& target );
+
+ /**
+ * @copydoc Dali::DevelActor::LowerBelow()
+ */
+ void LowerBelow( Internal::Actor& target );
+
private:
+ struct SendMessage
+ {
+ enum Type
+ {
+ FALSE = 0,
+ TRUE = 1,
+ };
+ };
+
// Undefined
Actor();
}
/**
- * For use in derived classes; this is called after Remove() has removed a child.
+ * For use in derived classes; this is called after Remove() has attempted to remove a child( regardless of whether it succeeded or not ).
* @param[in] child The child that was removed.
*/
virtual void OnChildRemove( Actor& child )
}
/**
+ * @brief Retrieves the cached event side value of a default property.
+ * @param[in] index The index of the property
+ * @param[out] value Is set with the cached value of the property if found.
+ * @return True if value set, false otherwise.
+ */
+ bool GetCachedPropertyValue( Property::Index index, Property::Value& value ) const;
+
+ /**
+ * @brief Retrieves the current value of a default property from the scene-graph.
+ * @param[in] index The index of the property
+ * @param[out] value Is set with the current scene-graph value of the property
+ * @return True if value set, false otherwise.
+ */
+ bool GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const;
+
+ /**
* @brief Ensure the relayout data is allocated
*/
void EnsureRelayoutData();
*/
Vector2 ApplySizeSetPolicy( const Vector2 size );
+ /**
+ * Retrieve the parent object of an Actor.
+ * @return The parent object, or NULL if the Actor does not have a parent.
+ */
+ virtual Object* GetParentObject() const;
+
+ /**
+ * Set Sibling order
+ * @param[in] order The sibling order this Actor should be
+ */
+ void SetSiblingOrder( unsigned int order);
+
+ /**
+ * @brief Re-orders the sibling order when any actor raised to the max level
+ * @param[in] siblings the container of sibling actors
+ */
+ void DefragmentSiblingIndexes( ActorContainer& siblings );
+
+ /**
+ * @brief Shifts all siblings levels from the target level up by 1 to make space for a newly insert sibling
+ * at an exclusive level.
+ *
+ * @note Used with Raise and Lower API
+ *
+ * @param[in] siblings the actor container of the siblings
+ * @param[in] targetLevelToShiftFrom the sibling level to start shifting from
+ */
+ bool ShiftSiblingsLevels( ActorContainer& siblings, int targetLevelToShiftFrom );
+
+ /**
+ * @brief Get the current position of the actor in screen coordinates.
+ *
+ * @return Returns the screen position of actor
+ */
+ const Vector2 GetCurrentScreenPosition() const;
+
+ /**
+ * Sets the visibility flag of an actor.
+ * @param[in] visible The new visibility flag.
+ * @param[in] sendMessage Whether to send a message to the update thread or not.
+ */
+ void SetVisibleInternal( bool visible, SendMessage::Type sendMessage );
+
protected:
Actor* mParent; ///< Each actor (except the root) can have one parent
- ActorContainer* mChildren; ///< Container of referenced actors
+ ActorContainer* mChildren; ///< Container of referenced actors, lazily initialized
RendererContainer* mRenderers; ///< Renderer container
const SceneGraph::Node* mNode; ///< Not owned
ActorGestureData* mGestureData; ///< Optional Gesture data. Only created when actor requires gestures
- ActorAttachmentPtr mAttachment; ///< Optional referenced attachment
-
// Signals
Dali::Actor::TouchSignalType mTouchedSignal;
+ Dali::Actor::TouchDataSignalType mTouchSignal;
Dali::Actor::HoverSignalType mHoveredSignal;
Dali::Actor::WheelEventSignalType mWheelEventSignal;
Dali::Actor::OnStageSignalType mOnStageSignal;
Dali::Actor::OffStageSignalType mOffStageSignal;
Dali::Actor::OnRelayoutSignalType mOnRelayoutSignal;
+ DevelActor::VisibilityChangedSignalType mVisibilityChangedSignal;
- Vector3 mTargetSize; ///< Event-side storage for size (not a pointer as most actors will have a size)
- Vector3 mTargetPosition; ///< Event-side storage for position (not a pointer as most actors will have a position)
+ Quaternion mTargetOrientation; ///< Event-side storage for orientation
+ Vector4 mTargetColor; ///< Event-side storage for color
+ Vector3 mTargetSize; ///< Event-side storage for size (not a pointer as most actors will have a size)
+ Vector3 mTargetPosition; ///< Event-side storage for position (not a pointer as most actors will have a position)
+ Vector3 mTargetScale; ///< Event-side storage for scale
std::string mName; ///< Name of the actor
unsigned int mId; ///< A unique ID to identify the actor starting from 1, and 0 is reserved
- unsigned short mDepth :12; ///< Cached: The depth in the hierarchy of the actor. Only 4096 levels of depth are supported
+ uint32_t mSortedDepth; ///< The sorted depth index. A combination of tree traversal and sibling order.
+ uint16_t mDepth; ///< The depth in the hierarchy of the actor. Only 4096 levels of depth are supported
+ uint16_t mSiblingOrder; ///< The sibling order of the actor
+
const bool mIsRoot : 1; ///< Flag to identify the root actor
const bool mIsLayer : 1; ///< Flag to identify that this is a layer
bool mIsOnStage : 1; ///< Flag to identify whether the actor is on-stage
bool mDerivedRequiresWheelEvent : 1; ///< Whether the derived actor type requires wheel event signals
bool mOnStageSignalled : 1; ///< Set to true before OnStageConnection signal is emitted, and false before OnStageDisconnection
bool mInsideOnSizeSet : 1; ///< Whether we are inside OnSizeSet
+ bool mInheritPosition : 1; ///< Cached: Whether the parent's position should be inherited.
bool mInheritOrientation : 1; ///< Cached: Whether the parent's orientation should be inherited.
bool mInheritScale : 1; ///< Cached: Whether the parent's scale should be inherited.
+ bool mPositionUsesAnchorPoint : 1; ///< Cached: Whether the position uses the anchor point or not.
+ bool mVisible : 1; ///< Cached: Whether the actor is visible or not.
DrawMode::Type mDrawMode : 2; ///< Cached: How the actor and its children should be drawn
PositionInheritanceMode mPositionInheritanceMode : 2; ///< Cached: Determines how position is inherited
ColorMode mColorMode : 2; ///< Cached: Determines whether mWorldColor is inherited
+ ClippingMode::Type mClippingMode : 2; ///< Cached: Determines which clipping mode (if any) to use.
private:
static ActorContainer mNullChildren; ///< Empty container (shared by all actors, returned by GetChildren() const)
static unsigned int mActorCounter; ///< A counter to track the actor instance creation
+};
+
+/**
+ * Helper class to create sorted depth index
+ */
+class ActorDepthTreeNode
+{
+public:
+ ActorDepthTreeNode()
+ : mParentNode(NULL),
+ mNextSiblingNode(NULL),
+ mFirstChildNode(NULL),
+ mSiblingOrder( 0 )
+ {
+ }
+
+ ActorDepthTreeNode( Actor* actor, uint16_t siblingOrder )
+ : mParentNode(NULL),
+ mNextSiblingNode(NULL),
+ mFirstChildNode(NULL),
+ mSiblingOrder( siblingOrder )
+ {
+ mActors.push_back( actor );
+ }
+
+ ~ActorDepthTreeNode()
+ {
+ if( mFirstChildNode )
+ {
+ delete mFirstChildNode;
+ mFirstChildNode = NULL;
+ }
+ if( mNextSiblingNode )
+ {
+ delete mNextSiblingNode;
+ mNextSiblingNode = NULL;
+ }
+ mParentNode = NULL;
+ }
+
+ uint16_t GetSiblingOrder()
+ {
+ return mSiblingOrder;
+ }
+
+ void AddActor( Actor* actor )
+ {
+ mActors.push_back( actor );
+ }
+public:
+ std::vector<Actor*> mActors; // Array of actors with the same sibling order and same ancestor sibling orders
+ ActorDepthTreeNode* mParentNode;
+ ActorDepthTreeNode* mNextSiblingNode;
+ ActorDepthTreeNode* mFirstChildNode;
+ uint16_t mSiblingOrder;
+
+private:
+ ActorDepthTreeNode( ActorDepthTreeNode& );
+ ActorDepthTreeNode& operator=(const ActorDepthTreeNode& );
};
+
} // namespace Internal
// Helpers for public-api forwarding methods
} // namespace Dali
-#endif // __DALI_INTERNAL_ACTOR_H__
+#endif // DALI_INTERNAL_ACTOR_H