Skip to content

UIVerticalLayout

Vertical layout container with scroll support.

Description

UIVerticalLayout organizes UI elements vertically, one below another. It supports scrolling when content exceeds the visible viewport and handles keyboard/D-pad navigation automatically.

This layout is ideal for menus, lists, and any vertical arrangement of UI elements.

Namespace

namespace pixelroot32::graphics::ui {
    class UIVerticalLayout : public UILayout {
        // ...
    };
}

Inheritance

  • Inherits from: UILayout
  • Inherited by: Your custom vertical layouts (if needed)

Constructors

UIVerticalLayout(float x, float y, float w, float h)

Constructs a new UIVerticalLayout.

Parameters: - x (float): X position of the layout container - y (float): Y position of the layout container - w (float): Width of the layout container - h (float): Height of the layout container (viewport height)

Example:

#include "graphics/ui/UIVerticalLayout.h"

// Create vertical layout for menu
pixelroot32::graphics::ui::UIVerticalLayout* menuLayout = 
    new pixelroot32::graphics::ui::UIVerticalLayout(
        20.0f, 20.0f,  // position
        88.0f, 88.0f   // size (viewport)
    );

Public Methods

void addElement(UIElement* element)

Adds a UI element to the layout.

Parameters: - element (UIElement*): Pointer to the element to add

Returns: - void

Notes: - Elements are arranged vertically, one below another - Layout is automatically recalculated - Elements are positioned based on spacing and padding

Example:

menuLayout->addElement(startButton);
menuLayout->addElement(quitButton);

void removeElement(UIElement* element)

Removes a UI element from the layout.

Parameters: - element (UIElement*): Pointer to the element to remove

Returns: - void

Notes: - Layout is automatically recalculated - Element is not deleted (you must manage its lifetime)

void updateLayout()

Recalculates positions of all elements.

Returns: - void

Notes: - Called automatically when elements are added/removed - Can be called manually if needed - Recalculates all element positions and content height

void handleInput(const InputManager& input)

Handles input for navigation and scrolling.

Parameters: - input (const pixelroot32::input::InputManager&): Reference to the InputManager

Returns: - void

Notes: - Handles UP/DOWN navigation - Manages selection state - Handles scrolling if enabled - Should be called every frame in update()

Example:

void update(unsigned long deltaTime) override {
    UIVerticalLayout::update(deltaTime);

    auto& input = engine.getInputManager();
    menuLayout->handleInput(input);
}

void update(unsigned long deltaTime) override

Updates the layout (handles smooth scrolling).

Parameters: - deltaTime (unsigned long): Time elapsed since last frame in milliseconds

Returns: - void

Notes: - Called automatically by Scene if isEnabled is true - Updates smooth scrolling animation - Updates child elements

void draw(Renderer& renderer) override

Draws the layout and its visible elements.

Parameters: - renderer (pixelroot32::graphics::Renderer&): Reference to the renderer

Returns: - void

Notes: - Called automatically by Scene if isVisible is true - Only draws visible elements (viewport culling) - Draws elements in order

void setScrollEnabled(bool enable)

Enables or disables scrolling.

Parameters: - enable (bool): true to enable scrolling

Returns: - void

Notes: - When disabled, scroll offset is reset to 0 - Scrolling is useful when content exceeds viewport height

Example:

menuLayout->setScrollEnabled(true);  // Enable scrolling

void enableScroll(bool enable)

Alias for setScrollEnabled().

Parameters: - enable (bool): true to enable scrolling

void setViewportHeight(float h)

Sets the viewport height (visible area).

Parameters: - h (float): Viewport height in pixels

Returns: - void

Notes: - Layout is automatically recalculated - Use to adjust visible area

float getScrollOffset() const

Gets the current scroll offset.

Returns: - float: Scroll offset in pixels

void setScrollOffset(float offset)

Sets the scroll offset directly.

Parameters: - offset (float): Scroll offset in pixels

Returns: - void

Notes: - Offset is clamped to valid range automatically - Use for programmatic scrolling

float getContentHeight() const

Gets the total content height.

Returns: - float: Content height in pixels

Notes: - Includes all elements plus spacing and padding - Useful for scroll calculations

int getSelectedIndex() const

Gets the currently selected element index.

Returns: - int: Selected index, or -1 if none selected

void setSelectedIndex(int index)

Sets the selected element index.

Parameters: - index (int): Index to select (-1 to deselect)

Returns: - void

Notes: - Selected element is highlighted - Selection is scrolled into view if needed

UIElement* getSelectedElement() const

Gets the selected element.

Returns: - UIElement*: Pointer to selected element, or nullptr if none selected

void setScrollSpeed(float speed)

Sets the scroll speed for smooth scrolling.

Parameters: - speed (float): Pixels per millisecond

Returns: - void

Notes: - Default: 0.5 pixels per millisecond - Higher values = faster scrolling

Example:

menuLayout->setScrollSpeed(1.0f);  // Faster scrolling

void setNavigationButtons(uint8_t upButton, uint8_t downButton)

Sets the navigation button indices.

Parameters: - upButton (uint8_t): Button index for UP navigation - downButton (uint8_t): Button index for DOWN navigation

Returns: - void

Notes: - Default: UP = 0, DOWN = 1 - Change if your input mapping differs

Example:

menuLayout->setNavigationButtons(0, 1);  // UP=0, DOWN=1

void setButtonStyle(Color selectedTextCol, Color selectedBgCol, Color unselectedTextCol, Color unselectedBgCol)

Sets the style colors for selected and unselected buttons.

Parameters: - selectedTextCol (Color): Text color when selected - selectedBgCol (Color): Background color when selected - unselectedTextCol (Color): Text color when not selected - unselectedBgCol (Color): Background color when not selected

Returns: - void

Example:

menuLayout->setButtonStyle(
    Color::Yellow,  // Selected text
    Color::Blue,    // Selected background
    Color::White,   // Unselected text
    Color::Black    // Unselected background
);

Usage Example

#include "graphics/ui/UIVerticalLayout.h"
#include "graphics/ui/UIButton.h"

class MainMenuScene : public pixelroot32::core::Scene {
private:
    pixelroot32::graphics::ui::UIVerticalLayout* menuLayout;

public:
    void init() override {
        // Create menu layout
        menuLayout = new pixelroot32::graphics::ui::UIVerticalLayout(
            20.0f, 20.0f,  // position
            88.0f, 88.0f   // size
        );
        menuLayout->setScrollEnabled(true);
        menuLayout->setSpacing(8.0f);
        menuLayout->setPadding(4.0f);

        // Create buttons
        auto* startButton = new pixelroot32::graphics::ui::UIButton(
            "Start",
            0, 64.0f, 50.0f, 100.0f, 30.0f,
            [this]() { engine.setScene(&gameScene); }
        );

        auto* quitButton = new pixelroot32::graphics::ui::UIButton(
            "Quit",
            1, 64.0f, 50.0f, 100.0f, 30.0f,
            [this]() { engine.stop(); }
        );

        // Add buttons to layout
        menuLayout->addElement(startButton);
        menuLayout->addElement(quitButton);

        // Add layout to scene
        addEntity(menuLayout);
    }

    void update(unsigned long deltaTime) override {
        Scene::update(deltaTime);

        // Layout handles input automatically
        auto& input = engine.getInputManager();
        menuLayout->handleInput(input);
    }

    void draw(pixelroot32::graphics::Renderer& renderer) override {
        renderer.drawFilledRectangle(0, 0, 128, 128, Color::Black);
        Scene::draw(renderer);  // Draws layout and buttons
    }
};

The layout handles D-pad navigation automatically:

  • UP button: Moves selection up
  • DOWN button: Moves selection down
  • Action button: Triggers selected button's callback
  • Scrolling: Automatically scrolls to keep selected element visible

Performance Considerations

  • Viewport culling: Only visible elements are drawn
  • Layout recalculation: Fast (simple positioning)
  • Scrolling: Smooth scrolling is efficient

ESP32 Considerations

  • Element count: Stay within MAX_ENTITIES limit
  • Scrolling: Smooth scrolling uses minimal CPU

See Also