From 3b671bbb975502ba2b37f1ae826871174e069bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 27 Feb 2026 00:22:58 -0300 Subject: [PATCH] Added documentation to Node, UINode, UIWidget, SceneNode and UISceneNode with the help of AI + human supervision (hopefully I didn't miss any important detail). I chose these classes given that they are core classes of the UI framework. --- bin/assets/colorschemes/colorschemes.conf | 1 - include/eepp/scene/node.hpp | 1964 ++++++++++++++++++++- include/eepp/scene/scenenode.hpp | 308 +++- include/eepp/ui/uinode.hpp | 1449 ++++++++++++++- include/eepp/ui/uiscenenode.hpp | 711 +++++++- include/eepp/ui/uiwidget.hpp | 1236 ++++++++++++- src/eepp/scene/scenenode.cpp | 6 +- src/eepp/ui/uiscenenode.cpp | 15 +- 8 files changed, 5608 insertions(+), 82 deletions(-) diff --git a/bin/assets/colorschemes/colorschemes.conf b/bin/assets/colorschemes/colorschemes.conf index b4b0fd460..e4247a865 100644 --- a/bin/assets/colorschemes/colorschemes.conf +++ b/bin/assets/colorschemes/colorschemes.conf @@ -307,7 +307,6 @@ literal = #ea5964 string = #ea5964 operator = #657085 function = #ffffff -preprocessor = #98c875 [monodark] background = #080808 diff --git a/include/eepp/scene/node.hpp b/include/eepp/scene/node.hpp index 77c5ddf0e..aa462f250 100644 --- a/include/eepp/scene/node.hpp +++ b/include/eepp/scene/node.hpp @@ -31,6 +31,21 @@ using namespace EE::Scene; namespace EE { namespace Scene { +/** + * @enum NodeFlags + * @brief Bitmask flags used to control and track node state. + * + * These flags control various aspects of node behavior + * and state. They can be combined using bitwise operations. + * + * The flags are divided into categories: + * - Update and dirty flags (position, polygon, view) + * - Transformation flags (rotation, scale) + * - State flags (mouse over, focus, selected, dragging) + * - Rendering flags (reverse draw, frame buffer, clip enable) + * - Type identification flags (SceneNode, UISceneNode, UINode, Widget, Window) + * - Layout and behavior flags + */ enum NodeFlags { NODE_FLAG_SCHEDULED_UPDATE = ( 1 << 0 ), NODE_FLAG_VIEW_DIRTY = ( 1 << 1 ), @@ -67,205 +82,919 @@ enum NodeFlags { NODE_FLAG_FREE_USE = ( 1 << 30 ) }; +/** + * @brief Core node class for scene graph management. + * + * Node is the fundamental building block for the scene graph system. It provides + * hierarchical organization with parent-child relationships, transformation support + * (position, rotation, scale), event handling, and rendering capabilities. + * + * Nodes can be used for general scene management or as base classes for specialized + * nodes like SceneNode and UISceneNode. The class supports both simple scene + * composition and complex UI hierarchies. + * + * Key features: + * - Hierarchical parent-child relationships + * - 2D transformations (position, rotation, scale) + * - Event system with callbacks + * - Action system for animations and timed operations + * - Coordinate space conversion + * - Visibility and enabled state management + * - Drawing with optional clipping and reverse order + * - Dirty flag system for efficient updates + * + * @see SceneNode + * @see UISceneNode + * @see UIWidget + */ class EE_API Node : public Transformable { public: + /** + * @brief Creates a new Node instance. + * + * This factory method creates a new Node with default values. Direct instantiation + * of Node is uncommon; typically derived classes like SceneNode or UIWidget are used. + * + * @return Pointer to the newly created Node instance. + */ static Node* New(); typedef std::function EventCallback; + /** + * @brief Destructor. + * + * Cleans up the node and its children, removes it from parent, and handles + * cleanup of actions, event listeners, and focus state. + */ virtual ~Node(); + /** + * @brief Transforms a world position to node-local position. + * + * Converts a world coordinate position to this node's local coordinate space + * by subtracting the positions of all parent nodes up to the root. + * + * @param position Reference to the position to transform (modified in place). + */ virtual void worldToNodeTranslation( Vector2f& position ) const; + /** + * @brief Transforms a node-local position to world position. + * + * Converts a node-local coordinate position to world coordinate space + * by adding the positions of all parent nodes. + * + * @param position Reference to the position to transform (modified in place). + */ virtual void nodeToWorldTranslation( Vector2f& position ) const; + /** + * @brief Converts world integer coordinates to node-local coordinates. + * + * Transforms a world position (with integer coordinates) to this node's + * local coordinate space. + * + * @param pos Reference to the integer position to transform (modified in place). + */ virtual void worldToNode( Vector2i& pos ) const; + /** + * @brief Converts node-local integer coordinates to world coordinates. + * + * Transforms a node-local position (with integer coordinates) to world + * coordinate space. + * + * @param pos Reference to the integer position to transform (modified in place). + */ virtual void nodeToWorld( Vector2i& pos ) const; + /** + * @brief Converts world floating-point coordinates to node-local coordinates. + * + * Transforms a world position (with floating-point coordinates) to this node's + * local coordinate space. + * + * @param pos Reference to the floating-point position to transform (modified in place). + */ virtual void worldToNode( Vector2f& pos ) const; + /** + * @brief Converts node-local floating-point coordinates to world coordinates. + * + * Transforms a node-local position (with floating-point coordinates) to world + * coordinate space. + * + * @param pos Reference to the floating-point position to transform (modified in place). + */ virtual void nodeToWorld( Vector2f& pos ) const; + /** + * @brief Gets the node type identifier. + * + * Returns a unique type identifier for this node class. Derived classes should + * override this to return their specific type constant. + * + * @return The node type as a Uint32. + */ virtual Uint32 getType() const; + /** + * @brief Checks if the node is of a specific type. + * + * Determines whether this node is of the specified type or derived from it. + * + * @param type The type identifier to check. + * @return True if the node is of the specified type, false otherwise. + */ virtual bool isType( const Uint32& type ) const; + /** + * @brief Posts a message to this node and its ancestors. + * + * Sends a node message up the parent chain until a node handles it. Messages + * are used for custom communication between nodes. + * + * @param Msg Pointer to the NodeMessage to post. + */ void messagePost( const NodeMessage* Msg ); + /** + * @brief Sets the node position in density-independent pixels (dp). + * + * Sets the position of the node. The position is relative to the parent node's + * coordinate system. Setting a new position marks the node as dirty and triggers + * layout updates. + * + * @param Pos The new position. + */ virtual void setPosition( const Vector2f& Pos ); + /** + * @brief Sets the node position using separate coordinates. + * + * Convenience method to set the X and Y coordinates individually. + * + * @param x The X coordinate. + * @param y The Y coordinate. + * @return Pointer to this node for method chaining. + */ virtual Node* setPosition( const Float& x, const Float& y ); + /** + * @brief Sets the node size in density-independent pixels (dp). + * + * Sets the size of the node. The size will be validated against minimum/maximum + * constraints if applicable. + * + * @param size The new size. + * @return Pointer to this node for method chaining. + */ virtual Node* setSize( const Sizef& size ); + /** + * @brief Sets the node size using separate width and height values. + * + * Convenience method to set width and height individually. + * + * @param Width The width in dp. + * @param Height The height in dp. + * @return Pointer to this node for method chaining. + */ Node* setSize( const Float& Width, const Float& Height ); + /** + * @brief Gets the node size in density-independent pixels (dp). + * + * Returns the current size of the node. This value may differ from the + * pixel size if scaling is applied. + * + * @return The size as a Sizef. + */ virtual const Sizef& getSize() const; + /** + * @brief Gets the node size in actual screen pixels. + * + * Returns the current size of the node in raw pixel units, accounting for + * any scaling factors. + * + * @return The pixel size as a Sizef. + */ const Sizef& getPixelsSize() const; + /** + * @brief Sets the visibility of the node. + * + * Controls whether the node is rendered. Invisible nodes and their children + * are not drawn and do not receive mouse events. + * + * @param visible True to make the node visible, false to hide it. + * @param emitEventNotification If true, emits a visibility change event. + * @return Pointer to this node for method chaining. + */ Node* setVisible( const bool& visible, bool emitEventNotification = true ); + /** + * @brief Sets visibility for all children recursively. + * + * Changes the visibility state of this node and all its descendants. + * + * @param visible The visibility state to set. + * @param emitEventNotification If true, emits visibility change events. + * @return Pointer to this node for method chaining. + */ Node* setChildrenVisibility( bool visible, bool emitEventNotification = true ); + /** + * @brief Checks if the node is visible. + * + * Returns the current visibility state of this node only, not considering + * parent visibility. + * + * @return True if the node is visible, false otherwise. + */ bool isVisible() const; + /** + * @brief Checks if the node and all its parents are visible. + * + * Traverses up the parent chain to verify that this node and all ancestors + * are visible. Useful for determining if the node will actually be rendered. + * + * @return True if the node and all parents are visible, false otherwise. + */ bool hasVisibility() const; + /** + * @brief Enables or disables the node. + * + * Disabled nodes do not receive input events and are typically rendered + * with a disabled appearance. + * + * @param enabled True to enable the node, false to disable. + * @return Pointer to this node for method chaining. + */ Node* setEnabled( const bool& enabled ); + /** + * @brief Checks if the node is enabled. + * + * @return True if the node is enabled, false if disabled. + */ bool isEnabled() const; + /** + * @brief Checks if the node is disabled. + * + * Convenience method equivalent to !isEnabled(). + * + * @return True if the node is disabled, false otherwise. + */ bool isDisabled() const; + /** + * @brief Gets the parent node. + * + * Returns the direct parent of this node in the scene graph, or nullptr if + * the node has no parent. + * + * @return Pointer to the parent node or nullptr. + */ Node* getParent() const; + /** + * @brief Sets the parent node. + * + * Re-parents this node to a new parent. The node is automatically removed + * from its current parent if any. + * + * @param parent The new parent node. + * @return Pointer to this node for method chaining. + */ Node* setParent( Node* parent ); + /** + * @brief Closes the node. + * + * Marks the node for closure. The node will be removed from the scene during + * the next update cycle. This is the safe way to remove nodes as it prevents + * iterator invalidation issues. + */ virtual void close(); + /** + * @brief Draws the node. + * + * Virtual method that derived classes should override to implement custom + * rendering. The default implementation does nothing. This is called during + * the render cycle after the transformation matrix is set up. + */ virtual void draw(); + /** + * @brief Updates the node. + * + * Called once per frame to update the node's state. The default implementation + * recursively updates all children. Derived classes should call the base + * implementation to maintain child updates. + * + * @param time The time elapsed since the last frame. + */ virtual void update( const Time& time ); + /** + * @brief Performs scheduled updates for nodes with update subscriptions. + * + * Called by the scene manager for nodes that have subscribed to scheduled updates. + * Override to implement time-based update logic for this node. + * + * @param time The time elapsed since the last frame. + */ virtual void scheduledUpdate( const Time& time ); + /** + * @brief Gets the next sibling node in the parent's child list. + * + * Returns the node that comes after this one in the parent's linked list of + * children, or nullptr if this is the last child. + * + * @return Pointer to the next sibling node or nullptr. + */ Node* getNextNode() const; + /** + * @brief Gets the previous sibling node in the parent's child list. + * + * Returns the node that comes before this one in the parent's linked list of + * children, or nullptr if this is the first child. + * + * @return Pointer to the previous sibling node or nullptr. + */ Node* getPrevNode() const; + /** + * @brief Gets the next sibling node, wrapping to first if at end. + * + * Returns the next sibling node, or if this is the last child, returns the + * parent's first child (creating a circular traversal). + * + * @return Pointer to the next node in the loop. + */ Node* getNextNodeLoop() const; + /** + * @brief Attaches arbitrary user data to this node. + * + * Sets a user data pointer that can be used to associate custom data with + * this node. The data is not managed by the node and must be cleaned up + * by the user. + * + * @param data The user data pointer to store. + * @return Pointer to this node for method chaining. + */ Node* setData( const UintPtr& data ); + /** + * @brief Gets the user data previously set with setData(). + * + * @return The stored user data pointer. + */ const UintPtr& getData() const; + /** + * @brief Sets the blend mode for this node. + * + * Controls how this node's colors blend with the background when rendered. + * Common blend modes include Alpha, Add, Multiply, etc. + * + * @param blend The blend mode to use. + * @return Pointer to this node for method chaining. + */ Node* setBlendMode( const BlendMode& blend ); + /** + * @brief Gets the current blend mode. + * + * @return The current blend mode. + */ const BlendMode& getBlendMode() const; + /** + * @brief Moves this node to the front of its parent's child list. + * + * Changes the rendering order so this node is drawn after all its siblings. + * This affects the visual stacking order (nodes drawn later appear on top). + * + * @return Pointer to this node for method chaining. + */ Node* toFront(); + /** + * @brief Moves this node to the back of its parent's child list. + * + * Changes the rendering order so this node is drawn before all its siblings. + * This affects the visual stacking order (nodes drawn earlier appear behind). + * + * @return Pointer to this node for method chaining. + */ Node* toBack(); + /** + * @brief Moves this node to a specific position in the parent's child list. + * + * Changes the rendering order by placing this node at the specified index + * among its siblings. + * + * @param position The zero-based index position in the parent's child list. + */ void toPosition( const Uint32& position ); + /** + * @brief Gets the current node flags. + * + * Returns the bitmask of flags that control various node behaviors and states. + * + * @return The flags as a Uint32 bitmask. + */ const Uint32& getNodeFlags() const; - /** Use it at your own risk */ + /** + * @brief Sets the node flags directly. + * + * Use with caution - this replaces all flags and may cause unexpected behavior. + * Prefer specific flag manipulation methods when available. + * + * @param flags The new flags bitmask. + */ void setNodeFlags( const Uint32& flags ); + /** + * @brief Checks if this node is a SceneNode. + * + * SceneNode is the base class for nodes that handle rendering and scene management. + * + * @return True if this node is a SceneNode, false otherwise. + */ bool isSceneNode() const; + /** + * @brief Checks if this node is a UISceneNode. + * + * UISceneNode is the root node for UI rendering with CSS styling support. + * + * @return True if this node is a UISceneNode, false otherwise. + */ bool isUISceneNode() const; + /** + * @brief Checks if this node is a UINode. + * + * UINode is the base class for UI elements with theming and layout support. + * + * @return True if this node is a UINode, false otherwise. + */ bool isUINode() const; + /** + * @brief Checks if this node is a UIWidget. + * + * UIWidget is the base class for interactive UI elements with CSS support. + * + * @return True if this node is a UIWidget, false otherwise. + */ bool isWidget() const; + /** + * @brief Checks if this node is a Window. + * + * Window nodes represent top-level application windows. + * + * @return True if this node is a Window, false otherwise. + */ bool isWindow() const; + /** + * @brief Checks if this node is a Layout. + * + * Layout nodes are specialized containers that manage the positioning of + * their children according to layout rules. + * + * @return True if this node is a Layout, false otherwise. + */ bool isLayout() const; + /** + * @brief Checks if clipping is enabled for this node. + * + * When clipping is enabled, node content is restricted to the node's bounds. + * + * @return True if clipping is enabled, false otherwise. + */ bool isClipped() const; + /** + * @brief Checks if this node has rotation applied. + * + * @return True if the node's rotation is non-zero, false otherwise. + */ bool isRotated() const; + /** + * @brief Checks if this node has scaling applied. + * + * @return True if the node's scale is not (1,1), false otherwise. + */ bool isScaled() const; + /** + * @brief Checks if this node uses a frame buffer. + * + * Frame buffer nodes render to an off-screen texture first. + * + * @return True if using frame buffer rendering, false otherwise. + */ bool isFrameBuffer() const; + /** + * @brief Checks if the mouse is currently over this node. + * + * @return True if the mouse cursor is over this node, false otherwise. + */ bool isMouseOver() const; + /** + * @brief Checks if the mouse is over this node or any of its children. + * + * @return True if the mouse is over this node or any descendant, false otherwise. + */ bool isMouseOverMeOrChildren() const; + /** + * @brief Checks if this node and all its parents are visible in the tree. + * + * Similar to hasVisibility() but optimized for tree traversal. + * + * @return True if this node and all ancestors are visible, false otherwise. + */ bool isMeOrParentTreeVisible() const; + /** + * @brief Checks if this node or any parent has rotation. + * + * @return True if this node or any ancestor is rotated, false otherwise. + */ bool isMeOrParentTreeRotated() const; + /** + * @brief Checks if this node or any parent has scaling. + * + * @return True if this node or any ancestor is scaled, false otherwise. + */ bool isMeOrParentTreeScaled() const; + /** + * @brief Checks if this node or any parent has scaling or rotation. + * + * @return True if this node or any ancestor is scaled or rotated, false otherwise. + */ bool isMeOrParentTreeScaledOrRotated() const; + /** + * @brief Checks if this node or any parent has scaling, rotation, or frame buffer. + * + * This is used to determine if special clipping planes are needed. + * + * @return True if this node or any ancestor has any of these transforms, false otherwise. + */ bool isMeOrParentTreeScaledOrRotatedOrFrameBuffer() const; + /** + * @brief Adds an event listener for a specific event type. + * + * Registers a callback function to be invoked when the specified event occurs. + * Returns a unique ID that can be used to remove the listener later. + * + * @param eventType The event type constant (e.g., Event::MouseClick). + * @param callback The function to call when the event occurs. + * @return A unique callback identifier. + */ Uint32 addEventListener( const Uint32& eventType, const EventCallback& callback ); + /** + * @brief Adds an event listener (alias for addEventListener). + * + * @param eventType The event type constant. + * @param callback The function to call when the event occurs. + * @return A unique callback identifier. + */ Uint32 on( const Uint32& eventType, const EventCallback& callback ); + /** + * @brief Adds a mouse click event listener. + * + * Convenience method to listen for mouse click events, optionally filtered + * by mouse button. + * + * @param callback The function to call on mouse click. + * @param button The mouse button to filter for (default: left button). + * @return A unique callback identifier. + */ Uint32 onClick( const std::function& callback, const MouseButton& button = MouseButton::EE_BUTTON_LEFT ); + /** + * @brief Adds a mouse double-click event listener. + * + * Convenience method to listen for mouse double-click events. + * + * @param callback The function to call on double click. + * @param button The mouse button to filter for (default: left button). + * @return A unique callback identifier. + */ Uint32 onDoubleClick( const std::function& callback, const MouseButton& button = MouseButton::EE_BUTTON_LEFT ); + /** + * @brief Removes all event listeners of a specific type. + * + * @param eventType The event type to remove listeners for. + */ void removeEventsOfType( const Uint32& eventType ); + /** + * @brief Removes a specific event listener by its callback ID. + * + * @param callbackId The ID returned by addEventListener or on(). + */ void removeEventListener( const Uint32& callbackId ); + /** + * @brief Removes multiple event listeners by their callback IDs. + * + * @param callbacksIds Vector of callback IDs to remove. + */ void removeEventListener( const std::vector& callbacksIds ); + /** + * @brief Removes all event listeners from this node. + * + * Clears the entire event listener registry. + */ void clearEventListener(); + /** + * @brief Gets the first child node. + * + * @return Pointer to the first child or nullptr if no children exist. + */ Node* getFirstChild() const; + /** + * @brief Gets the last child node. + * + * @return Pointer to the last child or nullptr if no children exist. + */ Node* getLastChild() const; + /** + * @brief Gets the world polygon of this node. + * + * Returns the axis-aligned bounding polygon in world coordinates, accounting + * for all transformations (position, rotation, scale, parent transforms). + * The polygon is cached and only recalculated when dirty. + * + * @return Const reference to the Polygon2f representing world bounds. + */ const Polygon2f& getWorldPolygon(); + /** + * @brief Gets the world bounding rectangle. + * + * Returns the axis-aligned bounding box in world coordinates. This is + * derived from the world polygon and is also cached. + * + * @return Const reference to the Rectf representing world bounds. + */ const Rectf& getWorldBounds(); + /** + * @brief Checks if a node is a descendant of this node. + * + * Determines whether the specified node is in this node's subtree. + * + * @param node The node to check. + * @return True if node is a child or grandchild, false otherwise. + */ bool isParentOf( const Node* node ) const; + /** + * @brief Sends an event to this node for handling. + * + * Dispatches the event to all registered listeners for the event type. + * The event is processed synchronously in the calling thread. + * + * @param Event Pointer to the event to send. + */ void sendEvent( const Event* Event ); + /** + * @brief Sends a mouse event to this node. + * + * Creates and sends a MouseEvent with the specified parameters. + * + * @param Event The mouse event type (e.g., Event::MouseClick). + * @param position The mouse position in pixels. + * @param flags The mouse event flags (button states, modifiers). + */ void sendMouseEvent( const Uint32& Event, const Vector2i& position, const Uint32& flags ); + /** + * @brief Sends a common event to this node. + * + * Creates and sends an Event with the specified event type. + * + * @param Event The event type. + */ void sendCommonEvent( const Uint32& Event ); + /** + * @brief Sends a text event to this node. + * + * Creates and sends a TextEvent with the specified text content. + * + * @param event The event type (typically text-related). + * @param text The text string to send. + */ void sendTextEvent( const Uint32& event, const std::string& text ); + /** + * @brief Closes all children recursively. + * + * Marks all descendant nodes for closure. The nodes will be removed during + * the next update cycle. + */ void closeAllChildren(); + /** + * @brief Gets the node's identifier string. + * + * Returns the unique ID string set with setId(). An empty string means + * no ID is set. + * + * @return The node ID as a const string reference. + */ const std::string& getId() const; + /** + * @brief Sets the node's identifier string. + * + * Assigns a unique ID to this node. The ID can be used for CSS selectors + * and for finding the node with find(). Calling setId() also updates + * the cached hash value and triggers onIdChange(). + * + * @param id The ID string to set. + * @return Pointer to this node for method chaining. + */ virtual Node* setId( const std::string& id ); + /** + * @brief Gets the precomputed hash of the node ID. + * + * Returns the cached hash of the ID string for efficient lookups. + * + * @return The ID hash value. + */ const String::HashType& getIdHash() const; + /** + * @brief Finds a descendant node by its ID string. + * + * Searches the subtree rooted at this node for a node with the specified + * ID. The search is depth-first and stops at the first match. + * + * @param id The ID string to search for. + * @return Pointer to the matching node or nullptr if not found. + */ Node* find( const std::string& id ) const; + /** + * @brief Checks if this node has a direct child with the specified ID. + * + * Only searches among immediate children, not the full subtree. + * + * @param id The ID string to search for. + * @return Pointer to the child node or nullptr if not found. + */ Node* hasChild( const std::string& id ) const; + /** + * @brief Template version of find() with type casting. + * + * Finds a descendant node by ID and casts it to the specified type. + * Returns nullptr if not found or if the cast would fail. + * + * @tparam T The type to cast the found node to. + * @param id The ID string to search for. + * @return Pointer to the node cast to T* or nullptr. + */ template T* find( const std::string& id ) const { return reinterpret_cast( find( id ) ); } + /** + * @brief Template version of hasChild() with type casting. + * + * Finds a direct child by ID and casts it to the specified type. + * + * @tparam T The type to cast the found child to. + * @param id The ID string to search for. + * @param node Output parameter that receives the found node pointer. + * @return Pointer to the node cast to T* or nullptr. + */ template T* bind( const std::string& id, T*& node ) { node = find( id ); return node; } + /** + * @brief Casts this node to a different type without checking. + * + * Dangerous - use only when you are certain of the actual type. + * + * @tparam T The type to cast to. + * @return Pointer to this node as T*. + */ template T* asType() { return reinterpret_cast( this ); } + /** + * @brief Const version of asType(). + * + * @tparam T The type to cast to. + * @return Const pointer to this node as const T*. + */ template const T* asConstType() const { return reinterpret_cast( this ); } + /** + * @brief Finds a descendant node by type. + * + * Searches the subtree for the first node of the specified type. The search + * is depth-first and checks node types using isType(). + * + * @param type The node type constant to search for. + * @return Pointer to the first matching node or nullptr. + */ Node* findByType( const Uint32& type ) const; + /** + * @brief Template version of findByType() with type casting. + * + * Finds a descendant node by type and casts it to the specified template type. + * + * @tparam T The type to cast to. + * @param type The node type constant to search for. + * @return Pointer to the node cast to T* or nullptr. + */ template T* findByType( const Uint32& type ) const { return reinterpret_cast( findByType( type ) ); } + /** + * @brief Template helper for findByType() with output parameter. + * + * Finds a descendant node by type and stores the result in the output parameter. + * + * @tparam T The type to cast to. + * @param type The node type constant to search for. + * @param node Output parameter that receives the found node pointer. + * @return Pointer to the found node cast to T* or nullptr. + */ template T* bindByType( const Uint32& type, T*& node ) { node = findByType( type ); return node; } + /** + * @brief Finds all descendant nodes of a specific type. + * + * Searches the entire subtree and collects all nodes matching the specified type. + * + * @param type The node type constant to search for. + * @return Vector of pointers to all matching nodes (may be empty). + */ std::vector findAllByType( const Uint32& type ) const; + /** + * @brief Template version of findAllByType() with type casting. + * + * Finds all descendant nodes of a type and casts them to the specified template type. + * + * @tparam T The type to cast each node to. + * @param type The node type constant to search for. + * @return Vector of pointers to nodes cast to T* (may be empty). + */ template std::vector findAllByType( const Uint32& type ) const { std::vector casted; auto all( findAllByType( type ) ); @@ -275,210 +1004,897 @@ class EE_API Node : public Transformable { return casted; } + /** + * @brief Checks if a node is in this node's tree. + * + * Determines whether the specified node is this node itself or any descendant. + * + * @param node The node to check. + * @return True if the node is in this tree, false otherwise. + */ bool inNodeTree( Node* node ) const; + /** + * @brief Checks if this node draws in reverse order. + * + * When reverse draw is enabled, children are drawn from last to first, + * causing the last child to appear on top. + * + * @return True if reverse drawing is enabled, false otherwise. + */ bool isReverseDraw() const; + /** + * @brief Enables or disables reverse drawing order. + * + * Controls whether children are drawn in normal order (first to last) + * or reverse order (last to first). + * + * @param reverseDraw True to draw children in reverse order. + */ void setReverseDraw( bool reverseDraw ); + /** + * @brief Invalidates this node's draw state. + * + * Marks the node as needing to be redrawn. This triggers a redraw in the + * next frame. The invalidation is propagated to the draw invalidator node. + */ void invalidateDraw(); + /** + * @brief Sets the rotation angle in degrees. + * + * Sets the node's rotation around its rotation origin point. The rotation + * is applied in world coordinates after scaling. + * + * @param angle The rotation angle in degrees. + */ void setRotation( float angle ); + /** + * @brief Sets the rotation angle and origin point. + * + * Sets both the rotation angle and the point around which rotation occurs. + * + * @param angle The rotation angle in degrees. + * @param center The rotation origin point in dp. + */ void setRotation( const Float& angle, const OriginPoint& center ); + /** + * @brief Gets the current rotation origin point. + * + * Returns the point around which rotation is applied, in dp units. + * + * @return Const reference to the rotation origin point. + */ const OriginPoint& getRotationOriginPoint() const; + /** + * @brief Sets the rotation origin point in dp. + * + * Defines the point around which rotation occurs, using dp units. + * + * @param center The rotation origin point in dp. + */ void setRotationOriginPoint( const OriginPoint& center ); + /** + * @brief Sets the rotation origin point in pixels. + * + * Like setRotationOriginPoint but uses pixel units directly without dp conversion. + * + * @param center The rotation origin point in pixels. + */ void setRotationOriginPointPixels( const OriginPoint& center ); + /** + * @brief Sets the X coordinate of the rotation origin using a CSS-like expression. + * + * Allows dynamic origin specification with expressions like "50%" or "10px". + * + * @param xEq The X coordinate expression string. + */ void setRotationOriginPointX( const std::string& xEq ); + /** + * @brief Sets the Y coordinate of the rotation origin using a CSS-like expression. + * + * Allows dynamic origin specification with expressions like "50%" or "10px". + * + * @param yEq The Y coordinate expression string. + */ void setRotationOriginPointY( const std::string& yEq ); + /** + * @brief Gets the actual rotation center in screen coordinates. + * + * Calculates and returns the world-space point around which rotation occurs, + * based on the origin point setting and current size. + * + * @return The rotation center as a Vector2f in dp. + */ Vector2f getRotationCenter() const; - void setScale( const Vector2f& scale ); - - void setScale( const Vector2f& scale, const OriginPoint& center ); - - void setScale( const Float& scale, const OriginPoint& center ); - + /** + * @brief Sets uniform scaling factor. + * + * Sets the same scale factor for both X and Y axes. Scale of 1.0 means + * no scaling, values > 1 enlarge, values < 1 shrink. + * + * @param scale The uniform scale factor. + */ void setScale( const Float& scale ); + /** + * @brief Sets scaling with separate factors for X and Y. + * + * @param scale The scale vector (x, y factors). + */ + void setScale( const Vector2f& scale ); + + /** + * @brief Sets scaling with origin point. + * + * Sets the scale factors and the origin point around which scaling occurs. + * + * @param scale The scale vector (x, y factors). + * @param center The scaling origin point in dp. + */ + void setScale( const Vector2f& scale, const OriginPoint& center ); + + /** + * @brief Sets uniform scaling with origin point. + * + * Sets uniform scaling and the origin point around which scaling occurs. + * + * @param scale The uniform scale factor. + * @param center The scaling origin point in dp. + */ + void setScale( const Float& scale, const OriginPoint& center ); + + /** + * @brief Gets the current scale origin point. + * + * Returns the point around which scaling is applied, in dp units. + * + * @return Const reference to the scale origin point. + */ const OriginPoint& getScaleOriginPoint() const; + /** + * @brief Sets the scale origin point in dp. + * + * Defines the point around which scaling occurs. + * + * @param center The scale origin point in dp. + */ void setScaleOriginPoint( const OriginPoint& center ); + /** + * @brief Sets the scale origin point in pixels. + * + * Like setScaleOriginPoint but uses pixel units directly without dp conversion. + * + * @param center The scale origin point in pixels. + */ void setScaleOriginPointPixels( const OriginPoint& center ); + /** + * @brief Sets the X coordinate of the scale origin using a CSS-like expression. + * + * Allows dynamic origin specification with expressions like "50%" or "10px". + * + * @param xEq The X coordinate expression string. + */ void setScaleOriginPointX( const std::string& xEq ); + /** + * @brief Sets the Y coordinate of the scale origin using a CSS-like expression. + * + * Allows dynamic origin specification with expressions like "50%" or "10px". + * + * @param yEq The Y coordinate expression string. + */ void setScaleOriginPointY( const std::string& yEq ); + /** + * @brief Gets the actual scale center in screen coordinates. + * + * Calculates and returns the world-space point around which scaling occurs, + * based on the origin point setting and current size. + * + * @return The scale center as a Vector2f in dp. + */ Vector2f getScaleCenter() const; + /** + * @brief Sets non-uniform scaling with raw float factors. + * + * Virtual method that derived classes can override to add custom scaling behavior. + * + * @param factorX The X scale factor. + * @param factorY The Y scale factor. + */ virtual void setScale( float factorX, float factorY ); + /** + * @brief Sets the scale origin with raw coordinates. + * + * Virtual method that sets the point around which scaling occurs using raw + * float coordinates. + * + * @param x The X coordinate of the scale origin. + * @param y The Y coordinate of the scale origin. + */ virtual void setScaleOrigin( float x, float y ); + /** + * @brief Sets the rotation origin with raw coordinates. + * + * Virtual method that sets the point around which rotation occurs using raw + * float coordinates. + * + * @param x The X coordinate of the rotation origin. + * @param y The Y coordinate of the rotation origin. + */ virtual void setRotationOrigin( float x, float y ); + /** + * @brief Gets the current alpha (transparency) value. + * + * Returns the alpha value that affects this node's opacity. Range is typically + * 0-255 where 0 is fully transparent and 255 is fully opaque. + * + * @return The alpha value as a Float (typically 0-255). + */ const Float& getAlpha() const; + /** + * @brief Sets the alpha (transparency) for this node. + * + * Controls the opacity of this node. Values typically range from 0 (transparent) + * to 255 (opaque). This affects both the node and its children. + * + * @param alpha The alpha value to set. + */ virtual void setAlpha( const Float& alpha ); + /** + * @brief Sets alpha for this node and all children recursively. + * + * Convenience method to set uniform alpha across the entire subtree. + * + * @param alpha The alpha value to set for all nodes. + */ virtual void setChildrenAlpha( const Float& alpha ); + /** + * @brief Gets the action manager associated with this node. + * + * Returns the ActionManager that controls actions (animations, timed callbacks) + * for this node. The action manager is obtained from the scene node. + * + * @return Pointer to the ActionManager. + */ ActionManager* getActionManager() const; + /** + * @brief Runs an action on this node. + * + * Starts an action (animation, delay, callback, etc.) that will be updated + * automatically. The action will be owned by the action manager. + * + * @param action Pointer to the Action to run. + * @return Pointer to this node for method chaining. + */ Node* runAction( Action* action ); + /** + * @brief Removes a specific action from this node. + * + * Stops and removes the specified action if it is running on this node. + * + * @param action Pointer to the action to remove. + * @return True if the action was found and removed, false otherwise. + */ bool removeAction( Action* action ); + /** + * @brief Removes multiple actions from this node. + * + * Stops and removes all actions in the provided vector. + * + * @param actions Vector of action pointers to remove. + * @return True if any actions were removed, false otherwise. + */ bool removeActions( const std::vector& actions ); + /** + * @brief Removes all actions with a specific tag from this node. + * + * Useful for stopping a group of related actions identified by a common tag. + * + * @param tag The unique tag identifier. + * @return True if any actions were removed, false otherwise. + */ bool removeActionsByTag( const Action::UniqueID& tag ); + /** + * @brief Gets all actions currently running on this node. + * + * @return Vector of pointers to all active actions. + */ std::vector getActions(); + /** + * @brief Gets all actions with a specific tag. + * + * @param tag The tag to search for. + * @return Vector of pointers to matching actions (may be empty). + */ std::vector getActionsByTag( const Action::UniqueID& tag ); + /** + * @brief Removes all actions from this node. + * + * Stops and clears every action currently running on this node. + */ void clearActions(); + /** + * @brief Gets the local transformation matrix. + * + * Returns the transformation matrix representing this node's local transform + * (position, rotation, scale) without parent influences. + * + * @return The local Transform matrix. + */ Transform getLocalTransform() const; + /** + * @brief Gets the global transformation matrix. + * + * Returns the complete transformation matrix from this node's local space + * to world space, including all parent transformations. + * + * @return The global Transform matrix. + */ Transform getGlobalTransform() const; + /** + * @brief Gets the node-to-world transformation matrix. + * + * Alias for getGlobalTransform(). + * + * @return The node-to-world Transform matrix. + */ Transform getNodeToWorldTransform() const; + /** + * @brief Gets the world-to-node transformation matrix. + * + * Returns the inverse of the node-to-world transform, useful for converting + * world coordinates to this node's local space. + * + * @return The world-to-node Transform matrix. + */ Transform getWorldToNodeTransform() const; + /** + * @brief Converts a world point to node-local coordinates. + * + * Transforms a point from world space to this node's local space using + * the transformation matrices. + * + * @param worldPoint The point in world coordinates. + * @return The point in node-local coordinates. + */ Vector2f convertToNodeSpace( const Vector2f& worldPoint ) const; + /** + * @brief Converts a node-local point to world coordinates. + * + * Transforms a point from this node's local space to world space. + * + * @param nodePoint The point in node-local coordinates. + * @return The point in world coordinates. + */ Vector2f convertToWorldSpace( const Vector2f& nodePoint ) const; + /** + * @brief Gets the node's local bounding rectangle. + * + * Returns the axis-aligned bounding box in the node's local coordinate space + * (from origin to size). This is the untransformed bounds. + * + * @return Rectf representing local bounds (0,0 to width,height). + */ Rectf getLocalBounds() const; + /** + * @brief Checks if this node currently has input focus. + * + * Focus means this node receives keyboard and other input events. + * + * @return True if this node has focus, false otherwise. + */ bool hasFocus() const; + /** + * @brief Checks if this node or any descendant has focus. + * + * @return True if this node or any child has focus, false otherwise. + */ bool hasFocusWithin() const; + /** + * @brief Requests input focus for this node. + * + * Attempts to give this node keyboard focus. Derived classes may override + * to implement custom focus behavior. + * + * @param reason The reason for the focus request. + * @return Pointer to this node if focus was granted, nullptr otherwise. + */ virtual Node* setFocus( NodeFocusReason reason = NodeFocusReason::Unknown ); + /** + * @brief Gets the first widget child. + * + * Searches among direct children and returns the first one that is a UIWidget. + * + * @return Pointer to the first child widget or nullptr if none found. + */ Node* getFirstWidget() const; + /** + * @brief Gets the nearest widget ancestor. + * + * Traverses up the parent chain looking for a widget. Useful for finding + * a UIWidget container. + * + * @return Pointer to the parent widget or nullptr if not found. + */ Node* getParentWidget() const; + /** + * @brief Enables reporting of size changes to children. + * + * When enabled, children will receive onParentSizeChange() calls when + * this node's size changes. + */ void enableReportSizeChangeToChildren(); + /** + * @brief Disables reporting of size changes to children. + * + * When disabled, children will not be notified when this node's size changes. + */ void disableReportSizeChangeToChildren(); + /** + * @brief Checks if size change reporting to children is enabled. + * + * @return True if size changes are reported to children, false otherwise. + */ bool reportSizeChangeToChildren() const; + /** + * @brief Centers this node horizontally within its parent. + * + * Adjusts the node's X position so it is centered in the parent's width. + * + * @return Pointer to this node for method chaining. + */ Node* centerHorizontal(); + /** + * @brief Centers this node vertically within its parent. + * + * Adjusts the node's Y position so it is centered in the parent's height. + * + * @return Pointer to this node for method chaining. + */ Node* centerVertical(); + /** + * @brief Centers this node both horizontally and vertically. + * + * Convenience method that calls both centerHorizontal() and centerVertical(). + * + * @return Pointer to this node for method chaining. + */ Node* center(); + /** + * @brief Enables clipping to the node's bounds. + * + * When clipping is enabled, content drawn outside this node's rectangle + * will be cut off. + * + * @return Pointer to this node for method chaining. + */ Node* clipEnable(); + /** + * @brief Disables clipping to the node's bounds. + * + * Content will be allowed to draw outside the node's rectangle. + * + * @return Pointer to this node for method chaining. + */ Node* clipDisable(); + /** + * @brief Sets or clears a specific node flag bit. + * + * Internal helper method for modifying individual flag bits without affecting + * other flags. + * + * @param Flag The flag bit to modify (one of the NODE_FLAG_* constants). + * @param Val The value to set (1 to set, 0 to clear). + */ void writeNodeFlag( const Uint32& Flag, const Uint32& Val ); + /** + * @brief Gets the SceneNode that contains this node. + * + * Traverses up the parent chain to find the nearest SceneNode ancestor. + * + * @return Pointer to the SceneNode or nullptr if not found. + */ SceneNode* getSceneNode() const; + /** + * @brief Gets the event dispatcher associated with this node. + * + * Returns the EventDispatcher from the scene node, or nullptr if this node + * is not in a scene. + * + * @return Pointer to the EventDispatcher or nullptr. + */ EventDispatcher* getEventDispatcher() const; + /** + * @brief Checks if this node is a draw invalidator. + * + * Draw invalidators are nodes that trigger redraws of their entire subtree + * when they become invalidated. The base Node class returns false; derived + * classes like SceneNode override this to return true. + * + * @return True if this node invalidates children on draw invalidation. + */ virtual bool isDrawInvalidator() const; + /** + * @brief Checks if this node has been invalidated. + * + * Returns whether the view dirty flag is set, indicating the node needs + * to be redrawn. + * + * @return True if the node is invalidated, false otherwise. + */ bool invalidated() const; + /** + * @brief Invalidates this node and optionally its children. + * + * Marks this node as needing redraw. If the node is visible and has non-zero + * alpha, sets the view dirty flag. Derived classes may override to add + * custom invalidation logic. + * + * @param invalidator The node that caused the invalidation (unused in base). + */ virtual void invalidate( Node* invalidator ); + /** + * @brief Gets the number of direct children. + * + * @return Count of immediate child nodes. + */ Uint32 getChildCount() const; + /** + * @brief Counts children of a specific type. + * + * Counts how many immediate children have the specified node type. + * + * @param type The node type to count. + * @return Number of children of that type. + */ Uint32 getChildOfTypeCount( const Uint32& type ) const; - Node* getChildAt( Uint32 Index ) const; + /** + * @brief Gets the child node at the specified index. + * + * Returns the child at the given zero-based index in the linked list of children. + * Children are stored in the order they were added. + * + * @param index Zero-based index of the child to retrieve. + * @return Pointer to the child node or nullptr if index is out of range. + */ + Node* getChildAt( Uint32 index ) const; + /** + * @brief Gets the index of this node in its parent's child list. + * + * Returns the zero-based position of this node among its siblings. + * + * @return The node index, or 0 if the node has no parent. + */ Uint32 getNodeIndex() const; + /** + * @brief Gets the index of this node among siblings of the same type. + * + * Returns the position of this node when counting only siblings that have + * the same type as this node. + * + * @return The type-based node index, or 0 if the node has no parent. + */ Uint32 getNodeOfTypeIndex() const; - //! Enqueues the runnable to be executed on the main thread (during the scene node update). - //! It will always be equeued to the main thread execution queue (a.k.a. actions). + /** + * @brief Enqueues a runnable to be executed on the main thread. + * + * Schedules the runnable function to be executed during the scene node's update + * cycle, on the main thread. Useful for thread-safe operations from background + * threads. + * + * @param runnable The function to execute. + * @param delay The time to wait before execution (default: 0). + * @param uniqueIdentifier Optional unique ID for the action. + */ void runOnMainThread( Actions::Runnable::RunnableFunc runnable, const Time& delay = Seconds( 0 ), const Action::UniqueID& uniqueIdentifier = 0 ); - //! Does the same as runOnMainThread if called from a none main thread, otherwise it will be - //! executed immediately. - //! @return True if runnable was immediately executed. + /** + * @brief Executes runnable immediately if on main thread, otherwise queues it. + * + * Checks if called from the main thread. If so, executes the runnable immediately. + * If not, queues it for execution on the main thread via runOnMainThread(). + * + * @param runnable The function to execute. + * @param uniqueIdentifier Optional unique ID for the action. + * @return True if executed immediately, false if queued. + */ bool ensureMainThread( Actions::Runnable::RunnableFunc runnable, const Action::UniqueID& uniqueIdentifier = 0 ); - //! Enqueues the runnable to be run after delay time. + /** + * @brief Executes a runnable after a delay. + * + * Schedules the runnable to be executed once after the specified delay. + * + * @param runnable The function to execute. + * @param delay The time to wait before execution. + * @param uniqueIdentifier Optional unique ID for the action. + */ void setTimeout( Actions::Runnable::RunnableFunc runnable, const Time& delay = Seconds( 0 ), const Action::UniqueID& uniqueIdentifier = 0 ); - //! Repeatedly calls executes the runnable, with a fixed time delay between each call. + /** + * @brief Executes a runnable repeatedly at fixed intervals. + * + * Schedules the runnable to be executed repeatedly, with a fixed time delay + * between each call. The runnable will continue until cancelled. + * + * @param runnable The function to execute. + * @param interval The time between executions. + * @param uniqueIdentifier Optional unique ID for the action. + */ void setInterval( Actions::Runnable::RunnableFunc runnable, const Time& interval, const Action::UniqueID& uniqueIdentifier = 0 ); - //! Enqueues a runnable to be executed in delay time with a unique identifier, if a new runnable - //! is provided before the delay passed, previous enqueue runnable will be removed and the new - //! one will be enqueued, if no other runnable with the same identifier is enqueued until delay - //! passed, the last runnable will be executed. + /** + * @brief Debounces a runnable execution. + * + * If the debounce function is called again before the delay expires, the previous + * pending execution is cancelled and the timer resets. Useful for rate-limiting + * rapid successive calls. + * + * @param runnable The function to execute after the delay. + * @param delay The debounce delay. + * @param uniqueIdentifier Unique ID used to identify and cancel previous debounced calls. + */ void debounce( Actions::Runnable::RunnableFunc runnable, const Time& delay, const Action::UniqueID& uniqueIdentifier ); + /** + * @brief Checks if a node is a direct child of this node. + * + * @param child The node to check. + * @return True if the node is an immediate child, false otherwise. + */ bool isChild( Node* child ) const; + /** + * @brief Checks if a node is in this node's parent tree. + * + * Determines whether the specified node is an ancestor of this node. + * + * @param child The node to treat as child (checking if this node is its parent). + * @return True if this node is in the parent chain of the given node. + */ bool inParentTreeOf( Node* child ) const; + /** + * @brief Checks if any ancestor has a specific node type. + * + * Traverses the parent chain looking for a node of the specified type. + * + * @param type The node type to look for. + * @return True if an ancestor of that type exists, false otherwise. + */ bool inParentTreeOfType( Uint32 type ) const; + /** + * @brief Finds the nearest ancestor of a specific type. + * + * Traverses up the parent chain and returns the first node matching the type. + * + * @param type The node type to search for. + * @return Pointer to the parent node of that type, or nullptr if not found. + */ Node* getParentOfType( Uint32 type ) const; + /** + * @brief Sets the loading state flag. + * + * Marks the node as loading or not loading. This flag can be used to + * suppress certain operations during loading. + * + * @param loading True to set loading state, false to clear. + */ void setLoadingState( bool loading ); + /** + * @brief Checks if the node is in loading state. + * + * @return True if the node's loading flag is set, false otherwise. + */ bool isLoadingState() const; + /** + * @brief Called when the node's ID changes. + * + * Virtual method that can be overridden to respond to ID changes. + * The default implementation sends an OnIdChange event. + */ virtual void onIdChange(); + /** + * @brief Checks if the node is marked for closure. + * + * @return True if the close flag is set (node will be removed), false otherwise. + */ bool isClosing() const; + /** + * @brief Checks if the node is in the process of closing children. + * + * @return True if the closing children flag is set, false otherwise. + */ bool isClosingChildren() const; + /** + * @brief Finds the node under a point, considering hit testing. + * + * Used for mouse picking. Recursively searches children (in reverse order) to + * find the topmost node containing the point. Only nodes with the OVER_FIND_ALLOWED + * flag are considered. + * + * @param Point The point to test in world coordinates. + * @return The topmost node at that point, or nullptr. + */ virtual Node* overFind( const Vector2f& Point ); - /** This removes the node from its parent. Never use this unless you know what you are doing. */ + /** + * @brief Removes the node from its parent. + * + * Detaches this node from its parent without triggering deletion. After calling + * this, the node has no parent and must be managed manually. + * + * Use with caution - this bypasses normal deletion lifecycle. + */ void detach(); + /** + * @brief Applies a function to this node and all descendants. + * + * Traverses the entire subtree in depth-first order, calling func on each node. + * + * @param func The function to apply to each node. + */ void forEachNode( std::function func ); + /** + * @brief Applies a function to all direct children. + * + * Calls func on each immediate child of this node (not including this node itself). + * + * @param func The function to apply to each child. + */ void forEachChild( std::function func ); + /** + * @brief Performs the node's custom drawing operations. + * + * Virtual method that can be overridden to implement custom rendering. This + * is called during the draw cycle after the transform is set. The default + * implementation does nothing. + */ virtual void nodeDraw(); + /** + * @brief Simulates a key down event on this node. + * + * Forces a key down event to be processed by this node, as if the user + * pressed a key while this node had focus. + * + * @param event The key event to simulate. + * @return The event handling result. + */ Uint32 forceKeyDown( const KeyEvent& event ); + /** + * @brief Simulates a key up event on this node. + * + * Forces a key up event to be processed by this node. + * + * @param event The key event to simulate. + * @return The event handling result. + */ Uint32 foceKeyUp( const KeyEvent& event ); + /** + * @brief Simulates a text input event on this node. + * + * Forces a text input event to be processed by this node. + * + * @param Event The text input event to simulate. + * @return The event handling result. + */ Uint32 forceTextInput( const TextInputEvent& Event ); + /** + * @brief Gets the screen-space position of this node. + * + * Returns the computed position in actual screen pixels. This is the world + * position after all parent transformations have been applied. + * + * @return Const reference to the screen position as Vector2f. + */ const Vector2f& getScreenPos() const; + /** + * @brief Gets the screen-space rectangle of this node. + * + * Returns the node's bounds in actual screen pixels as a rectangle. + * + * @return Rectf representing the screen-space bounds. + */ Rectf getScreenRect() const; + /** + * @brief Checks if this node has listeners for a specific event type. + * + * Queries whether there are any event callbacks registered for the given + * event type on this node. + * + * @param eventType The event type to check. + * @return True if listeners exist, false otherwise. + */ bool hasEventsOfType( const Uint32& eventType ) const; protected: + /** @brief Map of event type to callback ID to callback function. */ typedef UnorderedMap> EventsMap; + + /** @brief Forward declaration for EventDispatcher. */ friend class EventDispatcher; std::string mId; @@ -490,154 +1906,638 @@ class EE_API Node : public Transformable { Node* mParentNode{ nullptr }; SceneNode* mSceneNode{ nullptr }; Node* mNodeDrawInvalidator{ nullptr }; - Node* mChild{ nullptr }; //! Pointer to the first child of the node - Node* mChildLast{ nullptr }; //! Pointer to the last child added - Node* mNext{ nullptr }; //! Pointer to the next child of the father - Node* mPrev{ nullptr }; //! Pointer to the prev child of the father + Node* mChild{ nullptr }; + Node* mChildLast{ nullptr }; + Node* mNext{ nullptr }; + Node* mPrev{ nullptr }; Uint32 mNodeFlags{ NODE_FLAG_POSITION_DIRTY | NODE_FLAG_POLYGON_DIRTY }; BlendMode mBlend{ BlendMode::Alpha() }; bool mVisible{ true }; bool mEnabled{ true }; Uint32 mNumCallBacks{ 0 }; - mutable Polygon2f mPoly; mutable Rectf mWorldBounds; Vector2f mCenter; - EventsMap mEvents; - - OriginPoint mRotationOriginPoint; OriginPoint mScaleOriginPoint; Node(); + /** + * @brief Handles an incoming node message. + * + * Called when a message is posted to this node. Override to implement custom + * message handling. Return 0 to continue propagating to parent, non-zero to stop. + * + * @param msg The message to handle. + * @return 0 to continue propagation, non-zero to stop. + */ virtual Uint32 onMessage( const NodeMessage* msg ); + /** + * @brief Handles text input events. + * + * Called when text is input (e.g., from an IME). Default implementation forwards + * the event via sendTextEvent(). + * + * @param event The text input event. + * @return Event handling result. + */ virtual Uint32 onTextInput( const TextInputEvent& event ); + /** + * @brief Handles text editing events. + * + * Called during text composition (e.g., IME editing). Default implementation + * forwards the event. + * + * @param event The text editing event. + * @return Event handling result. + */ virtual Uint32 onTextEditing( const TextEditingEvent& event ); + /** + * @brief Handles key down events. + * + * Called when a key is pressed while this node has focus. Default implementation + * sends a KeyEvent to registered listeners. + * + * @param event The key event. + * @return Event handling result. + */ virtual Uint32 onKeyDown( const KeyEvent& event ); + /** + * @brief Handles key up events. + * + * Called when a key is released while this node has focus. Default implementation + * sends a KeyEvent to registered listeners. + * + * @param event The key event. + * @return Event handling result. + */ virtual Uint32 onKeyUp( const KeyEvent& event ); + /** + * @brief Handles mouse motion events. + * + * Called when the mouse moves over this node. Default implementation sends + * a MouseMove event and returns 1. + * + * @param position Mouse position in pixels. + * @param flags Mouse state flags. + * @return Event handling result (1 stops propagation). + */ virtual Uint32 onMouseMove( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles mouse button down events. + * + * Called when a mouse button is pressed over this node. Default implementation + * sends a MouseDown event and returns 1. + * + * @param position Mouse position in pixels. + * @param flags Mouse state flags. + * @return Event handling result (1 stops propagation). + */ virtual Uint32 onMouseDown( const Vector2i& position, const Uint32& flags ); - virtual Uint32 onMouseClick( const Vector2i& position, const Uint32& flags ); - - virtual Uint32 onMouseDoubleClick( const Vector2i& position, const Uint32& flags ); - + /** + * @brief Handles mouse button up events. + * + * Called when a mouse button is released over this node. Default implementation + * sends a MouseUp event and returns 1. + * + * @param position Mouse position in pixels. + * @param flags Mouse state flags. + * @return Event handling result (1 stops propagation). + */ virtual Uint32 onMouseUp( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles mouse click events. + * + * Called after a complete click (down + up). Default implementation sends + * a MouseClick event and returns 1. + * + * @param position Mouse position in pixels. + * @param flags Mouse state flags. + * @return Event handling result (1 stops propagation). + */ + virtual Uint32 onMouseClick( const Vector2i& position, const Uint32& flags ); + + /** + * @brief Handles mouse double-click events. + * + * Called when a double-click is detected. Default implementation sends + * a MouseDoubleClick event and returns 1. + * + * @param position Mouse position in pixels. + * @param flags Mouse state flags. + * @return Event handling result (1 stops propagation). + */ + virtual Uint32 onMouseDoubleClick( const Vector2i& position, const Uint32& flags ); + + /** + * @brief Handles mouse enter/mouse over events. + * + * Called when the mouse enters this node's area. Updates the mouse over flag + * and sends MouseEnter/MouseOver events. Returns 1 to stop propagation. + * + * @param position Mouse position in pixels. + * @param flags Mouse state flags. + * @return Event handling result (1 stops propagation). + */ virtual Uint32 onMouseOver( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles mouse leave events. + * + * Called when the mouse leaves this node's area. Clears the mouse over flag + * and sends MouseLeave/MouseOut events. Returns 1 to stop propagation. + * + * @param position Mouse position in pixels. + * @param flags Mouse state flags. + * @return Event handling result (1 stops propagation). + */ virtual Uint32 onMouseLeave( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles mouse wheel scroll events. + * + * Called when the mouse wheel is scrolled. Default implementation returns 1 + * to stop propagation but does not forward the event. + * + * @param offset Scroll offset vector. + * @param flipped Whether the scroll direction is flipped (e.g., on Mac). + * @return Event handling result (1 stops propagation). + */ virtual Uint32 onMouseWheel( const Vector2f& offset, bool flipped ); + /** + * @brief Calculates drag data for drag operations. + * + * Called during drag operations to calculate drag data. Default implementation + * returns 1 to indicate drag is handled. + * + * @param position Current drag position. + * @param flags Drag state flags. + * @return Event handling result (1 stops propagation). + */ virtual Uint32 onCalculateDrag( const Vector2f& position, const Uint32& flags ); + /** + * @brief Called when the node is being closed. + * + * Sends an OnClose event to notify listeners that the node is closing. + */ void onClose(); + /** + * @brief Called when visibility changes. + * + * Sends an OnVisibleChange event and invalidates the node for redraw. + * Can be overridden for custom visibility handling. + */ virtual void onVisibilityChange(); + /** + * @brief Called when enabled state changes. + * + * Sends an OnEnabledChange event, invalidates the node, and may clear focus + * if the node is disabled. Can be overridden for custom enabled handling. + */ virtual void onEnabledChange(); + /** + * @brief Called when position changes. + * + * Sends an OnPositionChange event and invalidates the node for redraw. + * Can be overridden for custom position handling. + */ virtual void onPositionChange(); + /** + * @brief Called when size changes. + * + * Updates origin points, invalidates the node, and sends OnSizeChange event. + * Can be overridden for custom size handling. + */ virtual void onSizeChange(); + /** + * @brief Called when the parent's size changes. + * + * Sends an OnParentSizeChange event and invalidates the node. Derived classes + * should call base implementation to maintain this behavior. + * + * @param SizeChange The size change delta. + */ virtual void onParentSizeChange( const Vector2f& SizeChange ); + /** + * @brief Called when the parent node changes. + * + * Invalidates the node to trigger layout updates. Called during re-parenting. + */ virtual void onParentChange(); + /** + * @brief Updates the world polygon and bounds cache. + * + * Recalculates the node's world-space polygon and bounding rectangle, + * accounting for all transformations. Clears the dirty flag when complete. + */ void updateWorldPolygon(); + /** + * @brief Updates the node's center point in screen space. + * + * Recalculates the center point based on current screen position and size. + * Called when position or size changes. + */ void updateCenter(); + /** + * @brief Sets up OpenGL transformation matrices. + * + * Called before drawing this node. Pushes the current matrix state and + * applies scale and rotation transformations. Override to add custom + * matrix operations. + */ virtual void matrixSet(); + /** + * @brief Restores OpenGL transformation matrices. + * + * Called after drawing this node. Pops the matrix state undone by matrixSet(). + * Override to clean up custom matrix operations. + */ virtual void matrixUnset(); + /** + * @brief Draws all child nodes in appropriate order. + * + * Called during the draw cycle. Iterates through children and calls nodeDraw() + * on each visible child. The order respects the reverseDraw flag. + */ virtual void drawChildren(); + /** + * @brief Called when a child is added or removed. + * + * Sends an OnChildCountChanged event and invalidates the node. Override to + * respond to child list changes. + * + * @param child The child node that changed. + * @param removed True if child was removed, false if added. + */ virtual void onChildCountChange( Node* child, const bool& removed ); + /** + * @brief Called when rotation angle changes. + * + * Sends an OnAngleChange event and invalidates the node. Override for custom + * rotation change handling. + */ virtual void onAngleChange(); + /** + * @brief Called when scale changes. + * + * Sends an OnScaleChange event and invalidates the node. Override for custom + * scale change handling. + */ virtual void onScaleChange(); + /** + * @brief Called when alpha changes. + * + * Sends an OnAlphaChange event and invalidates the node. Override for custom + * alpha change handling. + */ virtual void onAlphaChange(); + /** + * @brief Called when the node's scene changes. + * + * Updates the scene node pointer and propagates the change to all children. + * Called when the node is moved to a different scene or when the scene changes. + */ virtual void onSceneChange(); + /** + * @brief Called when this node gains input focus. + * + * Sets the focus flag and sends an OnFocus event. Override to implement + * custom focus behavior. Return 0 to allow focus, non-zero to reject. + * + * @param reason The reason focus was requested. + * @return Event handling result. + */ virtual Uint32 onFocus( NodeFocusReason reason ); + /** + * @brief Called when this node loses input focus. + * + * Clears the focus flag and sends an OnFocusLoss event. Override for custom + * focus loss handling. + * + * @return Event handling result. + */ virtual Uint32 onFocusLoss(); + /** + * @brief Enables clipping planes for the node's bounds. + * + * Internal method called during drawing to set up clipping. Uses either + * scissor test or clipping planes depending on needsClipPlanes. + * + * @param x Left edge in pixels. + * @param y Top edge in pixels. + * @param Width Width in pixels. + * @param Height Height in pixels. + * @param needsClipPlanes True to use clipping planes instead of scissor. + */ void clipStart( bool needsClipPlanes ); + /** + * @brief Disables clipping planes for the node's bounds. + * + * Internal method called during drawing to restore clipping state. + * + * @param needsClipPlanes True to disable clipping planes. + */ void clipEnd( bool needsClipPlanes ); + /** + * @brief Updates the screen position from the local position. + * + * Recalculates mScreenPos by converting the local position to world space. + * Clears the position dirty flag and sends OnUpdateScreenPosition event. + */ void updateScreenPos(); + /** + * @brief Internal size setter without triggering events. + * + * Sets the size directly and marks polygon dirty. Does not trigger change + * notifications. Called by public setSize() methods. + * + * @param size The new size. + */ virtual void setInternalSize( const Sizef& size ); + /** + * @brief Checks if the node should be closed. + * + * Internal method that checks closure conditions. Currently just calls close() + * but exists for potential subclass customization. + */ void checkClose(); + /** + * @brief Propagates parent size change to children. + * + * If reportSizeChangeToChildren() is true, calls onParentSizeChange() on + * each direct child. + * + * @param sizeChange The size change delta. + */ void sendParentSizeChange( const Vector2f& sizeChange ); + /** + * @brief Deletes all children recursively. + * + * Removes and deletes every child node from this node. Used during destruction + * or when clearing the node tree. + */ void childDeleteAll(); + /** + * @brief Adds a child node to the end of the child list. + * + * Appends the node to the parent's child list and sets the node's parent pointer. + * Called by setParent(). + * + * @param node The child node to add. + */ void childAdd( Node* node ); + /** + * @brief Adds a child node at a specific index. + * + * Inserts the node into the parent's child list at the given position. + * Used by setParent() and toPosition(). + * + * @param node The child node to add. + * @param index Zero-based position in the child list. + */ void childAddAt( Node* node, Uint32 index ); + /** + * @brief Removes a child node without deleting it. + * + * Detaches the given child from this parent but does not delete it. + * Called during re-parenting and node destruction. + * + * @param node The child node to remove. + */ void childRemove( Node* node ); + /** + * @brief Gets the node's bounds in screen coordinates. + * + * Returns an axis-aligned rectangle representing the node's position and size + * in actual screen pixels (untransformed). + * + * @return Rectf with screen position and pixel size. + */ Rectf getScreenBounds() const; + /** + * @brief Internal position setter without triggering events. + * + * Sets the position directly and marks the node dirty. Does not trigger change + * notifications. Called by public setPosition() method. + * + * @param Pos The new position in dp. + */ void setInternalPosition( const Vector2f& Pos ); + /** + * @brief Internal width setter. + * + * Sets only the width component of the size. Only changes size if the new + * width differs from current. + * + * @param width The new width. + */ void setInternalWidth( const Float& width ); + /** + * @brief Internal height setter. + * + * Sets only the height component of the size. Only changes size if the new + * height differs from current. + * + * @param height The new height. + */ void setInternalHeight( const Float& height ); + /** + * @brief Calculates the color with this node's alpha applied. + * + * Blends the given color with this node's alpha value, returning a new color + * with modified alpha component. + * + * @param Col The base color. + * @return A Color with alpha multiplied by this node's alpha. + */ Color getColor( const Color& Col ); + /** + * @brief Finds a node by its precomputed ID hash. + * + * Depth-first search for a descendant node with matching ID hash. + * Returns this node if it matches and is not closing. + * + * @param idHash The ID hash to search for. + * @return Pointer to matching node or nullptr. + */ Node* findIdHash( const String::HashType& idHash ) const; + /** + * @brief Checks if any direct child has the given ID hash. + * + * Only searches immediate children, not the full subtree. + * + * @param idHash The ID hash to look for. + * @return Pointer to child node or nullptr. + */ Node* hasChildHash( const String::HashType& idHash ) const; + /** + * @brief Updates origin point calculations. + * + * Recalculates rotation and scale origin points based on size and origin type. + * Called when size changes or origin configuration changes. + */ virtual void updateOriginPoint(); + /** + * @brief Marks the node and children as dirty. + * + * Sets both position and polygon dirty flags, which triggers recalculation + * of screen positions and world bounds. Propagates to all children. + */ void setDirty(); + /** + * @brief Marks all children as dirty. + * + * Calls setDirty() on each child in the tree. Used when this node becomes + * dirty to ensure children recalculate too. + */ void setChildrenDirty(); + /** + * @brief Enables clipping planes for specific rectangle. + * + * Overload that takes pixel coordinates and dimensions. Used during draw cycle. + * + * @param x Left edge. + * @param y Top edge. + * @param Width Width. + * @param Height Height. + * @param needsClipPlanes Whether clipping planes are needed. + */ void clipSmartEnable( const Int32& x, const Int32& y, const Uint32& Width, const Uint32& Height, bool needsClipPlanes ); + /** + * @brief Disables clipping planes. + * + * Overload that takes only the needsClipPlanes flag. + * + * @param needsClipPlanes Whether clipping planes are active. + */ void clipSmartDisable( bool needsClipPlanes ); + /** + * @brief Enables clipping for the node's bounds. + * + * Convenience overload that automatically determines if clipping planes + * are needed based on transforms. + * + * @param x Left edge. + * @param y Top edge. + * @param Width Width. + * @param Height Height. + */ void clipSmartEnable( const Int32& x, const Int32& y, const Uint32& Width, const Uint32& Height ); + /** + * @brief Disables clipping. + * + * Convenience overload that automatically determines if clipping planes + * are active. + */ void clipSmartDisable(); + /** + * @brief Finds the nearest draw invalidator in the parent chain. + * + * Traverses up the parent tree to find a node that reports itself as a + * draw invalidator. SceneNode returns true for this. + * + * @return The nearest draw invalidator node or nullptr. + */ Node* getDrawInvalidator(); + /** + * @brief Finds the SceneNode ancestor. + * + * Traverses up the parent chain looking for a SceneNode. Returns this node + * if it is a SceneNode itself. + * + * @return Pointer to the SceneNode or nullptr. + */ SceneNode* findSceneNode(); + /** + * @brief Updates the draw invalidator cache. + * + * Recalculates and caches which node will handle draw invalidation for + * this subtree. Call when parent changes or manually to force update. + * + * @param force If true, forces update even if already set. + */ void updateDrawInvalidator( bool force = false ); + /** + * @brief Subscribes this node to scheduled updates. + * + * Registers this node with the SceneNode to receive scheduledUpdate() calls + * each frame. Sets NODE_FLAG_SCHEDULED_UPDATE flag. + */ void subscribeScheduledUpdate(); + /** + * @brief Unsubscribes from scheduled updates. + * + * Removes this node from the SceneNode's update list. Clears + * NODE_FLAG_SCHEDULED_UPDATE flag. + */ void unsubscribeScheduledUpdate(); + /** + * @brief Checks if node is subscribed to scheduled updates. + * + * @return True if NODE_FLAG_SCHEDULED_UPDATE is set. + */ bool isSubscribedForScheduledUpdate(); }; diff --git a/include/eepp/scene/scenenode.hpp b/include/eepp/scene/scenenode.hpp index a59818474..ff1fa121f 100644 --- a/include/eepp/scene/scenenode.hpp +++ b/include/eepp/scene/scenenode.hpp @@ -19,98 +19,400 @@ namespace EE { namespace Scene { class EE_API SceneNode : public Node { public: + /** + * @brief Creates a new SceneNode instance. + * + * This is the factory method for creating SceneNode instances. + * + * @param window Pointer to the window to associate with this scene node. + * If NULL, uses the current window from Engine. + * @return Pointer to the newly created SceneNode instance. + */ static SceneNode* New( EE::Window::Window* window = NULL ); + /** + * @brief Constructs a SceneNode with an optional window. + * + * Creates a SceneNode that can be used as a root node for rendering + * and scene management. Optionally specifies which window to use. + * + * @param window Pointer to the window to associate with this scene node. + * If NULL, uses the current window from Engine. + */ SceneNode( EE::Window::Window* window = NULL ); + /** + * @brief Destroys the SceneNode and cleans up resources. + * + * Deletes associated action manager, event dispatcher, and frame buffer. + * Also handles removal from window resize callback and closes children. + */ ~SceneNode(); + /** + * @brief Enables the use of a frame buffer for off-screen rendering. + * + * Creates a frame buffer if one doesn't exist. When enabled, rendering + * will occur to the frame buffer first before being drawn to the screen. + */ void enableFrameBuffer(); + /** + * @brief Disables frame buffer usage and deletes the frame buffer. + * + * Turns off off-screen rendering and releases the frame buffer resource. + */ void disableFrameBuffer(); + /** + * @brief Checks if the node owns its frame buffer. + * + * Ownership means the scene node created and manages the frame buffer. + * + * @return True if the frame buffer is owned by this node, false otherwise. + */ bool ownsFrameBuffer() const; + /** + * @brief Draws the scene node and its children. + * + * This is the main rendering method. Handles frame buffer binding, + * matrix transformations, clipping, and drawing children. Also draws + * debug visualizations if enabled. + */ virtual void draw(); + /** + * @brief Updates the scene node and its children. + * + * Called each frame to update the node's state, actions, event dispatcher, + * and scheduled updates. Manages the update of children based on + * mUpdateAllChildren flag. + * + * @param elapsed The time elapsed since the last update. + */ virtual void update( const Time& elapsed ); + /** + * @brief Enables draw invalidation. + * + * When enabled, the node will use dirty rectangle rendering and only + * redraw regions that have been invalidated. This can improve performance. + */ void enableDrawInvalidation(); + /** + * @brief Disables draw invalidation. + * + * When disabled, the entire node will be redrawn every frame. + */ void disableDrawInvalidation(); + /** + * @brief Gets the window associated with this scene node. + * + * @return Pointer to the Window object. + */ EE::Window::Window* getWindow(); + /** + * @brief Gets the frame buffer used for off-screen rendering. + * + * @return Pointer to the FrameBuffer, or NULL if none is set. + */ FrameBuffer* getFrameBuffer() const; + /** + * @brief Sets the event dispatcher for this scene node. + * + * The event dispatcher handles input and other events. This allows + * custom event handling for this scene. + * + * @param eventDispatcher Pointer to the EventDispatcher to set. + */ void setEventDispatcher( EventDispatcher* eventDispatcher ); + /** + * @brief Gets the event dispatcher. + * + * @return Pointer to the EventDispatcher, or NULL if none set. + */ EventDispatcher* getEventDispatcher() const; + /** + * @brief Enables or disables debug data drawing. + * + * When enabled, additional debug information may be rendered (like + * bounding boxes, invalidation regions, etc.). + * + * @param debug True to enable debug drawing, false to disable. + */ void setDrawDebugData( bool debug ); + /** + * @brief Checks if debug data drawing is enabled. + * + * @return True if debug drawing is enabled, false otherwise. + */ bool getDrawDebugData() const; + /** + * @brief Enables or disables drawing of bounding boxes. + * + * When enabled, bounding boxes around nodes may be rendered for + * debugging purposes. + * + * @param draw True to draw boxes, false to hide them. + */ void setDrawBoxes( bool draw ); + /** + * @brief Checks if bounding boxes are being drawn. + * + * @return True if boxes are drawn, false otherwise. + */ bool getDrawBoxes() const; + /** + * @brief Enables or disables highlighting for mouse-over state. + * + * When enabled and a node is moused over, a highlight effect may be shown. + * + * @param Highlight True to enable highlight on mouse over, false to disable. + */ void setHighlightOver( bool Highlight ); + /** + * @brief Checks if mouse-over highlighting is enabled. + * + * @return True if highlighting is enabled, false otherwise. + */ bool getHighlightOver() const; + /** + * @brief Enables or disables highlighting for focus state. + * + * When enabled and a node has focus, a highlight effect may be shown. + * + * @param Highlight True to enable highlight on focus, false to disable. + */ void setHighlightFocus( bool Highlight ); + /** + * @brief Checks if focus highlighting is enabled. + * + * @return True if focus highlighting is enabled, false otherwise. + */ bool getHighlightFocus() const; + /** + * @brief Enables or disables highlighting for invalidation regions. + * + * When enabled, areas of the screen that are invalidated (need redrawing) + * may be highlighted for debugging. + * + * @param Highlight True to enable invalidation highlighting, false to disable. + */ void setHighlightInvalidation( bool Highlight ); + /** + * @brief Checks if invalidation highlighting is enabled. + * + * @return True if invalidation highlighting is enabled, false otherwise. + */ bool getHighlightInvalidation() const; + /** + * @brief Sets the color used for mouse-over highlighting. + * + * @param Color The highlight color to use. + */ void setHighlightOverColor( const Color& Color ); + /** + * @brief Gets the mouse-over highlight color. + * + * @return The highlight color as a const Color reference. + */ const Color& getHighlightOverColor() const; + /** + * @brief Sets the color used for focus highlighting. + * + * @param Color The highlight color to use. + */ void setHighlightFocusColor( const Color& Color ); + /** + * @brief Gets the focus highlight color. + * + * @return The highlight color as a const Color reference. + */ const Color& getHighlightFocusColor() const; + /** + * @brief Sets the color used for invalidation highlighting. + * + * @param Color The highlight color to use. + */ void setHighlightInvalidationColor( const Color& Color ); + /** + * @brief Gets the invalidation highlight color. + * + * @return The highlight color as a const Color reference. + */ const Color& getHighlightInvalidationColor() const; + /** + * @brief Gets the elapsed time since the last frame. + * + * This is the time that was passed to the most recent update() call. + * + * @return The elapsed time as a const Time reference. + */ const Time& getElapsed() const; + /** + * @brief Checks if draw invalidation is being used. + * + * When using invalidation, only dirty regions are redrawn. + * + * @return True if invalidation is enabled, false otherwise. + */ bool usesInvalidation() const; - void setUseGlobalCursors( const bool& use ); + /** + * @brief Sets whether to use global cursor management. + * + * When enabled, cursor changes are managed globally through the window's + * cursor manager. When disabled, cursor changes may be managed locally. + * + * @param use True to use global cursors, false for local cursor handling. + */ + void setUseGlobalCursors( bool use ); - const bool& getUseGlobalCursors(); + /** + * @brief Gets whether global cursor management is enabled. + * + * @return Reference to the boolean indicating global cursor usage. + */ + bool getUseGlobalCursors(); + /** + * @brief Sets the cursor type. + * + * Changes the cursor appearance if global cursors are enabled. + * + * @param cursor The cursor type to set (from Cursor::Type). + */ void setCursor( Cursor::Type cursor ); + /** + * @brief Checks if this node is a draw invalidator. + * + * SceneNode always returns true, indicating it supports dirty rectangle + * rendering and will invalidate itself when needed. + * + * @return Always true for SceneNode. + */ virtual bool isDrawInvalidator() const; + /** + * @brief Gets the action manager associated with this scene node. + * + * The action manager handles timed actions and animations. + * + * @return Pointer to the ActionManager. + */ ActionManager* getActionManager() const; + /** + * @brief Subscribes a node for scheduled updates. + * + * The specified node will receive scheduledUpdate() calls each frame. + * + * @param node Pointer to the node to subscribe. + */ void subscribeScheduledUpdate( Node* node ); + /** + * @brief Unsubscribes a node from scheduled updates. + * + * The node will no longer receive scheduledUpdate() calls. + * + * @param node Pointer to the node to unsubscribe. + */ void unsubscribeScheduledUpdate( Node* node ); + /** + * @brief Checks if a node is subscribed for scheduled updates. + * + * @param node Pointer to the node to check. + * @return True if the node is subscribed, false otherwise. + */ bool isSubscribedForScheduledUpdate( Node* node ); + /** + * @brief Adds a node to the mouse-over tracking list. + * + * This is used internally to track which nodes are currently under + * the mouse cursor. + * + * @param node Pointer to the node to track. + */ void addMouseOverNode( Node* node ); + /** + * @brief Removes a node from the mouse-over tracking list. + * + * @param node Pointer to the node to stop tracking. + */ void removeMouseOverNode( Node* node ); - const bool& getUpdateAllChildren() const; + /** + * @brief Gets whether all children are updated each frame. + * + * When enabled, all children receive update() calls. When disabled, + * only specific nodes (like those with scheduled updates) are updated. + * + * @return Reference to the boolean indicating update-all-children mode. + */ + bool getUpdateAllChildren() const; + /** + * @brief Sets whether to update all children each frame. + * + * Controls whether all children receive update() calls or only + * subscribed nodes. + * + * @param updateAllChildren True to update all children, false to update selectively. + */ void setUpdateAllChildren( bool updateAllChildren ); + /** + * @brief Gets the DPI (dots per inch) of the display. + * + * @return The DPI as a Float. + */ const Float& getDPI() const; + /** + * @brief Checks if verbose logging is enabled. + * + * When enabled, additional debug messages may be logged. + * + * @return True if verbose logging is enabled, false otherwise. + */ bool getVerbose() const; + /** + * @brief Enables or disables verbose logging. + * + * Controls whether detailed debug information is printed to the log. + * + * @param verbose True to enable verbose logging, false to disable. + */ void setVerbose( bool verbose ); protected: diff --git a/include/eepp/ui/uinode.hpp b/include/eepp/ui/uinode.hpp index dfab3d9e1..031a86328 100644 --- a/include/eepp/ui/uinode.hpp +++ b/include/eepp/ui/uinode.hpp @@ -31,295 +31,1390 @@ class UIBorderDrawable; class EE_API UINode : public Node { public: + /** + * @brief Creates a new UINode instance. + * + * This is the factory method for creating UINode instances. + * + * @return Pointer to the newly created UINode instance. + */ static UINode* New(); typedef std::function EventCallback; virtual ~UINode(); + /** + * @brief Transforms a world position to node-local position. + * + * Converts a world coordinate position to this node's local coordinate space. + * The position is modified in place. + * + * @param position Reference to the position to transform. + */ void worldToNodeTranslation( Vector2f& position ) const; + /** + * @brief Transforms a node-local position to world position. + * + * Converts a node-local coordinate position to world coordinate space. + * The position is modified in place. + * + * @param position Reference to the position to transform. + */ void nodeToWorldTranslation( Vector2f& position ) const; + /** + * @brief Converts world integer coordinates to node-local coordinates. + * + * Converts world coordinate integer position to this node's local coordinate space. + * The position is modified in place. + * + * @param pos Reference to the integer position to transform. + */ void worldToNode( Vector2i& pos ) const; + /** + * @brief Converts node-local integer coordinates to world coordinates. + * + * Converts node-local coordinate integer position to world coordinate space. + * The position is modified in place. + * + * @param pos Reference to the integer position to transform. + */ void nodeToWorld( Vector2i& pos ) const; + /** + * @brief Converts world floating-point coordinates to node-local coordinates. + * + * Converts world coordinate floating-point position to this node's local coordinate space. + * The position is modified in place. + * + * @param pos Reference to the floating-point position to transform. + */ void worldToNode( Vector2f& pos ) const; + /** + * @brief Converts node-local floating-point coordinates to world coordinates. + * + * Converts node-local coordinate floating-point position to world coordinate space. + * The position is modified in place. + * + * @param pos Reference to the floating-point position to transform. + */ void nodeToWorld( Vector2f& pos ) const; + /** + * @brief Gets the node type identifier. + * + * Returns a unique type identifier for this node class. + * + * @return The node type as a Uint32. + */ virtual Uint32 getType() const; + /** + * @brief Checks if the node is of a specific type. + * + * Determines whether this node is of the specified type or derived from it. + * + * @param type The type identifier to check. + * @return True if the node is of the specified type, false otherwise. + */ virtual bool isType( const Uint32& type ) const; + /** + * @brief Sets the node position in density-independent pixels (dp). + * + * Sets the position of the node using density-independent pixels (dp) for + * resolution-independent layout. The position is relative to the parent. + * + * @param Pos The new position in dp. + */ virtual void setPosition( const Vector2f& Pos ); + /** + * @brief Sets the node position in density-independent pixels (dp). + * + * Sets the position of the node using individual coordinates in dp. + * + * @param x The X coordinate in dp. + * @param y The Y coordinate in dp. + * @return Pointer to this node for method chaining. + */ virtual Node* setPosition( const Float& x, const Float& y ); + /** + * @brief Sets the node position in actual screen pixels. + * + * Sets the position of the node using raw screen pixels. This bypasses + * density scaling and should be used when exact pixel control is needed. + * + * @param position The new position in pixels. + * @return Pointer to this node for method chaining. + */ UINode* setPixelsPosition( const Vector2f& position ); + /** + * @brief Sets the node position in actual screen pixels. + * + * Sets the position of the node using individual pixel coordinates. + * + * @param x The X coordinate in pixels. + * @param y The Y coordinate in pixels. + * @return Pointer to this node for method chaining. + */ UINode* setPixelsPosition( const Float& x, const Float& y ); + /** + * @brief Gets the node position in density-independent pixels (dp). + * + * Returns the current position of the node in dp. + * + * @return The position as a Vector2f in dp. + */ const Vector2f& getPosition() const; + /** + * @brief Gets the node position in actual screen pixels. + * + * Returns the current position of the node in raw screen pixels. + * + * @return The position as a Vector2f in pixels. + */ const Vector2f& getPixelsPosition() const; + /** + * @brief Sets the node size in density-independent pixels (dp). + * + * Sets the size of the node using dp units. The size will be constrained + * by minimum size requirements. + * + * @param size The new size in dp. + * @return Pointer to this node for method chaining. + */ virtual Node* setSize( const Sizef& size ); + /** + * @brief Sets the node size in density-independent pixels (dp). + * + * Sets the size of the node using individual dimensions in dp. + * + * @param Width The width in dp. + * @param Height The height in dp. + * @return Pointer to this node for method chaining. + */ virtual Node* setSize( const Float& Width, const Float& Height ); + /** + * @brief Sets the node size in actual screen pixels. + * + * Sets the size of the node using raw pixel units. The size will be + * constrained by minimum size requirements. + * + * @param size The new size in pixels. + * @return Pointer to this node for method chaining. + */ UINode* setPixelsSize( const Sizef& size ); + /** + * @brief Sets the node size in actual screen pixels. + * + * Sets the size of the node using individual pixel dimensions. + * + * @param x The width in pixels. + * @param y The height in pixels. + * @return Pointer to this node for method chaining. + */ UINode* setPixelsSize( const Float& x, const Float& y ); + /** + * @brief Gets the node size in density-independent pixels (dp). + * + * Returns the current size of the node in dp. + * + * @return The size as a Sizef in dp. + */ const Sizef& getSize() const; + /** + * @brief Gets the node rectangle in integer coordinates. + * + * Returns the node's bounds as an integer rectangle based on the dp position + * and size. + * + * @return The rectangle representing the node's bounds. + */ Rect getRect() const; + /** + * @brief Gets the node bounding box in floating-point coordinates. + * + * Returns the node's bounds as a floating-point rectangle in pixel coordinates. + * + * @return The bounding box as a Rectf. + */ Rectf getRectBox() const; + /** + * @brief Draws the node. + * + * Virtual method that can be overridden to implement custom drawing behavior. + * The default implementation does nothing. This is called during the render cycle. + */ virtual void draw(); + /** + * @brief Gets the horizontal alignment flags. + * + * Returns the current horizontal alignment setting for text/content within the node. + * + * @return The horizontal alignment as a Uint32 bitmask. + */ Uint32 getHorizontalAlign() const; + /** + * @brief Sets the horizontal alignment. + * + * Sets how content should be aligned horizontally within the node. + * + * @param halign The horizontal alignment flags. + * @return Pointer to this node for method chaining. + */ UINode* setHorizontalAlign( Uint32 halign ); + /** + * @brief Gets the vertical alignment flags. + * + * Returns the current vertical alignment setting for text/content within the node. + * + * @return The vertical alignment as a Uint32 bitmask. + */ Uint32 getVerticalAlign() const; + /** + * @brief Sets the vertical alignment. + * + * Sets how content should be aligned vertically within the node. + * + * @param valign The vertical alignment flags. + * @return Pointer to this node for method chaining. + */ UINode* setVerticalAlign( Uint32 valign ); + /** + * @brief Sets both horizontal and vertical alignment. + * + * Convenience method to set the gravity (combined horizontal and vertical alignment). + * + * @param hvalign The combined horizontal and vertical alignment flags. + * @return Pointer to this node for method chaining. + */ UINode* setGravity( Uint32 hvalign ); + /** + * @brief Enables or disables background fill and returns the background drawable. + * + * If enabled, creates or returns the background drawable. If disabled, + * the background fill is disabled. + * + * @param enabled True to enable background fill, false to disable. + * @return Pointer to the UINodeDrawable for the background. + */ UINodeDrawable* setBackgroundFillEnabled( bool enabled ); + /** + * @brief Sets a background drawable from a Drawable object. + * + * Enables background fill and sets the specified drawable at the given index. + * + * @param drawable Pointer to the Drawable to use. + * @param ownIt If true, the node takes ownership of the drawable. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ UINode* setBackgroundDrawable( Drawable* drawable, bool ownIt = false, int index = 0 ); + /** + * @brief Sets a background drawable from a skin name. + * + * Enables background fill and sets a drawable using the specified skin name. + * + * @param drawable The skin name for the drawable. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ UINode* setBackgroundDrawable( const std::string& drawable, int index ); + /** + * @brief Sets the background color. + * + * Sets a solid color for the background. This will enable background fill if not already + * enabled. + * + * @param color The background color. + * @return Pointer to this node for method chaining. + */ UINode* setBackgroundColor( const Color& color ); + /** + * @brief Sets the background tint for a specific layer. + * + * Applies a color tint to the background drawable at the specified layer index. + * + * @param color The tint color. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ UINode* setBackgroundTint( const Color& color, int index ); + /** + * @brief Sets the background position X CSS property. + * + * Controls the horizontal positioning of the background drawable at the given layer. + * + * @param positionX The CSS position value (e.g., "left", "center", "right", or length). + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ UINode* setBackgroundPositionX( const std::string& positionX, int index = 0 ); + /** + * @brief Sets the background position Y CSS property. + * + * Controls the vertical positioning of the background drawable at the given layer. + * + * @param positionY The CSS position value (e.g., "top", "center", "bottom", or length). + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ UINode* setBackgroundPositionY( const std::string& positionY, int index = 0 ); + /** + * @brief Sets the background repeat CSS property. + * + * Controls how the background drawable repeats at the specified layer. + * + * @param repeatRule The repeat rule (e.g., "repeat", "no-repeat", "repeat-x", "repeat-y"). + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ UINode* setBackgroundRepeat( const std::string& repeatRule, int index = 0 ); + /** + * @brief Sets the background size CSS property. + * + * Controls the size of the background drawable at the specified layer. + * + * @param size The size value (e.g., "auto", "cover", "contain", or length). + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ UINode* setBackgroundSize( const std::string& size, int index = 0 ); + /** + * @brief Gets the background color. + * + * Returns the current background color. If no background is set, returns transparent. + * + * @return The background color. + */ Color getBackgroundColor() const; + /** + * @brief Gets the background tint color for a specific layer. + * + * Returns the tint color applied to the background drawable at the specified layer. + * + * @param index The layer index (0-based). + * @return The background tint color at the specified layer. + */ Color getBackgroundTint( int index = 0 ) const; + /** + * @brief Sets the border radius for all corners. + * + * Enables the border and sets the radius for all corners. This affects both + * the border and background fill. + * + * @param corners The border radius in pixels. + * @return Pointer to this node for method chaining. + */ UINode* setBorderRadius( const unsigned int& corners ); + /** + * @brief Sets the top-left border radius. + * + * Sets the radius for the top-left corner using a CSS-style value. + * + * @param radius The radius value as a string (e.g., "5px", "50%"). + * @return Pointer to this node for method chaining. + */ UINode* setTopLeftRadius( const std::string& radius ); + /** + * @brief Sets the top-right border radius. + * + * Sets the radius for the top-right corner using a CSS-style value. + * + * @param radius The radius value as a string (e.g., "5px", "50%"). + * @return Pointer to this node for method chaining. + */ UINode* setTopRightRadius( const std::string& radius ); + /** + * @brief Sets the bottom-left border radius. + * + * Sets the radius for the bottom-left corner using a CSS-style value. + * + * @param radius The radius value as a string (e.g., "5px", "50%"). + * @return Pointer to this node for method chaining. + */ UINode* setBottomLeftRadius( const std::string& radius ); + /** + * @brief Sets the bottom-right border radius. + * + * Sets the radius for the bottom-right corner using a CSS-style value. + * + * @param radius The radius value as a string (e.g., "5px", "50%"). + * @return Pointer to this node for method chaining. + */ UINode* setBottomRightRadius( const std::string& radius ); + /** + * @brief Gets the current border radius. + * + * Returns the border radius value in pixels. Returns 0 if no border is enabled. + * + * @return The border radius in pixels. + */ Uint32 getBorderRadius() const; + /** + * @brief Enables or disables foreground fill and returns the foreground drawable. + * + * If enabled, creates or returns the foreground drawable. If disabled, + * the foreground fill is disabled. + * + * @param enabled True to enable foreground fill, false to disable. + * @return Pointer to the UINodeDrawable for the foreground. + */ UINodeDrawable* setForegroundFillEnabled( bool enabled ); + /** + * @brief Sets a foreground drawable from a Drawable object. + * + * Enables foreground fill and sets the specified drawable at the given index. + * + * @param drawable Pointer to the Drawable to use. + * @param ownIt If true, the node takes ownership of the drawable. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ UINode* setForegroundDrawable( Drawable* drawable, bool ownIt = false, int index = 0 ); + /** + * @brief Sets a foreground drawable from a skin name. + * + * Enables foreground fill and sets a drawable using the specified skin name. + * + * @param drawable The skin name for the drawable. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ UINode* setForegroundDrawable( const std::string& drawable, int index = 0 ); - UINode* setForegroundColor( const Color& color ); - - UINode* setForegroundTint( const Color& color, int index ); - - UINode* setForegroundPositionX( const std::string& positionX, int index = 0 ); - - UINode* setForegroundPositionY( const std::string& positionY, int index = 0 ); - - UINode* setForegroundRepeat( const std::string& repeatRule, int index = 0 ); - - UINode* setForegroundSize( const std::string& size, int index = 0 ); - + /** + * @brief Gets the foreground color. + * + * Returns the current foreground color. If no foreground is set, returns transparent. + * + * @return The foreground color. + */ Color getForegroundColor() const; + /** + * @brief Gets the foreground tint color for a specific layer. + * + * Returns the tint color applied to the foreground drawable at the specified layer. + * + * @param index The layer index (0-based). + * @return The foreground tint color at the specified layer. + */ Color getForegroundTint( int index ) const; + /** + * @brief Sets the foreground color. + * + * Sets a solid color for the foreground. This will enable foreground fill if not already + * enabled. + * + * @param color The foreground color. + * @return Pointer to this node for method chaining. + */ + UINode* setForegroundColor( const Color& color ); + + /** + * @brief Sets the foreground tint for a specific layer. + * + * Applies a color tint to the foreground drawable at the specified layer. + * + * @param color The tint color. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ + UINode* setForegroundTint( const Color& color, int index ); + + /** + * @brief Sets the foreground position X CSS property. + * + * Controls the horizontal positioning of the foreground drawable at the given layer. + * + * @param positionX The CSS position value. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ + UINode* setForegroundPositionX( const std::string& positionX, int index = 0 ); + + /** + * @brief Sets the foreground position Y CSS property. + * + * Controls the vertical positioning of the foreground drawable at the given layer. + * + * @param positionY The CSS position value. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ + UINode* setForegroundPositionY( const std::string& positionY, int index = 0 ); + + /** + * @brief Sets the foreground repeat CSS property. + * + * Controls how the foreground drawable repeats at the specified layer. + * + * @param repeatRule The repeat rule. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ + UINode* setForegroundRepeat( const std::string& repeatRule, int index = 0 ); + + /** + * @brief Sets the foreground size CSS property. + * + * Controls the size of the foreground drawable at the specified layer. + * + * @param size The size value. + * @param index The layer index (0-based). + * @return Pointer to this node for method chaining. + */ + UINode* setForegroundSize( const std::string& size, int index = 0 ); + + /** + * @brief Sets the foreground border radius for all corners. + * + * Sets the radius for the foreground content's corners. + * + * @param corners The border radius in pixels. + * @return Pointer to this node for method chaining. + */ UINode* setForegroundRadius( const unsigned int& corners ); + /** + * @brief Gets the current foreground border radius. + * + * Returns the foreground border radius in pixels. Returns 0 if no foreground is enabled. + * + * @return The foreground border radius in pixels. + */ Uint32 getForegroundRadius() const; + /** + * @brief Enables or disables the border and returns the border drawable. + * + * If enabled, creates or returns the border drawable. If disabled, the border is hidden. + * + * @param enabled True to enable the border, false to disable. + * @return Pointer to the UIBorderDrawable for the border. + */ UIBorderDrawable* setBorderEnabled( bool enabled ) const; + /** + * @brief Sets the border color. + * + * Sets the color of the border. This will enable the border if not already enabled. + * + * @param color The border color. + * @return Pointer to this node for method chaining. + */ UINode* setBorderColor( const Color& color ); + /** + * @brief Gets the border color. + * + * Returns the current border color. The border drawable will be created if it doesn't exist. + * + * @return The border color. + */ Color getBorderColor(); + /** + * @brief Sets the border width. + * + * Sets the thickness of the border in pixels. This will enable the border if not already + * enabled. + * + * @param width The border width in pixels. + * @return Pointer to this node for method chaining. + */ UINode* setBorderWidth( const unsigned int& width ); + /** + * @brief Gets the border width. + * + * Returns the current border width in pixels. Defaults to 1.0 if no border is set. + * + * @return The border width as a Float. + */ Float getBorderWidth() const; + /** + * @brief Gets the current node flags. + * + * Returns the bitmask of flags that control various node behaviors and states. + * + * @return The flags as a Uint32 bitmask. + */ const Uint32& getFlags() const; + /** + * @brief Sets multiple flags on the node. + * + * Adds the specified flags to the node's current flag set. This can enable + * various behaviors like fill modes, drag support, alignment, etc. + * + * @param flags Bitwise combination of flags to set. + * @return Pointer to this node for method chaining. + */ virtual UINode* setFlags( const Uint32& flags ); + /** + * @brief Unsets multiple flags on the node. + * + * Removes the specified flags from the node's current flag set. + * + * @param flags Bitwise combination of flags to unset. + * @return Pointer to this node for method chaining. + */ virtual UINode* unsetFlags( const Uint32& flags ); + /** + * @brief Resets all flags to a specific value. + * + * Clears all current flags and optionally sets new flags. + * + * @param newFlags The new flags bitmask (default is 0 to clear all). + * @return Pointer to this node for method chaining. + */ virtual UINode* resetFlags( Uint32 newFlags = 0 ); + /** + * @brief Gets the background drawable. + * + * Returns the background drawable object, creating it if it doesn't exist. + * + * @return Pointer to the UINodeDrawable for the background. + */ UINodeDrawable* getBackground() const; + /** + * @brief Checks if the node has a background drawable. + * + * @return True if a background drawable exists, false otherwise. + */ bool hasBackground() const; + /** + * @brief Gets the foreground drawable. + * + * Returns the foreground drawable object, creating it if it doesn't exist. + * + * @return Pointer to the UINodeDrawable for the foreground. + */ UINodeDrawable* getForeground() const; + /** + * @brief Checks if the node has a foreground drawable. + * + * @return True if a foreground drawable exists, false otherwise. + */ bool hasForeground() const; + /** + * @brief Gets the border drawable. + * + * Returns the border drawable object, creating it if it doesn't exist. + * + * @return Pointer to the UIBorderDrawable for the border. + */ UIBorderDrawable* getBorder() const; + /** + * @brief Sets the theme by name. + * + * Applies a theme to this node by looking up the theme by its name from the + * UIThemeManager. The theme will control the visual appearance. + * + * @param Theme The name of the theme to apply. + */ void setThemeByName( const std::string& Theme ); + /** + * @brief Sets the theme for this node. + * + * Applies the specified UITheme to this node, affecting its visual appearance + * through skins and styles. + * + * @param Theme Pointer to the UITheme to apply. + */ virtual void setTheme( UITheme* Theme ); + /** + * @brief Sets the theme skin with an explicit theme. + * + * Applies a specific skin from the specified theme to this node. + * + * @param Theme Pointer to the UITheme to use. + * @param skinName Name of the skin to apply from the theme. + * @return Pointer to this node for method chaining. + */ virtual UINode* setThemeSkin( UITheme* Theme, const std::string& skinName ); + /** + * @brief Sets the theme skin using the default theme. + * + * Applies a specific skin from the default theme to this node. + * + * @param skinName Name of the skin to apply. + * @return Pointer to this node for method chaining. + */ virtual UINode* setThemeSkin( const std::string& skinName ); + /** + * @brief Sets the theme for all children recursively. + * + * Applies the specified theme to this node and all its descendants. + * + * @param Theme Pointer to the UITheme to apply to children. + */ void setThemeToChildren( UITheme* Theme ); + /** + * @brief Gets the current skin. + * + * Returns the UISkin object currently applied to this node, or nullptr if none. + * + * @return Pointer to the UISkin or nullptr. + */ UISkin* getSkin() const; + /** + * @brief Sets the skin from a UISkin reference. + * + * Applies the specified skin to this node. The skin is copied. + * + * @param Skin Reference to the UISkin to apply. + * @return Pointer to this node for method chaining. + */ virtual UINode* setSkin( const UISkin& Skin ); + /** + * @brief Sets the skin from a UISkin pointer. + * + * Applies the specified skin to this node without copying. + * + * @param skin Pointer to the UISkin to apply. + * @return Pointer to this node for method chaining. + */ UINode* setSkin( UISkin* skin ); + /** + * @brief Sets the skin color tint. + * + * Applies a color tint to the skin/sprite. This multiplies with the skin's colors. + * + * @param color The tint color to apply. + * @return Pointer to this node for method chaining. + */ UINode* setSkinColor( const Color& color ); + /** + * @brief Gets the current skin color tint. + * + * Returns the color tint currently applied to the skin. + * + * @return The skin color as a const Color reference. + */ const Color& getSkinColor() const; + /** + * @brief Removes the current skin. + * + * Deletes and removes the skin from this node, reverting to no custom skin. + */ void removeSkin(); + /** + * @brief Pushes a state onto the state stack. + * + * Adds a new state (like hover, pressed, focused) to the node. States can be + * combined and affect the skin rendering. If emitEvent is true, a state change + * event will be triggered. + * + * @param State The state to push (use UIState::StateFlag* values). + * @param emitEvent Whether to emit a state change event (default: true). + */ virtual void pushState( const Uint32& State, bool emitEvent = true ); + /** + * @brief Pops a state from the state stack. + * + * Removes a state from the node. This can revert visual changes from that state. + * If emitEvent is true, a state change event will be triggered. + * + * @param State The state to pop. + * @param emitEvent Whether to emit a state change event (default: true). + */ virtual void popState( const Uint32& State, bool emitEvent = true ); + /** + * @brief Gets the current skin size for a specific state. + * + * Returns the size of the current skin at the specified state. Useful for + * determining the preferred size of a skinned node. + * + * @param state The state flag (default: UIState::StateFlagNormal). + * @return The skin size as a Sizef. + */ Sizef getSkinSize( const Uint32& state = UIState::StateFlagNormal ) const; + /** + * @brief Applies the default theme to this node. + * + * Requests the UIThemeManager to apply the default theme to this node, + * setting up default skins and styles. + */ void applyDefaultTheme(); + /** + * @brief Gets the window container node. + * + * Finds and returns the container node of the window that contains this node, + * or the root if not in a window. + * + * @return Pointer to the window container node or the scene node. + */ Node* getWindowContainer() const; + /** + * @brief Checks if this node is tab focusable. + * + * Determines whether this node can receive focus via Tab key navigation. + * + * @return True if the node is tab focusable, false otherwise. + */ bool isTabFocusable() const; + /** + * @brief Checks if the node is currently being dragged. + * + * @return True if the node is in a drag operation, false otherwise. + */ bool isDragging() const; + /** + * @brief Sets or clears the dragging state. + * + * Changes whether the node is considered to be dragging. If emitDropEvent + * is true and ending the drag, a drop event will be sent to the node under + * the cursor. + * + * @param dragging True to start dragging, false to stop. + * @param emitDropEvent Whether to emit a drop event when stopping (default: true). + */ void setDragging( bool dragging, bool emitDropEvent = true ); + /** + * @brief Starts a drag operation from a specific position. + * + * Begins dragging this node, recording the starting position for drag calculations. + * + * @param position The starting position of the drag in dp. + */ void startDragging( const Vector2f& position ); + /** + * @brief Checks if this node owns its children's positions. + * + * Determines whether this node is responsible for positioning its children + * (as opposed to children positioning themselves). + * + * @return True if children positions are owned, false otherwise. + */ bool ownsChildPosition() const; + /** + * @brief Gets the current drag point. + * + * Returns the point where dragging started or the current drag position. + * + * @return The drag point as a Vector2f in dp. + */ const Vector2f& getDragPoint() const; + /** + * @brief Sets the drag point. + * + * Sets the reference point used during dragging operations. + * + * @param Point The new drag point in dp. + */ void setDragPoint( const Vector2f& Point ); + /** + * @brief Checks if dragging is enabled for this node. + * + * Determines whether this node can be dragged by the user. + * + * @return True if dragging is enabled, false otherwise. + */ bool isDragEnabled() const; + /** + * @brief Enables or disables dragging. + * + * Controls whether this node can be dragged by the user. + * + * @param enable True to enable dragging, false to disable. + */ void setDragEnabled( const bool& enable ); + /** + * @brief Sets which mouse button initiates dragging. + * + * Specifies which mouse button (left, right, middle) should be used to + * initiate dragging on this node. + * + * @param Button The mouse button mask (EE_BUTTON_* constants). + */ void setDragButton( const Uint32& Button ); + /** + * @brief Gets the mouse button that initiates dragging. + * + * Returns which mouse button is configured to start dragging. + * + * @return The mouse button mask. + */ const Uint32& getDragButton() const; + /** + * @brief Requests focus for this node. + * + * Attempts to give this node input focus. The focus change may be denied + * depending on node state and focus policies. + * + * @param reason The reason for the focus request (default: Unknown). + * @return Pointer to this node if focus was granted, nullptr otherwise. + */ virtual Node* setFocus( NodeFocusReason reason = NodeFocusReason::Unknown ); + /** + * @brief Gets a property's value relative to a container length. + * + * Evaluates a CSS property that has a relative target (like percentage or + * viewport units) and converts it to an absolute length based on the + * appropriate container dimensions. + * + * @param relativeTarget The relative target container (width, height, etc.). + * @param defaultValue The default value if the property cannot be evaluated. + * @param propertyIndex The property index for multi-value properties (default: 0). + * @return The computed length in pixels. + */ Float getPropertyRelativeTargetContainerLength( const CSS::PropertyRelativeTarget& relativeTarget, const Float& defaultValue = 0, const Uint32& propertyIndex = 0 ) const; + /** + * @brief Converts a CSS length to pixels. + * + * Parses and converts a CSS-style length value (with units like px, dp, %, em, rem, etc.) + * to an absolute pixel value based on the container length and current context. + * + * @param length The CSS length to convert. + * @param containerLength The reference container length in pixels. + * @return The computed length in pixels. + */ virtual Float convertLength( const CSS::StyleSheetLength& length, const Float& containerLength ) const; + /** + * @brief Converts a CSS length to density-independent pixels (dp). + * + * Similar to convertLength but returns the result in dp units instead of pixels. + * + * @param length The CSS length to convert. + * @param containerLength The reference container length in pixels. + * @return The computed length in dp. + */ Float convertLengthAsDp( const CSS::StyleSheetLength& length, const Float& containerLength ) const; + /** + * @brief Evaluates a CSS length string to a pixel value. + * + * Parses a string containing a CSS length value and converts it to pixels + * using the specified relative target for percentage/relative units. + * + * @param value The CSS length string (e.g., "10px", "50%", "1em"). + * @param relativeTarget The relative target for relative units. + * @param defaultValue The default value if parsing fails (default: 0). + * @param propertyIndex The property index for multi-value properties (default: 0). + * @return The computed length in pixels. + */ Float lengthFromValue( const std::string& value, const CSS::PropertyRelativeTarget& relativeTarget, const Float& defaultValue = 0, const Uint32& propertyIndex = 0 ) const; + /** + * @brief Evaluates a CSS property to a pixel value. + * + * Convenience method that extracts the value from a StyleSheetProperty and + * converts it to pixels. + * + * @param property The StyleSheetProperty containing the value to evaluate. + * @param defaultValue The default value if the property is not set (default: 0). + * @return The computed length in pixels. + */ Float lengthFromValue( const CSS::StyleSheetProperty& property, const Float& defaultValue = 0 ); + /** + * @brief Evaluates a CSS length string to a dp value. + * + * Similar to lengthFromValue but returns the result in dp units. + * + * @param value The CSS length string. + * @param relativeTarget The relative target for relative units. + * @param defaultValue The default value if parsing fails (default: 0). + * @param propertyIndex The property index for multi-value properties (default: 0). + * @return The computed length in dp. + */ Float lengthFromValueAsDp( const std::string& value, const CSS::PropertyRelativeTarget& relativeTarget, const Float& defaultValue = 0, const Uint32& propertyIndex = 0 ) const; + /** + * @brief Evaluates a CSS property to a dp value. + * + * Convenience method that extracts the value from a StyleSheetProperty and + * converts it to dp. + * + * @param property The StyleSheetProperty containing the value to evaluate. + * @param defaultValue The default value if the property is not set (default: 0). + * @return The computed length in dp. + */ Float lengthFromValueAsDp( const CSS::StyleSheetProperty& property, const Float& defaultValue = 0 ) const; + /** + * @brief Gets the UISceneNode that contains this node. + * + * Returns the UI scene node which is the root of the UI rendering hierarchy + * that this node belongs to. + * + * @return Pointer to the UISceneNode or nullptr. + */ UISceneNode* getUISceneNode() const; + /** + * @brief Gets the input manager. + * + * Returns the Input object used for handling keyboard and mouse input + * from the window associated with this UI node. + * + * @return Pointer to the Input object. + */ Input* getInput() const; + /** + * @brief Sets the minimum width constraint. + * + * Sets the minimum width that this node can be sized to. The node will not + * shrink below this width during layout. + * + * @param width The minimum width in dp. + */ void setMinWidth( const Float& width ); + /** + * @brief Sets the minimum height constraint. + * + * Sets the minimum height that this node can be sized to. The node will not + * shrink below this height during layout. + * + * @param height The minimum height in dp. + */ void setMinHeight( const Float& height ); + /** + * @brief Sets both minimum width and height constraints. + * + * Sets the minimum size constraints for this node. + * + * @param size The minimum size in dp. + */ void setMinSize( const Sizef& size ); + /** + * @brief Gets the current minimum size. + * + * Returns the minimum size constraints currently set on this node. + * + * @return The minimum size as a Sizef in dp. + */ const Sizef& getCurMinSize() const; + /** + * @brief Gets the local bounds in density-independent pixels. + * + * Returns the rectangle representing the node's local coordinate space + * (0,0 to width,height) in dp units. + * + * @return The local bounds as a Rectf. + */ Rectf getLocalDpBounds() const; + /** + * @brief Virtual method for custom node drawing. + * + * Override this method to implement custom drawing for the node. + * This is called after background and before foreground/border. + * Default implementation does nothing. + */ virtual void nodeDraw(); + /** + * @brief Clears the foreground drawable. + * + * Deletes and removes the foreground drawable from this node. + */ void clearForeground(); + /** + * @brief Clears the background drawable. + * + * Deletes and removes the background drawable from this node. + */ void clearBackground(); + /** + * @brief Gets the current clipping type. + * + * Returns what type of clipping is applied to this node's content. + * + * @return The current ClipType. + */ const ClipType& getClipType() const; + /** + * @brief Sets the clipping type. + * + * Controls how the node's content is clipped to its bounds or padding. + * + * @param clipType The clipping type to apply. + * @return Pointer to this node for method chaining. + */ UINode* setClipType( const ClipType& clipType ); + /** + * @brief Checks if the node has a border. + * + * @return True if border is enabled, false otherwise. + */ bool hasBorder() const; + /** + * @brief Gets the padding in actual pixels. + * + * Returns the padding values in pixel units. For UINode this returns + * a zero-sized rect as padding is typically managed by UIWidget. + * + * @return The padding as a Rectf in pixels. + */ virtual const Rectf& getPixelsPadding() const; + /** + * @brief Gets the minimum width equation. + * + * Returns the CSS-style expression that defines the minimum width, + * if one was set (e.g., "50%", "100px"). + * + * @return The minimum width equation string. + */ const std::string& getMinWidthEq() const; + /** + * @brief Sets both minimum width and height equations. + * + * Sets dynamic minimum size constraints using CSS-style expressions. + * These are evaluated during layout to determine the minimum size. + * + * @param minWidthEq The minimum width expression (e.g., "50%"). + * @param minHeightEq The minimum height expression. + */ void setMinSizeEq( const std::string& minWidthEq, const std::string& minHeightEq ); + /** + * @brief Sets the minimum width equation. + * + * Sets a dynamic minimum width constraint using a CSS-style expression. + * + * @param minWidthEq The minimum width expression. + */ void setMinWidthEq( const std::string& minWidthEq ); + /** + * @brief Gets the minimum height equation. + * + * Returns the CSS-style expression for minimum height. + * + * @return The minimum height equation string. + */ const std::string& getMinHeightEq() const; + /** + * @brief Sets the minimum height equation. + * + * Sets a dynamic minimum height constraint using a CSS-style expression. + * + * @param minHeightEq The minimum height expression. + */ void setMinHeightEq( const std::string& minHeightEq ); + /** + * @brief Gets the maximum width equation. + * + * Returns the CSS-style expression that defines the maximum width. + * + * @return The maximum width equation string. + */ const std::string& getMaxWidthEq() const; + /** + * @brief Sets both maximum width and height equations. + * + * Sets dynamic maximum size constraints using CSS-style expressions. + * + * @param maxWidthEq The maximum width expression. + * @param maxHeightEq The maximum height expression. + */ void setMaxSizeEq( const std::string& maxWidthEq, const std::string& maxHeightEq ); + /** + * @brief Sets the maximum width equation. + * + * Sets a dynamic maximum width constraint using a CSS-style expression. + * + * @param maxWidthEq The maximum width expression. + */ void setMaxWidthEq( const std::string& maxWidthEq ); + /** + * @brief Gets the maximum height equation. + * + * Returns the CSS-style expression for maximum height. + * + * @return The maximum height equation string. + */ const std::string& getMaxHeightEq() const; + /** + * @brief Sets the maximum height equation. + * + * Sets a dynamic maximum height constraint using a CSS-style expression. + * + * @param maxHeightEq The maximum height expression. + */ void setMaxHeightEq( const std::string& maxHeightEq ); + /** + * @brief Gets the computed minimum size in dp. + * + * Evaluates any minimum size equations and returns the actual minimum size + * that should be enforced during layout. + * + * @return The computed minimum size in dp. + */ Sizef getMinSize() const; + /** + * @brief Gets the computed maximum size in dp. + * + * Evaluates any maximum size equations and returns the actual maximum size + * that should be enforced during layout. + * + * @return The computed maximum size in dp. + */ Sizef getMaxSize() const; + /** + * @brief Gets the computed minimum size in pixels. + * + * Similar to getMinSize() but returns the result in pixel units. + * + * @return The computed minimum size in pixels. + */ Sizef getMinSizePx() const; + /** + * @brief Gets the computed maximum size in pixels. + * + * Similar to getMaxSize() but returns the result in pixel units. + * + * @return The computed maximum size in pixels. + */ Sizef getMaxSizePx() const; + /** + * @brief Fits a size to the minimum and maximum constraints in dp. + * + * Takes a proposed size and adjusts it to fall within the minimum and + * maximum size constraints, accounting for equations. + * + * @param size The proposed size in dp. + * @return The adjusted size that satisfies min/max constraints in dp. + */ Sizef fitMinMaxSizeDp( const Sizef& size ) const; + /** + * @brief Fits a size to the minimum and maximum constraints in pixels. + * + * Similar to fitMinMaxSizeDp but operates on pixel values. + * + * @param size The proposed size in pixels. + * @return The adjusted size that satisfies min/max constraints in pixels. + */ Sizef fitMinMaxSizePx( const Sizef& size ) const; + /** + * @brief Checks if the node is scrollable. + * + * Determines whether this node supports scrolling behavior. + * + * @return True if the node is scrollable, false otherwise. + */ virtual bool isScrollable() const; protected: @@ -344,93 +1439,423 @@ class EE_API UINode : public Node { std::string mMaxWidthEq; std::string mMaxHeightEq; + /** + * @brief Default constructor. + * + * Creates a UINode with default values. Typically nodes should be created + * using the New() factory method or by derived widget classes. + */ UINode(); + /** + * @brief Handles mouse down events. + * + * Called when a mouse button is pressed while over this node. + * Can be overridden to implement custom mouse down handling. + * + * @param position The mouse position in pixels. + * @param flags The mouse event flags. + * @return The event handling result (non-zero to consume event). + */ virtual Uint32 onMouseDown( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles mouse up events. + * + * Called when a mouse button is released. Can be overridden to implement + * custom mouse up handling. + * + * @param position The mouse position in pixels. + * @param flags The mouse event flags. + * @return The event handling result. + */ virtual Uint32 onMouseUp( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles value change events. + * + * Called when a value associated with this node has changed. + * Default implementation sends the OnValueChange event. + * + * @return The event handling result. + */ virtual Uint32 onValueChange(); + /** + * @brief Handles state changes. + * + * Called when the node's state bitmask changes. Default implementation + * invalidates the node for redraw. + */ virtual void onStateChange(); + /** + * @brief Handles enabled state changes. + * + * Called when the node's enabled state changes. Updates the disabled state + * accordingly and calls Node::onEnabledChange(). + */ virtual void onEnabledChange(); + /** + * @brief Handles alignment changes. + * + * Called when the node's alignment flags change. Default implementation + * invalidates the node for redraw. + */ virtual void onAlignChange(); + /** + * @brief Draws the node's skin. + * + * Called during the render cycle to draw the skin/sprite. Override to + * customize skin rendering. + */ virtual void drawSkin(); + /** + * @brief Draws the background. + * + * Called during the render cycle to draw the background. Default implementation + * draws the background drawable if the fill flag is set. + */ virtual void drawBackground(); + /** + * @brief Draws the foreground. + * + * Called during the render cycle to draw the foreground. Default implementation + * draws the foreground drawable if the fill flag is set. + */ virtual void drawForeground(); + /** + * @brief Draws the border. + * + * Called during the render cycle to draw the border. Default implementation + * draws the border drawable if the border flag is set. + */ virtual void drawBorder(); + /** + * @brief Handles theme loading. + * + * Called when a theme has been loaded or applied to this node. Default + * implementation invalidates the node for redraw. + */ virtual void onThemeLoaded(); + /** + * @brief Handles child count changes. + * + * Called when a child is added to or removed from this node. + * Can be overridden to respond to child count changes. + * + * @param child The child node that was added or removed. + * @param removed True if the child was removed, false if added. + */ virtual void onChildCountChange( Node* child, const bool& removed ); + /** + * @brief Handles drag calculation. + * + * Called during dragging to calculate whether and how the node should move. + * + * @param position The current mouse position. + * @param flags The mouse event flags. + * @return Non-zero to allow the drag to continue. + */ virtual Uint32 onCalculateDrag( const Vector2f& position, const Uint32& flags ); + /** + * @brief Handles drag movement. + * + * Called during a drag operation when the mouse moves. Can modify the + * node's position based on the drag difference. + * + * @param position The current mouse position. + * @param flags The mouse event flags. + * @param dragDiff The distance dragged since last call. + * @return Non-zero to indicate handling. + */ virtual Uint32 onDrag( const Vector2f& position, const Uint32& flags, const Sizef& dragDiff ); + /** + * @brief Handles drag start. + * + * Called when a drag operation begins. Default implementation sends + * the OnDragStart event. + * + * @param position The starting mouse position. + * @param flags The mouse event flags. + * @return The event handling result. + */ virtual Uint32 onDragStart( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles drag stop. + * + * Called when a drag operation ends. Default implementation sends + * the OnDragStop event and may send a drop event. + * + * @param position The final mouse position. + * @param flags The mouse event flags. + * @return The event handling result. + */ virtual Uint32 onDragStop( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles drop events. + * + * Called when a dragged node is dropped onto this node. Default implementation + * sends the OnNodeDropped event. + * + * @param widget The node that was dropped. + * @return The event handling result. + */ virtual Uint32 onDrop( UINode* widget ); + /** + * @brief Handles mouse over events. + * + * Called when the mouse cursor enters this node's area. Default implementation + * pushes the hover state. + * + * @param position The mouse position. + * @param flags The mouse event flags. + * @return The event handling result. + */ virtual Uint32 onMouseOver( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles mouse leave events. + * + * Called when the mouse cursor leaves this node's area. Default implementation + * pops the hover and pressed states. + * + * @param position The mouse position. + * @param flags The mouse event flags. + * @return The event handling result. + */ virtual Uint32 onMouseLeave( const Vector2i& position, const Uint32& flags ); + /** + * @brief Handles focus gain events. + * + * Called when this node gains input focus. Default implementation pushes + * the focus state and calls Node::onFocus(). + * + * @param reason The reason for the focus gain. + * @return The event handling result. + */ virtual Uint32 onFocus( NodeFocusReason reason ); + /** + * @brief Handles focus loss events. + * + * Called when this node loses input focus. Default implementation pops + * the focus state and calls Node::onFocusLoss(). + * + * @return The event handling result. + */ virtual Uint32 onFocusLoss(); + /** + * @brief Handles scene changes. + * + * Called when the node's scene changes. Updates the mUISceneNode pointer + * if the new scene is a UISceneNode. + */ virtual void onSceneChange(); + /** + * @brief Draws droppable hovering feedback. + * + * Called when this node is a potential drop target. Draws visual feedback + * indicating the node can accept the drop. + */ virtual void drawDroppableHovering(); + /** + * @brief Checks and handles close operations. + * + * Internal method to check if the node should be closed and handle cleanup. + */ void checkClose(); + /** + * @brief Handles widget focus loss. + * + * Called when a widget child loses focus. Sends the OnWidgetFocusLoss event + * and invalidates the node. + */ virtual void onWidgetFocusLoss(); + /** + * @brief Writes a flag bit. + * + * Internal helper to set or clear a specific flag bit. + * + * @param Flag The flag bit to modify. + * @param Val The value to set (1 to set, 0 to clear). + */ void writeFlag( const Uint32& Flag, const Uint32& Val ); + /** + * @brief Creates padding rectangle from skin border size. + * + * Internal method to calculate padding based on the skin's border dimensions. + * + * @param PadLeft Whether to include left padding (default: true). + * @param PadRight Whether to include right padding (default: true). + * @param PadTop Whether to include top padding (default: true). + * @param PadBottom Whether to include bottom padding (default: true). + * @param SkipFlags If true, ignores UI_AUTO_PADDING flag (default: false). + * @return The calculated padding in dp. + */ Rectf makePadding( bool PadLeft = true, bool PadRight = true, bool PadTop = true, bool PadBottom = true, bool SkipFlags = false ) const; + /** + * @brief Gets the skin size for a specific skin and state. + * + * Internal method to query the size of a given skin at a specific state. + * + * @param Skin Pointer to the UISkin to query. + * @param State The state flag (default: UIState::StateFlagNormal). + * @return The skin size as a Sizef. + */ Sizef getSkinSize( UISkin* Skin, const Uint32& State = UIState::StateFlagNormal ) const; + /** + * @brief Draws the focus highlight. + * + * Internal method to draw the focus rectangle around the node if it has focus. + */ void drawHighlightFocus(); + /** + * @brief Draws overlay highlight (e.g., mouse over). + * + * Internal method to draw an overlay highlight when the node is under the mouse. + */ void drawOverNode(); + /** + * @brief Updates debug visualization data. + * + * Internal method that updates debug information display, such as showing + * bounds, tags, IDs, etc. when debug mode is enabled. + */ void updateDebugData(); + /** + * @brief Draws the bounding box for debugging. + * + * Internal method to draw a rectangle around the node when box drawing is enabled. + */ void drawBox(); + /** + * @brief Sets the internal position without triggering callbacks. + * + * Internal method to set position without calling onPositionChange(). + * + * @param Pos The new position in dp. + */ void setInternalPosition( const Vector2f& Pos ); + /** + * @brief Sets the internal size without constraints. + * + * Internal method to set size without applying min/max constraints or + * triggering child notifications. + * + * @param size The new size in dp. + */ virtual void setInternalSize( const Sizef& size ); + /** + * @brief Sets the internal size in pixels without constraints. + * + * Internal method to set size in pixels without applying constraints. + * + * @param size The new size in pixels. + */ void setInternalPixelsSize( const Sizef& size ); + /** + * @brief Sets the internal width in pixels. + * + * Internal method to set width directly in pixels. + * + * @param width The new width in pixels. + */ void setInternalPixelsWidth( const Float& width ); + /** + * @brief Sets the internal height in pixels. + * + * Internal method to set height directly in pixels. + * + * @param height The new height in pixels. + */ void setInternalPixelsHeight( const Float& height ); + /** + * @brief Updates the origin point for transformations. + * + * Internal method called when size or rotation origin settings change. + * Recalculates rotation and scale origin points if they use equations. + */ virtual void updateOriginPoint(); + /** + * @brief Starts smart clipping. + * + * Internal method that enables clipping planes based on the specified clip type. + * + * @param reqClipType The requested clipping type. + * @param needsClipPlanes Whether clip planes are needed. + */ void smartClipStart( const ClipType& reqClipType, bool needsClipPlanes ); + /** + * @brief Ends smart clipping. + * + * Internal method that disables clipping planes set by smartClipStart. + * + * @param reqClipType The clipping type to end. + * @param needsClipPlanes Whether clip planes were used. + */ void smartClipEnd( const ClipType& reqClipType, bool needsClipPlanes ); + /** + * @brief Starts smart clipping (simplified version). + * + * Internal variant that automatically determines if clip planes are needed. + * + * @param reqClipType The requested clipping type. + */ void smartClipStart( const ClipType& reqClipType ); + /** + * @brief Ends smart clipping (simplified version). + * + * Internal variant that automatically determines if clip planes were used. + * + * @param reqClipType The clipping type to end. + */ void smartClipEnd( const ClipType& reqClipType ); + /** + * @brief Gets the droppable hovering color. + * + * Internal method that returns the color to use when showing drop feedback. + * Queries the "droppable-hovering-color" CSS property. + * + * @return The droppable hover color. + */ Color getDroppableHoveringColor(); }; diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp index 9df46d619..2294e3993 100644 --- a/include/eepp/ui/uiscenenode.hpp +++ b/include/eepp/ui/uiscenenode.hpp @@ -26,152 +26,655 @@ class UIIcon; class EE_API UISceneNode : public SceneNode { public: + /** + * @brief Creates a new UISceneNode instance. + * + * This is the factory method for creating UISceneNode instances. + * + * @param window Pointer to the window to associate with this UI scene node. + * If NULL, uses the current window from Engine. + * @return Pointer to the newly created UISceneNode instance. + */ static UISceneNode* New( EE::Window::Window* window = NULL ); + /** + * @brief Destroys the UISceneNode and cleans up resources. + * + * Deletes theme managers, icon theme manager, font faces, and event dispatcher. + * Also calls childDeleteAll() to ensure proper cleanup order (before thread pool). + */ virtual ~UISceneNode(); + /** + * @brief Sets the size in density-independent pixels (dp). + * + * Override of SceneNode::setSize to also update dp size and trigger media changes. + * + * @param size The new size in dp. + * @return Pointer to this node for method chaining. + */ virtual Node* setSize( const Sizef& size ); + /** + * @brief Sets the size in density-independent pixels (dp). + * + * Override of SceneNode::setSize with individual dimensions. + * + * @param Width The width in dp. + * @param Height The height in dp. + * @return Pointer to this node for method chaining. + */ virtual Node* setSize( const Float& Width, const Float& Height ); + /** + * @brief Sets the size in actual screen pixels. + * + * Sets the pixel size directly and updates the dp size accordingly. + * + * @param size The new size in pixels. + * @return Pointer to this node for method chaining. + */ UISceneNode* setPixelsSize( const Sizef& size ); + /** + * @brief Sets the size in actual screen pixels. + * + * Sets the pixel size using individual dimensions. + * + * @param x The width in pixels. + * @param y The height in pixels. + * @return Pointer to this node for method chaining. + */ UISceneNode* setPixelsSize( const Float& x, const Float& y ); + /** + * @brief Gets the size in density-independent pixels (dp). + * + * @return The size as a const Sizef reference in dp. + */ const Sizef& getSize() const; + /** + * @brief Updates the UISceneNode. + * + * Override that adds UI-specific update logic including: + * - Updating dirty styles, style states, and layouts + * - Handling multiple invalidation passes if needed + * - Processing scheduled updates + * + * @param elapsed The time elapsed since the last update. + */ virtual void update( const Time& elapsed ); + /** + * @brief Sets the translator for internationalization. + * + * The translator is used to translate strings throughout the UI. + * + * @param translator The Translator object to set. + */ void setTranslator( Translator translator ); + /** + * @brief Sets the translator for internationalization. + * + * The translator is used to translate strings throughout the UI. + * + * @param translator The Translator object to set. + */ + void setTranslator( Translator&& translator ); + + /** + * @brief Gets the translator as a const reference. + * + * @return The const Translator reference. + */ const Translator& getTranslator() const; + /** + * @brief Gets the translator as a non-const reference. + * + * @return The Translator reference for modification. + */ Translator& getTranslator(); + /** + * @brief Gets a translated string. + * + * Translates the given string using the translator. Supports special + * @string syntax for lookups and function-style expressions. + * + * @param str The string to translate. + * @return The translated string, or the original if no translation found. + */ String getTranslatorString( const std::string& str ); + /** + * @brief Gets a translated string with default value. + * + * Similar to getTranslatorString() but returns defaultValue if translation + * is not found. + * + * @param str The string to translate. + * @param defaultValue The default value to use if translation fails. + * @return The translated string or default value. + */ String getTranslatorString( const std::string& str, const String& defaultValue ); + /** + * @brief Gets a translated string from a translation key. + * + * Looks up the translation using the specified key. + * + * @param key The translation key to look up. + * @param defaultValue The default value if key not found. + * @return The translated string or default value. + */ String getTranslatorStringFromKey( const std::string& key, const String& defaultValue ); + /** + * @brief Translates a string (internationalization shorthand). + * + * Convenience method equivalent to getTranslatorStringFromKey(). + * + * @param key The translation key. + * @param defaultValue The default value if translation not found. + * @return The translated string or default value. + */ String i18n( const std::string& key, const String& defaultValue ); + /** + * @brief Loads UI layout from an XML node. + * + * Parses the XML node and creates UIWidgets accordingly. + * + * @param node The XML node to load from. + * @param parent The parent node to attach widgets to (default: this). + * @param marker A marker value to associate with loaded styles. + * @return The root UIWidget created, or NULL if none. + */ UIWidget* loadLayoutNodes( pugi::xml_node node, Node* parent, const Uint32& marker ); + /** + * @brief Loads a UI layout from a file. + * + * Parses an XML layout file and creates the UI hierarchy. + * + * @param layoutPath Path to the layout file. + * @param parent Parent node for the layout (default: this). + * @param marker Marker for style association. + * @return The root widget, or NULL if loading failed. + */ UIWidget* loadLayoutFromFile( const std::string& layoutPath, Node* parent = NULL, const Uint32& marker = 0 ); + /** + * @brief Loads a UI layout from a string. + * + * Parses an XML string and creates the UI hierarchy. + * + * @param layoutString The XML layout string. + * @param parent Parent node for the layout (default: this). + * @param marker Marker for style association. + * @return The root widget, or NULL if parsing failed. + */ UIWidget* loadLayoutFromString( const std::string& layoutString, Node* parent = NULL, const Uint32& marker = 0 ); + /** + * @brief Loads a UI layout from a C string. + * + * Parses an XML C-string and creates the UI hierarchy. + * + * @param layoutString The XML layout C-string. + * @param parent Parent node for the layout (default: this). + * @param marker Marker for style association. + * @return The root widget, or NULL if parsing failed. + */ UIWidget* loadLayoutFromString( const char* layoutString, Node* parent = NULL, const Uint32& marker = 0 ); + /** + * @brief Loads a UI layout from a memory buffer. + * + * Parses XML from a memory buffer and creates the UI hierarchy. + * + * @param buffer Pointer to the XML data in memory. + * @param bufferSize Size of the buffer in bytes. + * @param parent Parent node for the layout (default: this). + * @param marker Marker for style association. + * @return The root widget, or NULL if parsing failed. + */ UIWidget* loadLayoutFromMemory( const void* buffer, Int32 bufferSize, Node* parent = NULL, const Uint32& marker = 0 ); + /** + * @brief Loads a UI layout from an I/O stream. + * + * Reads XML from an IOStream and creates the UI hierarchy. + * + * @param stream The input stream to read from. + * @param parent Parent node for the layout (default: this). + * @param marker Marker for style association. + * @return The root widget, or NULL if reading or parsing failed. + */ UIWidget* loadLayoutFromStream( IOStream& stream, Node* parent = NULL, const Uint32& marker = 0 ); + /** + * @brief Loads a UI layout from a pack file. + * + * Extracts XML from a pack (archive) and creates the UI hierarchy. + * + * @param pack Pointer to the Pack to read from. + * @param FilePackPath Path within the pack to the layout file. + * @param parent Parent node for the layout (default: this). + * @return The root widget, or NULL if extraction or parsing failed. + */ UIWidget* loadLayoutFromPack( Pack* pack, const std::string& FilePackPath, Node* parent = NULL ); + /** + * @brief Sets the stylesheet for this UISceneNode. + * + * Replaces the current stylesheet with a new one and optionally loads + * the styles immediately. + * + * @param styleSheet The CSS StyleSheet to set. + * @param loadStyle If true, applies the styles immediately (default: true). + */ void setStyleSheet( const CSS::StyleSheet& styleSheet, bool loadStyle = true ); + /** + * @brief Sets the stylesheet from an inline CSS string. + * + * Parses the CSS string and sets it as the stylesheet. + * + * @param inlineStyleSheet The CSS stylesheet as a string. + */ void setStyleSheet( const std::string& inlineStyleSheet ); - void combineStyleSheet( const CSS::StyleSheet& styleSheet, - const bool& forceReloadStyle = true ); + /** + * @brief Combines a stylesheet with the existing one. + * + * Merges the given stylesheet into the current stylesheet. + * + * @param styleSheet The CSS StyleSheet to combine. + * @param forceReloadStyle If true, forces immediate style reload (default: true). + */ + void combineStyleSheet( const CSS::StyleSheet& styleSheet, bool forceReloadStyle = true ); - void combineStyleSheet( const std::string& inlineStyleSheet, - const bool& forceReloadStyle = true, const Uint32& marker = 0 ); + /** + * @brief Combines an inline stylesheet with the existing one. + * + * Parses the CSS string and merges it with the current stylesheet. + * + * @param inlineStyleSheet The CSS stylesheet as a string. + * @param forceReloadStyle If true, forces immediate style reload (default: true). + * @param marker Marker to associate with the new styles. + */ + void combineStyleSheet( const std::string& inlineStyleSheet, bool forceReloadStyle = true, + const Uint32& marker = 0 ); + /** + * @brief Gets the reference to the current stylesheet. + * + * @return Reference to the CSS StyleSheet. + */ CSS::StyleSheet& getStyleSheet(); + /** + * @brief Checks if a stylesheet is set. + * + * @return True if a non-empty stylesheet exists, false otherwise. + */ bool hasStyleSheet(); - const bool& isLoading() const; + /** + * @brief Checks if the UISceneNode is currently loading. + * + * This flag is set during layout loading operations. + * + * @return Const reference to the loading state boolean. + */ + bool isLoading() const; + /** + * @brief Gets the UIThemeManager. + * + * The theme manager is responsible for loading and providing UI themes. + * + * @return Pointer to the UIThemeManager. + */ UIThemeManager* getUIThemeManager() const; + /** + * @brief Gets the root widget of this UISceneNode. + * + * The root is a UIRoot widget that contains all other UI widgets. + * + * @return Pointer to the root UIWidget. + */ UIWidget* getRoot() const; + /** + * @brief Invalidates the style of a widget. + * + * Marks the widget's style as needing to be reloaded. The widget will + * have its CSS re-applied during the next update cycle. + * + * @param widget Pointer to the UIWidget to invalidate. + * @param tryReinsert If true, attempts to reposition the widget in the dirty set. + */ void invalidateStyle( UIWidget* widget, bool tryReinsert = false ); + /** + * @brief Invalidates the style state of a widget. + * + * Marks the widget's style state (pseudo-classes) as needing to be + * re-evaluated and re-applied. + * + * @param widget Pointer to the UIWidget to invalidate. + * @param disableCSSAnimations If true, disables CSS animations during the update. + * @param tryReinsert If true, attempts to reposition the widget in the dirty set. + */ void invalidateStyleState( UIWidget* widget, bool disableCSSAnimations = false, bool tryReinsert = false ); + /** + * @brief Invalidates the layout of a UILayout widget. + * + * Marks the layout as needing to be recalculated. The layout will be + * updated during the next update cycle. + * + * @param widget Pointer to the UILayout to invalidate. + */ void invalidateLayout( UILayout* widget ); + /** + * @brief Sets the loading state flag. + * + * This is typically managed internally but can be set manually if needed. + * + * @param isLoading The loading state to set. + */ void setIsLoading( bool isLoading ); + /** + * @brief Updates all dirty layouts. + * + * Processes the mDirtyLayouts set and calls updateLayoutTree() on each + * layout that needs recalculation. + */ void updateDirtyLayouts(); + /** + * @brief Updates all dirty styles. + * + * Processes the mDirtyStyle set and calls reloadStyle() on each widget + * that needs its CSS style re-applied. + */ void updateDirtyStyles(); + /** + * @brief Updates all dirty style states. + * + * Processes the mDirtyStyleState set and calls + * reportStyleStateChangeRecursive() on each widget that needs its + * pseudo-class state re-evaluated. + */ void updateDirtyStyleStates(); - const bool& isUpdatingLayouts() const; + /** + * @brief Checks if dirty layouts are currently being updated. + * + * Useful to avoid re-entrancy or to check if layout updates are in progress. + * + * @return Const reference to the boolean indicating layout update status. + */ + bool isUpdatingLayouts() const; + /** + * @brief Gets the UIIconThemeManager. + * + * The icon theme manager handles lookups of icon drawables by name. + * + * @return Pointer to the UIIconThemeManager. + */ UIIconThemeManager* getUIIconThemeManager() const; + /** + * @brief Finds an icon by name. + * + * Searches the icon theme manager for an icon with the specified name. + * + * @param iconName The name of the icon to find. + * @return Pointer to the UIIcon, or nullptr if not found. + */ UIIcon* findIcon( const std::string& iconName ); - /** @param drawableSize Size in pixels */ + /** + * @brief Finds an icon drawable by name and size. + * + * Convenience method that gets an icon and then retrieves a drawable + * of the specified size. + * + * @param iconName The name of the icon to find. + * @param drawableSize The desired size of the drawable in pixels. + * @return Pointer to the Drawable, or nullptr if not found. + */ Drawable* findIconDrawable( const std::string& iconName, const size_t& drawableSize ); + /** + * @brief Gets the keybindings manager. + * + * The keybindings system maps keyboard shortcuts to commands. + * + * @return Reference to the KeyBindings object. + */ + KeyBindings& getKeyBindings(); + + /** + * @brief Sets the keybindings. + * + * Replaces the current keybindings with a new set. + * + * @param keyBindings The KeyBindings object to set. + */ + void setKeyBindings( const KeyBindings& keyBindings ); + + /** + * @brief Adds a keybinding from string shortcut to command. + * + * Shortcut format is typically like "Ctrl+S" or "Alt+Enter". + * + * @param shortcut The string representation of the shortcut. + * @param command The command to execute when shortcut is pressed. + */ + void addKeyBindingString( const std::string& shortcut, const std::string& command ); + + /** + * @brief Adds a keybinding from Shortcut to command. + * + * @param shortcut The KeyBindings::Shortcut structure. + * @param command The command to execute when shortcut is pressed. + */ + void addKeyBinding( const KeyBindings::Shortcut& shortcut, const std::string& command ); + + /** + * @brief Replaces a keybinding using string shortcut. + * + * If the shortcut already exists, it is replaced; otherwise it is added. + * + * @param shortcut The string representation of the shortcut. + * @param command The command to execute. + */ + void replaceKeyBindingString( const std::string& shortcut, const std::string& command ); + + /** + * @brief Replaces a keybinding using Shortcut. + * + * If the shortcut already exists, it is replaced; otherwise it is added. + * + * @param shortcut The KeyBindings::Shortcut structure. + * @param command The command to execute. + */ + void replaceKeyBinding( const KeyBindings::Shortcut& shortcut, const std::string& command ); + + /** + * @brief Adds multiple keybindings from string map. + * + * @param binds Map of shortcut strings to command strings. + */ + void addKeyBindsString( const std::map& binds ); + + /** + * @brief Adds multiple keybindings from Shortcut map. + * + * @param binds Map of KeyBindings::Shortcut to command strings. + */ + void addKeyBinds( const std::map& binds ); + typedef std::function KeyBindingCommand; - KeyBindings& getKeyBindings(); - - void setKeyBindings( const KeyBindings& keyBindings ); - - void addKeyBindingString( const std::string& shortcut, const std::string& command ); - - void addKeyBinding( const KeyBindings::Shortcut& shortcut, const std::string& command ); - - void replaceKeyBindingString( const std::string& shortcut, const std::string& command ); - - void replaceKeyBinding( const KeyBindings::Shortcut& shortcut, const std::string& command ); - - void addKeyBindsString( const std::map& binds ); - - void addKeyBinds( const std::map& binds ); - + /** + * @brief Sets a function to execute for a command. + * + * Associates a command string with a callable function. This allows + * keybindings to trigger custom code. + * + * @param command The command string. + * @param func The function to call when the command is executed. + */ void setKeyBindingCommand( const std::string& command, KeyBindingCommand func ); + /** + * @brief Executes a keybinding command. + * + * Triggers the function associated with the given command string. + * + * @param command The command string to execute. + */ void executeKeyBindingCommand( const std::string& command ); + /** + * @brief Gets the UI-specific event dispatcher. + * + * Casts the generic event dispatcher to a UIEventDispatcher. + * + * @return Pointer to the UIEventDispatcher, or nullptr if not set. + */ UIEventDispatcher* getUIEventDispatcher() const; + /** + * @brief Gets the current color scheme preference. + * + * @return The ColorSchemePreference (Light or Dark). + */ ColorSchemePreference getColorSchemePreference() const; + /** + * @brief Sets the color scheme preference from extended preference. + * + * Converts extended preference (Light/Dark/System) to standard preference. + * For System, detects OS preference automatically. + * + * @param colorSchemePreference The extended ColorSchemeExtPreference. + */ void setColorSchemePreference( const ColorSchemeExtPreference& colorSchemePreference ); + /** + * @brief Sets the color scheme preference directly. + * + * Controls whether the UI uses light or dark color scheme by default. + * + * @param colorSchemePreference The ColorSchemePreference. + */ void setColorSchemePreference( const ColorSchemePreference& colorSchemePreference ); + /** + * @brief Gets the maximum invalidation depth. + * + * This controls how many times the update cycle will re-process dirty + * states to ensure all cascading style/layout changes are applied. + * + * @return Const reference to max invalidation depth. + */ const Uint32& getMaxInvalidationDepth() const; + /** + * @brief Sets the maximum invalidation depth. + * + * @param maxInvalidationDepth The maximum number of invalidation passes. + */ void setMaxInvalidationDepth( const Uint32& maxInvalidationDepth ); + /** + * @brief Transforms node-local coordinates to world coordinates. + * + * Override that uses dp (density-independent pixels) positions. + * + * @param Pos Reference to the position to transform (modified in place). + */ void nodeToWorldTranslation( Vector2f& Pos ) const; + /** + * @brief Reloads the UI styles. + * + * Forces all widgets to re-apply their CSS styles, optionally disabling + * animations, forcing re-application, or resetting property caches. + * + * @param disableAnimations If true, CSS animations are disabled during reload. + * @param forceReApplyProperties If true, all properties are re-applied even if unchanged. + * @param resetPropertiesCache If true, property cache is cleared. + */ void reloadStyle( bool disableAnimations = false, bool forceReApplyProperties = false, bool resetPropertiesCache = false ); + /** + * @brief Checks if a thread pool is available. + * + * @return True if a thread pool has been set, false otherwise. + */ bool hasThreadPool() const; + /** + * @brief Gets the thread pool. + * + * @return Shared pointer to the ThreadPool, or nullptr if none set. + */ std::shared_ptr getThreadPool(); + /** + * @brief Sets the thread pool for background tasks. + * + * @param threadPool Shared pointer to the ThreadPool to use. + */ void setThreadPool( const std::shared_ptr& threadPool ); + /** + * @brief Sets the theme for the entire UI scene. + * + * Applies the theme to the root widget and all children. + * + * @param theme Pointer to the UITheme to set. + */ void setTheme( UITheme* theme ); + /** + * @brief Gets the current media features. + * + * Returns information about the current media environment (screen size, + * resolution, color scheme, etc.) for CSS media queries. + * + * @return CSS::MediaFeatures structure with current media values. + */ CSS::MediaFeatures getMediaFeatures() const; protected: friend class EE::UI::UIWindow; friend class EE::UI::UIWidget; + UIWidget* mRoot{ nullptr }; Sizef mDpSize; Uint32 mFlags; @@ -196,50 +699,212 @@ class EE_API UISceneNode : public SceneNode { Uint32 mCurOnSizeChangeListener{ 0 }; std::shared_ptr mThreadPool; + /** + * @brief Protected constructor. + * + * Creates a UISceneNode with optional window association. + * + * @param window Pointer to the window, or NULL for default. + */ explicit UISceneNode( EE::Window::Window* window = NULL ); + /** + * @brief Handles node resize. + * + * Called when the window resizes. Updates the node size accordingly. + * + * @param win Pointer to the window that was resized. + */ virtual void resizeNode( EE::Window::Window* win ); + /** + * @brief Called when debug data drawing setting changes. + * + * Override to respond to changes in drawDebugData flag. + */ virtual void onDrawDebugDataChange(); + /** + * @brief Requests focus for this scene node. + * + * Delegates to the event dispatcher to set focus on the root widget. + * + * @param reason The reason for the focus request. + * @return Pointer to this node, or nullptr if focus failed. + */ virtual Node* setFocus( NodeFocusReason reason = NodeFocusReason::Unknown ); + /** + * @brief Called when this node's parent changes. + * + * Handles event dispatcher updates and size propagation. + */ virtual void onParentChange(); + /** + * @brief Sets the internal pixel size without triggering update cycles. + * + * Used internally for size adjustments that shouldn't generate events. + * + * @param size The new size in pixels. + */ void setInternalPixelsSize( const Sizef& size ); + /** + * @brief Sets the active window for this scene. + * + * @param window Pointer to the UIWindow to set as active. + */ void setActiveWindow( UIWindow* window ); + /** + * @brief Manages focus when a window loses focus. + * + * Ensures proper focus restoration when switching windows. + * + * @param window The window that was focused. + */ void setFocusLastWindow( UIWindow* window ); + /** + * @brief Adds a window to the scene's window list. + * + * @param win Pointer to the UIWindow to add. + */ void windowAdd( UIWindow* win ); + /** + * @brief Removes a window from the scene's window list. + * + * @param win Pointer to the UIWindow to remove. + */ void windowRemove( UIWindow* win ); + /** + * @brief Checks if a window exists in the scene's window list. + * + * @param win Pointer to the UIWindow to check. + * @return True if the window is in the list, false otherwise. + */ bool windowExists( UIWindow* win ); + /** + * @brief Sets the internal size in dp. + * + * Called internally when the size needs to be set in dp units. + * Updates the dp size and triggers size change notifications. + * + * @param size The new size in dp. + */ virtual void setInternalSize( const Sizef& size ); + /** + * @brief Handles media query changes. + * + * Called when media features might have changed (like DPI or size). + * Updates stylesheet media queries and triggers style re-evaluation if needed. + * + * @param forceReApplyStyles If true, forces all styles to be re-applied. + * @return True if media queries changed and styles were invalidated. + */ bool onMediaChanged( bool forceReApplyStyles = false ); + /** + * @brief Called when a child is added or removed. + * + * Override to handle child count changes. Automatically re-parents + * non-root children to the root widget. + * + * @param child The child node that changed. + * @param removed True if removed, false if added. + */ virtual void onChildCountChange( Node* child, const bool& removed ); + /** + * @brief Called when the node's size changes. + * + * Updates the root widget's pixel size and triggers size change events. + */ virtual void onSizeChange(); + /** + * @brief Processes @font-face and @glyph-icon rules in a stylesheet. + * + * Extracts font face definitions and glyph icon definitions from + * the stylesheet's at-rules and loads them. + * + * @param styleSheet The stylesheet to process. + */ void processStyleSheetAtRules( const CSS::StyleSheet& styleSheet ); + /** + * @brief Loads font faces from @font-face rules. + * + * Parses font face styles and loads the fonts from various sources + * (files, URLs, VFS). + * + * @param styles Vector of stylesheet styles from @font-face rules. + */ void loadFontFaces( const CSS::StyleSheetStyleVector& styles ); + /** + * @brief Loads glyph icons from @glyph-icon rules. + * + * Parses glyph icon definitions and registers them with the icon theme manager. + * + * @param styles Vector of stylesheet styles from @glyph-icon rules. + */ void loadGlyphIcon( const CSS::StyleSheetStyleVector& styles ); + /** + * @brief Handles key down events. + * + * Checks key bindings and executes associated commands. Override for + * custom keyboard handling. + * + * @param event The key event. + * @return 0 if the event was handled by a binding, otherwise base class return. + */ virtual Uint32 onKeyDown( const KeyEvent& event ); + /** + * @brief Called when a node is deleted. + * + * Cleans up dirty state tracking for the deleted node if it's a widget. + * + * @param node The node that was deleted. + */ void onWidgetDelete( Node* node ); + /** + * @brief Recursively resets tooltips for a node and its children. + * + * Used when debug mode is turned off to hide all tooltips. + * + * @param node The node to reset tooltips for. + */ void resetTooltips( Node* node ); + /** + * @brief Loads UI nodes from XML. + * + * Core method that parses XML and creates widget hierarchy. + * + * @param node The XML node to parse. + * @param parent The parent to attach widgets to. + * @param marker Marker for style association. + * @return Vector of root widgets created. + */ std::vector loadNode( pugi::xml_node node, Node* parent, const Uint32& marker ); + /** + * @brief Applies a theme to a node and its subtree. + * + * Recursively applies the specified UITheme to all widgets in the subtree. + * + * @param theme Pointer to the UITheme to apply. + * @param to The root node of the subtree to theme. + */ void setTheme( UITheme* theme, Node* to ); }; diff --git a/include/eepp/ui/uiwidget.hpp b/include/eepp/ui/uiwidget.hpp index d58403273..b78210b18 100644 --- a/include/eepp/ui/uiwidget.hpp +++ b/include/eepp/ui/uiwidget.hpp @@ -21,268 +21,1235 @@ namespace EE { namespace UI { class UITooltip; class UIStyle; +/** + * @brief Base class for all UI widgets in the eepp framework. + * + * UIWidget provides the core functionality for building graphical user interface + * elements. It serves as the foundation for all GUI components including text + * views, buttons, input fields, and containers. The class integrates with the + * CSS styling system, supports layout management, and handles user interactions. + * + * Typical usage: Derive from UIWidget to create custom widgets or use built-in + * derived classes like UITextView, UIPushButton, etc. + * + * @see UITextView + * @see UIPushButton + * @see UITextInput + */ class EE_API UIWidget : public UINode { public: + /** + * @brief Creates a new UIWidget with default tag "widget". + * + * This is the primary factory method for creating UIWidget instances. + * + * @return Pointer to the newly created UIWidget instance. + * @see NewWithTag + */ static UIWidget* New(); + /** + * @brief Creates a new UIWidget with a specific CSS tag. + * + * The tag parameter sets the CSS element tag which can be used for styling + * with CSS selectors. This is useful when you need to apply specific styles + * to certain widget types. + * + * @param tag The CSS element tag for the widget. + * @return Pointer to the newly created UIWidget instance. + * @see New + */ static UIWidget* NewWithTag( const std::string& tag ); virtual ~UIWidget(); + /** + * @brief Gets the widget type identifier. + * + * Returns a unique type identifier for this widget class. + * + * @return The widget type as a Uint32. + */ virtual Uint32 getType() const; + /** + * @brief Checks if the widget is of a specific type. + * + * Determines whether this widget is of the specified type or derived from it. + * + * @param type The type identifier to check. + * @return True if the widget is of the specified type, false otherwise. + */ virtual bool isType( const Uint32& type ) const; + /** + * @brief Sets multiple flags on the widget. + * + * Flags control various widget behaviors and states. Common flags include: + * - UI_ANCHOR_LEFT, UI_ANCHOR_TOP, UI_ANCHOR_RIGHT, UI_ANCHOR_BOTTOM + * - UI_AUTO_SIZE, UI_TAB_FOCUSABLE, UI_TOOLTIP_ENABLED + * + * @see UIFlag + * @param flags Bitwise combination of flags to set. + * @return Pointer to this widget for method chaining. + */ virtual UINode* setFlags( const Uint32& flags ); + /** + * @brief Unsets multiple flags on the widget. + * + * Removes the specified flags from the widget's current flag set. + * + * @see UIFlag + * @param flags Bitwise combination of flags to unset. + * @return Pointer to this widget for method chaining. + */ virtual UINode* unsetFlags( const Uint32& flags ); + /** + * @brief Sets anchor flags for relative positioning. + * + * Anchors control how the widget positions itself relative to its parent. + * Use combinations of UI_ANCHOR_LEFT, UI_ANCHOR_TOP, UI_ANCHOR_RIGHT, UI_ANCHOR_BOTTOM. + * + * @param flags Bitwise combination of anchor flags. + * @return Pointer to this widget for method chaining. + */ virtual UIWidget* setAnchors( const Uint32& flags ); + /** + * @brief Sets the theme for this widget. + * + * Applies the specified theme to the widget, affecting its visual appearance. + * The theme controls colors, fonts, borders, and other visual properties. + * + * @param Theme Pointer to the UITheme to apply. + */ virtual void setTheme( UITheme* Theme ); + /** + * @brief Sets the theme skin for this widget. + * + * Applies a specific skin from the current theme. If no theme is set, + * the default theme will be used. + * + * @param skinName Name of the skin to apply. + * @return Pointer to this widget for method chaining. + */ virtual UINode* setThemeSkin( const std::string& skinName ); + /** + * @brief Sets the theme skin for this widget with a specific theme. + * + * Applies a specific skin from the specified theme. + * + * @param Theme Pointer to the UITheme to use. + * @param skinName Name of the skin to apply. + * @return Pointer to this widget for method chaining. + */ virtual UINode* setThemeSkin( UITheme* Theme, const std::string& skinName ); + /** + * @brief Sets the unique identifier for this widget. + * + * The ID can be used for CSS selection and widget identification. + * + * @param id Unique identifier string. + * @return Pointer to this widget for method chaining. + */ virtual Node* setId( const std::string& id ); + /** + * @brief Checks if this widget can accept a dropped widget. + * + * Determines whether another widget can be dropped onto this widget. + * + * @param widget The widget to check for drop acceptance. + * @return True if the widget can be dropped, false otherwise. + */ virtual bool acceptsDropOfWidget( const UIWidget* widget ); + /** + * @brief Checks if this widget can accept a dropped widget in its tree. + * + * Recursively checks if this widget or any of its children can accept + * the specified widget as a drop target. + * + * @param widget The widget to check for drop acceptance. + * @return Pointer to the widget that accepts the drop, or nullptr if none. + */ UIWidget* acceptsDropOfWidgetInTree( const UIWidget* widget ); + /** + * @brief Gets the tooltip associated with this widget. + * + * Returns the tooltip object if one exists, or nullptr if no tooltip is set. + * + * @return Pointer to the UITooltip object or nullptr. + */ UITooltip* getTooltip(); + /** + * @brief Removes the tooltip from this widget. + * + * Detaches and deletes the tooltip object associated with this widget. + */ void tooltipRemove(); + /** + * @brief Sets the tooltip text for this widget. + * + * Creates a tooltip if one doesn't exist and sets its text content. + * + * @param text The text to display in the tooltip. + * @return Pointer to this widget for method chaining. + */ UIWidget* setTooltipText( const String& text ); + /** + * @brief Sets the tooltip text only if the text is not empty. + * + * This is useful for conditional tooltip setting where you only want + * to set a tooltip if there's actual content to display. + * + * @param text The text to display in the tooltip. + * @return Pointer to this widget for method chaining. + */ UIWidget* setTooltipTextIfNotEmpty( const String& text ); + /** + * @brief Gets the current tooltip text. + * + * Returns the text that will be displayed in the tooltip. + * + * @return The tooltip text string. + */ String getTooltipText(); + /** + * @brief Updates the distances to parent borders for anchoring. + * + * Recalculates the distances from this widget to the borders of its + * parent widget. This is used for anchor-based positioning. + */ void updateAnchorsDistances(); + /** + * @brief Gets the layout margin in density-independent pixels (dp). + * + * Layout margins define the space around the widget within its parent + * layout container. These values are in dp to support different screen densities. + * + * @return The layout margin as a Rectf. + */ const Rectf& getLayoutMargin() const; + /** + * @brief Gets the layout margin in actual pixels. + * + * Returns the margin values converted to actual screen pixels. + * + * @return The layout margin in pixels as a Rectf. + */ const Rectf& getLayoutPixelsMargin() const; + /** + * @brief Sets the layout margin for all sides. + * + * Sets the margin around the widget in density-independent pixels (dp). + * + * @param margin The margin values for left, top, right, bottom. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutMargin( const Rectf& margin ); + /** + * @brief Sets the left layout margin. + * + * Sets the left margin in density-independent pixels (dp). + * + * @param marginLeft The left margin value. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutMarginLeft( const Float& marginLeft ); + /** + * @brief Sets the right layout margin. + * + * Sets the right margin in density-independent pixels (dp). + * + * @param marginRight The right margin value. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutMarginRight( const Float& marginRight ); + /** + * @brief Sets the top layout margin. + * + * Sets the top margin in density-independent pixels (dp). + * + * @param marginTop The top margin value. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutMarginTop( const Float& marginTop ); + /** + * @brief Sets the bottom layout margin. + * + * Sets the bottom margin in density-independent pixels (dp). + * + * @param marginBottom The bottom margin value. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutMarginBottom( const Float& marginBottom ); + /** + * @brief Sets the layout margin for all sides in pixels. + * + * Sets the margin around the widget in actual screen pixels. + * + * @param margin The margin values for left, top, right, bottom in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutPixelsMargin( const Rectf& margin ); + /** + * @brief Sets the left margin in pixels. + * + * Sets the left margin in actual screen pixels. + * + * @param marginLeft The left margin value in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutPixelsMarginLeft( const Float& marginLeft ); + /** + * @brief Sets the right margin in pixels. + * + * Sets the right margin in actual screen pixels. + * + * @param marginRight The right margin value in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutPixelsMarginRight( const Float& marginRight ); + /** + * @brief Sets the top margin in pixels. + * + * Sets the top margin in actual screen pixels. + * + * @param marginTop The top margin value in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutPixelsMarginTop( const Float& marginTop ); + /** + * @brief Sets the bottom margin in pixels. + * + * Sets the bottom margin in actual screen pixels. + * + * @param marginBottom The bottom margin value in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutPixelsMarginBottom( const Float& marginBottom ); + /** + * @brief Gets the layout weight for this widget. + * + * Layout weight determines how much space this widget should take + * relative to other widgets in a LinearLayout. A weight of 0 means + * the widget takes only the space it needs. + * + * @return The layout weight as a Float. + */ Float getLayoutWeight() const; + /** + * @brief Sets the layout weight for this widget. + * + * Used in LinearLayout to distribute extra space among widgets. + * + * @param weight The layout weight value. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutWeight( const Float& weight ); + /** + * @brief Gets the layout gravity for this widget. + * + * Layout gravity determines how the widget is positioned within + * its parent layout. Common values include: + * - Gravity::Left, Gravity::Right, Gravity::Top, Gravity::Bottom + * - Gravity::Center, Gravity::CenterHorizontal, Gravity::CenterVertical + * + * @return The layout gravity as a Uint32 bitmask. + */ Uint32 getLayoutGravity() const; + /** + * @brief Sets the layout gravity for this widget. + * + * Controls how the widget is aligned within its parent layout. + * + * @param layoutGravity The gravity bitmask. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutGravity( const Uint32& layoutGravity ); + /** + * @brief Gets the width size policy for this widget. + * + * Size policies control how the widget resizes: + * - SizePolicy::WrapContent: Size to content + * - SizePolicy::MatchParent: Match parent size + * - SizePolicy::Exact: Exact size + * - SizePolicy::FillParent: Fill parent (may exceed) + * + * @return The width size policy. + */ const SizePolicy& getLayoutWidthPolicy() const; + /** + * @brief Sets the width size policy for this widget. + * + * Controls how the widget's width is determined. + * + * @param widthPolicy The size policy to apply. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutWidthPolicy( const SizePolicy& widthPolicy ); + /** + * @brief Gets the height size policy for this widget. + * + * Size policies control how the widget resizes: + * - SizePolicy::WrapContent: Size to content + * - SizePolicy::MatchParent: Match parent size + * - SizePolicy::Exact: Exact size + * - SizePolicy::FillParent: Fill parent (may exceed) + * + * @return The height size policy. + */ const SizePolicy& getLayoutHeightPolicy() const; + /** + * @brief Sets the height size policy for this widget. + * + * Controls how the widget's height is determined. + * + * @param heightPolicy The size policy to apply. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutHeightPolicy( const SizePolicy& heightPolicy ); + /** + * @brief Sets both width and height size policies. + * + * Convenience method to set both size policies at once. + * + * @param widthPolicy The width size policy. + * @param heightPolicy The height size policy. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutSizePolicy( const SizePolicy& widthPolicy, const SizePolicy& heightPolicy ); + /** + * @brief Sets the position policy for relative positioning. + * + * Position policies allow positioning this widget relative to another widget: + * - PositionPolicy::Above, Below, LeftOf, RightOf + * - PositionPolicy::AlignLeft, AlignRight, AlignTop, AlignBottom + * - PositionPolicy::CenterIn + * + * @param layoutPositionPolicy The position policy to apply. + * @param of The reference widget for positioning. + * @return Pointer to this widget for method chaining. + */ UIWidget* setLayoutPositionPolicy( const PositionPolicy& layoutPositionPolicy, UIWidget* of ); + /** + * @brief Gets the reference widget for position policy. + * + * Returns the widget that this widget is positioned relative to. + * + * @return Pointer to the reference widget or nullptr. + */ UIWidget* getLayoutPositionPolicyWidget() const; + /** + * @brief Gets the current position policy. + * + * Returns the position policy that determines how this widget is positioned + * relative to another widget. + * + * @return The position policy. + */ PositionPolicy getLayoutPositionPolicy() const; + /** + * @brief Loads widget configuration from an XML node. + * + * Parses XML configuration to set up the widget's properties, styles, and + * layout attributes. This is used for loading UI layouts from XML files. + * + * @param node The XML node containing the widget configuration. + */ virtual void loadFromXmlNode( const pugi::xml_node& node ); + /** + * @brief Notifies that layout attributes have changed. + * + * Triggers layout recalculation when layout-related properties change. + * This should be called after modifying layout attributes like margins, + * padding, size policies, etc. + */ void notifyLayoutAttrChange(); + /** + * @brief Notifies parent that layout attributes have changed. + * + * Triggers layout recalculation in the parent widget when this widget's + * layout attributes change. This ensures proper layout propagation. + */ void notifyLayoutAttrChangeParent(); + /** + * @brief Sets an inline CSS property. + * + * Applies a CSS property directly to this widget with high specificity. + * This overrides styles from stylesheets and themes. + * + * @param name The CSS property name. + * @param value The CSS property value. + * @param specificity The specificity level (default is inline specificity). + */ void setStyleSheetInlineProperty( const std::string& name, const std::string& value, const Uint32& specificity = UINT32_MAX - 1 /*SpecificityInline*/ ); + /** + * @brief Applies a CSS property to this widget. + * + * Applies the specified CSS property to the widget, updating its style + * and triggering any necessary style changes. + * + * @param attribute The CSS property to apply. + * @return True if the property was applied successfully, false otherwise. + */ virtual bool applyProperty( const StyleSheetProperty& attribute ); + /** + * @brief Gets the padding in density-independent pixels (dp). + * + * Padding defines the space between the widget's content and its border. + * These values are in dp to support different screen densities. + * + * @return The padding as a Rectf. + */ const Rectf& getPadding() const; + /** + * @brief Gets the padding in actual pixels. + * + * Returns the padding values converted to actual screen pixels. + * + * @return The padding in pixels as a Rectf. + */ const Rectf& getPixelsPadding() const; + /** + * @brief Sets the padding for all sides. + * + * Sets the padding around the widget's content in density-independent pixels (dp). + * + * @param padding The padding values for left, top, right, bottom. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPadding( const Rectf& padding ); + /** + * @brief Sets the left padding. + * + * Sets the left padding in density-independent pixels (dp). + * + * @param paddingLeft The left padding value. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPaddingLeft( const Float& paddingLeft ); + /** + * @brief Sets the right padding. + * + * Sets the right padding in density-independent pixels (dp). + * + * @param paddingRight The right padding value. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPaddingRight( const Float& paddingRight ); + /** + * @brief Sets the top padding. + * + * Sets the top padding in density-independent pixels (dp). + * + * @param paddingTop The top padding value. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPaddingTop( const Float& paddingTop ); + /** + * @brief Sets the bottom padding. + * + * Sets the bottom padding in density-independent pixels (dp). + * + * @param paddingBottom The bottom padding value. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPaddingBottom( const Float& paddingBottom ); + /** + * @brief Sets the padding for all sides in pixels. + * + * Sets the padding around the widget's content in actual screen pixels. + * + * @param padding The padding values for left, top, right, bottom in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPaddingPixels( const Rectf& padding ); + /** + * @brief Sets the left padding in pixels. + * + * Sets the left padding in actual screen pixels. + * + * @param paddingLeft The left padding value in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPaddingPixelsLeft( const Float& paddingLeft ); + /** + * @brief Sets the right padding in pixels. + * + * Sets the right padding in actual screen pixels. + * + * @param paddingRight The right padding value in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPaddingPixelsRight( const Float& paddingRight ); + /** + * @brief Sets the top padding in pixels. + * + * Sets the top padding in actual screen pixels. + * + * @param paddingTop The top padding value in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPaddingPixelsTop( const Float& paddingTop ); + /** + * @brief Sets the bottom padding in pixels. + * + * Sets the bottom padding in actual screen pixels. + * + * @param paddingBottom The bottom padding value in pixels. + * @return Pointer to this widget for method chaining. + */ UIWidget* setPaddingPixelsBottom( const Float& paddingBottom ); + /** + * @brief Gets the CSS tag for this widget. + * + * Returns the CSS element tag that can be used for styling with CSS selectors. + * + * @return The CSS tag string. + */ const std::string& getStyleSheetTag() const; + /** + * @brief Gets the CSS ID for this widget. + * + * Returns the CSS ID that can be used for styling with CSS selectors. + * + * @return The CSS ID string. + */ const std::string& getStyleSheetId() const; + /** + * @brief Gets all CSS classes for this widget. + * + * Returns a vector of all CSS classes applied to this widget. + * + * @return Vector of CSS class strings. + */ inline const std::vector& getStyleSheetClasses() const { return mClasses; } + /** + * @brief Gets the parent element for CSS styling. + * + * Returns the parent widget that serves as the parent element in CSS + * selector resolution. + * + * @return Pointer to the parent element widget or nullptr. + */ UIWidget* getStyleSheetParentElement() const; + /** + * @brief Gets the previous sibling element for CSS styling. + * + * Returns the previous sibling widget in the CSS selector context. + * + * @return Pointer to the previous sibling element widget or nullptr. + */ UIWidget* getStyleSheetPreviousSiblingElement() const; + /** + * @brief Gets the next sibling element for CSS styling. + * + * Returns the next sibling widget in the CSS selector context. + * + * @return Pointer to the next sibling element widget or nullptr. + */ UIWidget* getStyleSheetNextSiblingElement() const; + /** + * @brief Gets the active pseudo-classes for this widget. + * + * Returns a bitmask of active pseudo-classes (hover, focus, active, etc.). + * + * @return Bitmask of active pseudo-classes. + */ Uint32 getStyleSheetPseudoClasses() const { return mPseudoClasses; } + /** + * @brief Gets the pseudo-classes as string array. + * + * Returns an array of strings representing the active pseudo-classes. + * + * @return Vector of pseudo-class strings. + */ std::vector getStyleSheetPseudoClassesStrings() const; + /** + * @brief Resets all CSS classes and removes them. + * + * Clears all CSS classes from this widget. + * + * @return Pointer to this widget for method chaining. + */ UIWidget* resetClass(); - /** Resets all classes and assign a class */ + /** + * @brief Sets a single CSS class. + * + * Resets all existing classes and sets the specified class. + * + * @param cls The CSS class to set. + * @return Pointer to this widget for method chaining. + */ UIWidget* setClass( const std::string& cls ); + /** + * @brief Sets a single CSS class (move version). + * + * Resets all existing classes and sets the specified class using move semantics. + * + * @param cls The CSS class to set (moved). + * @return Pointer to this widget for method chaining. + */ UIWidget* setClass( std::string&& cls ); - /** Resets all classes and assign vector of classes */ + /** + * @brief Sets multiple CSS classes. + * + * Resets all existing classes and sets the specified vector of classes. + * + * @param classes Vector of CSS classes to set. + * @return Pointer to this widget for method chaining. + */ UIWidget* setClasses( const std::vector& classes ); + /** + * @brief Adds a CSS class. + * + * Adds the specified class to the widget's existing classes. + * + * @param cls The CSS class to add. + * @return Pointer to this widget for method chaining. + */ UIWidget* addClass( const std::string& cls ); + /** + * @brief Adds multiple CSS classes. + * + * Adds the specified vector of classes to the widget's existing classes. + * + * @param classes Vector of CSS classes to add. + * @return Pointer to this widget for method chaining. + */ UIWidget* addClasses( const std::vector& classes ); + /** + * @brief Removes a CSS class. + * + * Removes the specified class from the widget's existing classes. + * + * @param cls The CSS class to remove. + * @return Pointer to this widget for method chaining. + */ UIWidget* removeClass( const std::string& cls ); + /** + * @brief Removes multiple CSS classes. + * + * Removes the specified vector of classes from the widget's existing classes. + * + * @param classes Vector of CSS classes to remove. + * @return Pointer to this widget for method chaining. + */ UIWidget* removeClasses( const std::vector& classes ); + /** + * @brief Checks if the widget has a specific CSS class. + * + * Determines whether the widget has the specified CSS class. + * + * @param cls The CSS class to check. + * @return True if the widget has the class, false otherwise. + */ bool hasClass( const std::string_view& cls ) const; + /** + * @brief Toggles a CSS class. + * + * Adds the class if it doesn't exist, removes it if it does. + * + * @param cls The CSS class to toggle. + */ void toggleClass( const std::string& cls ); + /** + * @brief Sets the CSS element tag. + * + * Sets the CSS element tag that can be used for styling with CSS selectors. + * + * @param tag The CSS element tag to set. + */ void setElementTag( const std::string& tag ); + /** + * @brief Gets all CSS classes for this widget. + * + * Returns a vector of all CSS classes applied to this widget. + * + * @return Vector of CSS class strings. + */ const std::vector& getClasses() const; + /** + * @brief Gets the CSS element tag. + * + * Returns the CSS element tag that can be used for styling with CSS selectors. + * + * @return The CSS element tag string. + */ inline const std::string& getElementTag() const { return mTag; } + /** + * @brief Pushes a state onto the widget's state stack. + * + * Adds a new state to the widget's current state stack. This is used to + * track multiple states (hover, pressed, etc.) that can be combined. + * + * @param State The state to push. + * @param emitEvent Whether to emit a state change event. + */ virtual void pushState( const Uint32& State, bool emitEvent = true ); + /** + * @brief Pops a state from the widget's state stack. + * + * Removes a state from the widget's current state stack. This is used to + * revert to a previous state. + * + * @param State The state to pop. + * @param emitEvent Whether to emit a state change event. + */ virtual void popState( const Uint32& State, bool emitEvent = true ); + /** + * @brief Gets the UIStyle object for this widget. + * + * Returns the style object that manages CSS properties, animations, and + * transitions for this widget. + * + * @return Pointer to the UIStyle object. + */ UIStyle* getUIStyle() const; + /** + * @brief Reloads the widget's style. + * + * Forces the widget to reload its style from CSS stylesheets, themes, and + * inline properties. This is useful when style changes need to be applied + * immediately. + * + * @param reloadChildren Whether to reload styles for child widgets. + * @param disableAnimations Whether to disable CSS animations during reload. + * @param reportStateChange Whether to report state changes. + * @param forceReApplyProperties Whether to force re-application of all properties. + * @param resetPropertyCache Whether to reset the property cache. + */ void reloadStyle( bool reloadChildren = true, bool disableAnimations = false, bool reportStateChange = true, bool forceReApplyProperties = false, bool resetPropertyCache = false ); + /** + * @brief Begins an attributes transaction. + * + * Starts a transaction for batch attribute changes. This prevents multiple + * style recalculations during bulk updates. + */ void beginAttributesTransaction(); + /** + * @brief Ends an attributes transaction. + * + * Ends a transaction and applies all pending attribute changes at once. + */ void endAttributesTransaction(); + /** + * @brief Gets the current style state. + * + * Returns the current state bitmask (hover, focus, pressed, etc.). + * + * @return Current style state bitmask. + */ const Uint32& getStyleState() const; + /** + * @brief Gets the previous style state. + * + * Returns the previous state bitmask before the current state change. + * + * @return Previous style state bitmask. + */ const Uint32& getStylePreviousState() const; + /** + * @brief Finds all widgets by CSS class. + * + * Searches the widget tree for all widgets with the specified CSS class. + * + * @param className The CSS class to search for. + * @return Vector of matching UIWidget pointers. + */ std::vector findAllByClass( const std::string& className ); + /** + * @brief Finds all widgets by CSS tag. + * + * Searches the widget tree for all widgets with the specified CSS tag. + * + * @param tag The CSS tag to search for. + * @return Vector of matching UIWidget pointers. + */ std::vector findAllByTag( const std::string& tag ); + /** + * @brief Finds a widget by CSS class. + * + * Searches for the first widget with the specified CSS class. + * + * @param className The CSS class to search for. + * @return Pointer to the first matching widget or nullptr. + */ UIWidget* findByClass( const std::string& className ); template T* findByClass( const std::string& className ) { return reinterpret_cast( findByClass( className ) ); } + /** + * @brief Finds a widget by CSS tag. + * + * Searches for the first widget with the specified CSS tag. + * + * @param tag The CSS tag to search for. + * @return Pointer to the first matching widget or nullptr. + */ UIWidget* findByTag( const std::string& tag ); template T* findByTag( const std::string& tag ) { return reinterpret_cast( findByTag( tag ) ); } + /** + * @brief Queries a widget using a CSS selector. + * + * Finds the first widget matching the specified CSS selector. + * + * @param selector The CSS selector to use. + * @return Pointer to the first matching widget or nullptr. + */ UIWidget* querySelector( const CSS::StyleSheetSelector& selector ); + /** + * @brief Queries a widget using a CSS selector string. + * + * Finds the first widget matching the specified CSS selector string. + * + * @param selector The CSS selector string to use. + * @return Pointer to the first matching widget or nullptr. + */ UIWidget* querySelector( const std::string& selector ); template T* querySelector( const std::string& selector ) { return reinterpret_cast( querySelector( selector ) ); } + /** + * @brief Queries all widgets using a CSS selector. + * + * Finds all widgets matching the specified CSS selector. + * + * @param selector The CSS selector to use. + * @return Vector of all matching UIWidget pointers. + */ std::vector querySelectorAll( const CSS::StyleSheetSelector& selector ); + /** + * @brief Queries all widgets using a CSS selector string. + * + * Finds all widgets matching the specified CSS selector string. + * + * @param selector The CSS selector string to use. + * @return Vector of all matching UIWidget pointers. + */ std::vector querySelectorAll( const std::string& selector ); + /** + * @brief Gets a property value as a string. + * + * Returns the value of the specified CSS property as a string. + * + * @param property The CSS property name. + * @return The property value as a string. + */ std::string getPropertyString( const std::string& property ) const; + /** + * @brief Gets a property value as a string with property definition. + * + * Returns the value of the specified CSS property as a string, using + * the property definition for proper formatting. + * + * @param propertyDef The property definition. + * @param propertyIndex The property index (for multi-value properties). + * @return The property value as a string. + */ virtual std::string getPropertyString( const PropertyDefinition* propertyDef, const Uint32& propertyIndex = 0 ) const; + /** + * @brief Gets the list of properties implemented by this widget. + * + * Returns a vector of property IDs that this widget implements. + * This is used for CSS property introspection and validation. + * + * @return Vector of implemented property IDs. + */ virtual std::vector getPropertiesImplemented() const; + /** + * @brief Checks if the scene node is currently loading. + * + * Determines whether the scene node is in the process of loading, + * which can affect style application and event handling. + * + * @return True if the scene node is loading, false otherwise. + */ bool isSceneNodeLoading() const; + /** + * @brief Reports style state change recursively. + * + * Propagates style state changes to this widget and all its children. + * This is used when style changes need to be applied throughout the widget tree. + * + * @param disableAnimations Whether to disable CSS animations during the change. + * @param forceReApplyStyles Whether to force re-application of all styles. + */ void reportStyleStateChangeRecursive( bool disableAnimations = false, bool forceReApplyStyles = false ); + /** + * @brief Creates a tooltip for this widget. + * + * Creates and returns a tooltip object if one doesn't already exist. + * + * @return Pointer to the UITooltip object. + */ UITooltip* createTooltip(); + /** + * @brief Checks if this widget is a tab stop. + * + * Determines whether this widget can receive focus when the user presses the + * Tab key to navigate through widgets. + * + * @return True if this widget is a tab stop, false otherwise. + */ bool isTabStop() const; + /** + * @brief Sets this widget as a tab stop. + * + * Makes this widget able to receive focus when the user presses the Tab key. + */ void setTabStop(); + /** + * @brief Unsets this widget as a tab stop. + * + * Prevents this widget from receiving focus when the user presses the Tab key. + */ void unsetTabStop(); + /** + * @brief Checks if this widget is tab focusable. + * + * Determines whether this widget can receive focus via tab navigation. + * + * @return True if this widget is tab focusable, false otherwise. + */ bool isTabFocusable() const; + /** + * @brief Sets this widget as tab focusable. + * + * Makes this widget able to receive focus via tab navigation. + */ void setTabFocusable(); + /** + * @brief Unsets this widget as tab focusable. + * + * Prevents this widget from receiving focus via tab navigation. + */ void unsetTabFocusable(); + /** + * @brief Gets the previous widget in tab order. + * + * Returns the widget that comes before this one in the tab navigation sequence. + * + * @return Pointer to the previous tab widget or nullptr. + */ UIWidget* getPrevTabWidget() const; + /** + * @brief Gets the next widget in tab order. + * + * Returns the widget that comes after this one in the tab navigation sequence. + * + * @return Pointer to the next tab widget or nullptr. + */ UIWidget* getNextTabWidget() const; + /** + * @brief Checks if this widget has a specific pseudo-class. + * + * Determines whether this widget currently has the specified pseudo-class + * (e.g., hover, focus, active). + * + * @param pseudoCls The pseudo-class to check. + * @return True if the widget has the pseudo-class, false otherwise. + */ bool hasPseudoClass( const std::string& pseudoCls ) const; + /** + * @brief Checks if the tooltip is enabled for this widget. + * + * Determines whether tooltips are enabled for this widget. + * + * @return True if tooltips are enabled, false otherwise. + */ bool isTooltipEnabled() const; + /** + * @brief Sets whether the tooltip is enabled for this widget. + * + * Enables or disables tooltips for this widget. + * + * @param enabled True to enable tooltips, false to disable. + */ void setTooltipEnabled( bool enabled ); + /** + * @brief Gets the previous widget in the widget sequence. + * + * Returns the previous widget in the overall widget sequence (not necessarily + * tab order). + * + * @return Pointer to the previous widget or nullptr. + */ UIWidget* getPrevWidget() const; + /** + * @brief Gets the next widget in the widget sequence. + * + * Returns the next widget in the overall widget sequence (not necessarily + * tab order). + * + * @return Pointer to the next widget or nullptr. + */ UIWidget* getNextWidget() const; + /** + * @brief Gets a translated string. + * + * Returns the translation for the specified string using the current + * translation system. + * + * @param str The string to translate. + * @return The translated string. + */ String getTranslatorString( const std::string& str ); + /** + * @brief Gets a translated string with default value. + * + * Returns the translation for the specified string using the current + * translation system, or returns defaultValue if no translation is found. + * + * @param str The string to translate. + * @param defaultValue The default value to return if translation not found. + * @return The translated string or default value. + */ String getTranslatorString( const std::string& str, const String& defaultValue ); + /** + * @brief Translates a string (shorthand method). + * + * Convenience method for translating strings using the current translation system. + * + * @param str The string to translate. + * @return The translated string. + */ String i18n( const std::string& str ); + /** + * @brief Translates a string with default value (shorthand method). + * + * Convenience method for translating strings using the current translation system, + * with a default value if no translation is found. + * + * @param str The string to translate. + * @param defaultValue The default value to return if no translation is found. + * @return The translated string or default value. + */ String i18n( const std::string& str, const String& defaultValue ); protected: @@ -311,80 +1278,345 @@ class EE_API UIWidget : public UINode { std::vector mClasses; String mTooltipText; + /** + * @brief Default constructor. + * + * Creates a UIWidget with the default tag "widget". + * This constructor is protected and widgets should be created via New() methods. + */ UIWidget(); + /** + * @brief Constructor with specific tag. + * + * Creates a UIWidget with the specified CSS tag. + * This constructor is protected and widgets should be created via New() methods. + * + * @param tag The CSS element tag for the widget. + */ explicit UIWidget( const std::string& tag ); + /** + * @brief Updates pseudo-classes based on current state. + * + * Updates the internal pseudo-class bitmask based on the widget's current + * state (hover, focus, active, etc.). This is called automatically when + * state changes occur. + */ void updatePseudoClasses(); + /** + * @brief Handles child count changes. + * + * Called when a child is added or removed from this widget. This can be + * overridden to implement custom behavior when the widget's child count changes. + * + * @param child The child node that was added or removed. + * @param removed True if the child was removed, false if added. + */ virtual void onChildCountChange( Node* child, const bool& removed ); + /** + * @brief Handles key down events. + * + * Called when a key is pressed while this widget has focus. This can be + * overridden to implement custom keyboard handling. + * + * @param event The key event. + * @return The event handling result. + */ virtual Uint32 onKeyDown( const KeyEvent& event ); + /** + * @brief Handles mouse move events. + * + * Called when the mouse moves over this widget. This can be overridden to + * implement custom mouse move handling. + * + * @param Pos The mouse position. + * @param Flags The mouse event flags. + * @return The event handling result. + */ virtual Uint32 onMouseMove( const Vector2i& Pos, const Uint32& Flags ); + /** + * @brief Handles mouse over events. + * + * Called when the mouse enters this widget. This can be overridden to + * implement custom mouse over handling. + * + * @param Pos The mouse position. + * @param Flags The mouse event flags. + * @return The event handling result. + */ virtual Uint32 onMouseOver( const Vector2i& Pos, const Uint32& Flags ); + /** + * @brief Handles mouse leave events. + * + * Called when the mouse leaves this widget. This can be overridden to + * implement custom mouse leave handling. + * + * @param Pos The mouse position. + * @param Flags The mouse event flags. + * @return The event handling result. + */ virtual Uint32 onMouseLeave( const Vector2i& Pos, const Uint32& Flags ); + /** + * @brief Handles parent size change events. + * + * Called when the parent widget's size changes. This can be overridden to + * implement custom handling of parent size changes. + * + * @param sizeChange The change in parent size. + */ virtual void onParentSizeChange( const Vector2f& sizeChange ); + /** + * @brief Handles position change events. + * + * Called when this widget's position changes. This can be overridden to + * implement custom handling of position changes. + */ virtual void onPositionChange(); + /** + * @brief Handles visibility change events. + * + * Called when this widget's visibility changes. This can be overridden to + * implement custom handling of visibility changes. + */ virtual void onVisibilityChange(); + /** + * @brief Handles size change events. + * + * Called when this widget's size changes. This can be overridden to + * implement custom handling of size changes. + */ virtual void onSizeChange(); + /** + * @brief Handles auto-size events. + * + * Called when the widget automatically resizes to fit its content. This can + * be overridden to implement custom auto-sizing behavior. + */ virtual void onAutoSize(); + /** + * @brief Handles widget creation events. + * + * Called after the widget is created and initialized. This can be overridden + * to implement custom initialization behavior. + */ virtual void onWidgetCreated(); + /** + * @brief Handles padding change events. + * + * Called when the widget's padding changes. This can be overridden to + * implement custom handling of padding changes. + */ virtual void onPaddingChange(); + /** + * @brief Handles margin change events. + * + * Called when the widget's margin changes. This can be overridden to + * implement custom handling of margin changes. + */ virtual void onMarginChange(); + /** + * @brief Handles theme load events. + * + * Called when the widget's theme is loaded. This can be overridden to + * implement custom handling of theme loading. + */ virtual void onThemeLoaded(); + /** + * @brief Handles parent change events. + * + * Called when the widget's parent changes. This can be overridden to + * implement custom handling of parent changes. + */ virtual void onParentChange(); + /** + * @brief Handles class change events. + * + * Called when the widget's CSS classes change. This can be overridden to + * implement custom handling of class changes. + */ virtual void onClassChange(); + /** + * @brief Handles tag change events. + * + * Called when the widget's CSS tag changes. This can be overridden to + * implement custom handling of tag changes. + */ virtual void onTagChange(); + /** + * @brief Handles focus previous widget events. + * + * Called when the focus moves to the previous widget. This can be overridden + * to implement custom handling of focus changes. + */ virtual void onFocusPrevWidget(); + /** + * @brief Handles focus next widget events. + * + * Called when the focus moves to the next widget. This can be overridden + * to implement custom handling of focus changes. + */ virtual void onFocusNextWidget(); + /** + * @brief Handles focus gain events. + * + * Called when this widget gains focus. This can be overridden to implement + * custom focus handling. + * + * @param reason The reason for focus gain. + * @return The event handling result. + */ virtual Uint32 onFocus( NodeFocusReason reason ); + /** + * @brief Handles focus loss events. + * + * Called when this widget loses focus. This can be overridden to implement + * custom focus handling. + * + * @return The event handling result. + */ virtual Uint32 onFocusLoss(); + /** + * @brief Updates anchors based on size change. + * + * Updates the widget's anchor distances when the parent's size changes. + * This is used for anchor-based positioning. + * + * @param sizeChange The change in parent size. + */ void updateAnchors( const Vector2f& sizeChange ); + /** + * @brief Aligns widget against layout. + * + * Aligns the widget according to the current layout settings and gravity. + * This is used for layout positioning. + */ void alignAgainstLayout(); + /** + * @brief Reports style state change. + * + * Reports a style state change to the widget and its parent, optionally + * disabling animations or forcing re-application of styles. + * + * @param disableAnimations Whether to disable CSS animations. + * @param forceReApplyStyles Whether to force re-application of all styles. + */ void reportStyleStateChange( bool disableAnimations = false, bool forceReApplyStyles = false ); + /** + * @brief Gets layout width policy as string. + * + * Returns the width size policy as a human-readable string. + * + * @return The layout width policy string. + */ std::string getLayoutWidthPolicyString() const; + /** + * @brief Gets layout height policy as string. + * + * Returns the height size policy as a human-readable string. + * + * @return The layout height policy string. + */ std::string getLayoutHeightPolicyString() const; + /** + * @brief Gets layout gravity as string. + * + * Returns the layout gravity as a human-readable string. + * + * @return The layout gravity string. + */ std::string getLayoutGravityString() const; + /** + * @brief Gets gravity as string. + * + * Returns the gravity as a human-readable string. + * + * @return The gravity string. + */ std::string getGravityString() const; + /** + * @brief Gets flags as string. + * + * Returns the widget's flags as a human-readable string. + * + * @return The flags string. + */ std::string getFlagsString() const; + /** + * @brief Checks property definition. + * + * Checks whether a CSS property definition is valid for this widget. + * + * @param property The CSS property to check. + * @return True if the property is valid, false otherwise. + */ bool checkPropertyDefinition( const StyleSheetProperty& property ); + /** + * @brief Gets tooltip position. + * + * Calculates the position where the tooltip should be displayed. + * + * @return The tooltip position as a Vector2f. + */ Vector2f getTooltipPosition(); + /** + * @brief Creates the style object. + * + * Creates and initializes the UIStyle object for this widget. + */ void createStyle(); + /** + * @brief Enables CSS animations. + * + * Enables CSS animations for this widget. + */ void enableCSSAnimations(); + /** + * @brief Disables CSS animations. + * + * Disables CSS animations for this widget. + */ void disableCSSAnimations(); + /** + * @brief Reloads font family. + * + * Reloads the font family for this widget, typically after a theme change. + */ void reloadFontFamily(); }; diff --git a/src/eepp/scene/scenenode.cpp b/src/eepp/scene/scenenode.cpp index 06080df9b..77a158e75 100644 --- a/src/eepp/scene/scenenode.cpp +++ b/src/eepp/scene/scenenode.cpp @@ -445,11 +445,11 @@ bool SceneNode::usesInvalidation() const { return mUseInvalidation; } -void SceneNode::setUseGlobalCursors( const bool& use ) { +void SceneNode::setUseGlobalCursors( bool use ) { mUseGlobalCursors = use; } -const bool& SceneNode::getUseGlobalCursors() { +bool SceneNode::getUseGlobalCursors() { return mUseGlobalCursors; } @@ -496,7 +496,7 @@ void SceneNode::removeMouseOverNode( Node* node ) { mMouseOverNodes.erase( node ); } -const bool& SceneNode::getUpdateAllChildren() const { +bool SceneNode::getUpdateAllChildren() const { return mUpdateAllChildren; } diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index b34b303d9..085ba86bf 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -159,6 +159,10 @@ void UISceneNode::setTranslator( Translator translator ) { mTranslator = translator; } +void UISceneNode::setTranslator( Translator&& translator ) { + mTranslator = std::move( translator ); +} + const Translator& UISceneNode::getTranslator() const { return mTranslator; } @@ -367,8 +371,7 @@ void UISceneNode::setStyleSheet( const std::string& inlineStyleSheet ) { setStyleSheet( parser.getStyleSheet() ); } -void UISceneNode::combineStyleSheet( const CSS::StyleSheet& styleSheet, - const bool& forceReloadStyle ) { +void UISceneNode::combineStyleSheet( const CSS::StyleSheet& styleSheet, bool forceReloadStyle ) { mStyleSheet.combineStyleSheet( styleSheet ); processStyleSheetAtRules( styleSheet ); onMediaChanged(); @@ -376,8 +379,8 @@ void UISceneNode::combineStyleSheet( const CSS::StyleSheet& styleSheet, reloadStyle(); } -void UISceneNode::combineStyleSheet( const std::string& inlineStyleSheet, - const bool& forceReloadStyle, const Uint32& marker ) { +void UISceneNode::combineStyleSheet( const std::string& inlineStyleSheet, bool forceReloadStyle, + const Uint32& marker ) { CSS::StyleSheetParser parser; if ( parser.loadFromString( inlineStyleSheet ) ) { @@ -639,7 +642,7 @@ void UISceneNode::onWidgetDelete( Node* node ) { } } -const bool& UISceneNode::isLoading() const { +bool UISceneNode::isLoading() const { return mIsLoading; } @@ -814,7 +817,7 @@ void UISceneNode::updateDirtyStyleStates() { } } -const bool& UISceneNode::isUpdatingLayouts() const { +bool UISceneNode::isUpdatingLayouts() const { return mUpdatingLayouts; }