Skip to content

UIButton

A clickable button UI element.

Description

UIButton is a clickable button that supports both physical (keyboard/gamepad) and touch input. It can trigger a callback function when pressed and integrates with UI layouts for automatic navigation.

Buttons support selection state (for D-pad navigation), custom styling, and text alignment.

Namespace

namespace pixelroot32::graphics::ui {
    class UIButton : public UIElement {
        // ...
    };
}

Inheritance

  • Inherits from: UIElement
  • Inherited by: Your custom button classes (if needed)

Constructors

UIButton(string t, uint8_t index, float x, float y, float w, float h, function callback, TextAlignment textAlign = CENTER, int fontSize = 2)

Constructs a new UIButton.

Parameters: - t (std::string): Button label text - index (uint8_t): Navigation index (for D-pad navigation in layouts) - x (float): X position - y (float): Y position - w (float): Width - h (float): Height - callback (std::function): Function to call when clicked/pressed - textAlign (TextAlignment, optional): Text alignment. Default: CENTER - fontSize (int, optional): Text size multiplier. Default: 2

Example:

#include "graphics/ui/UIButton.h"

void onStartButtonClicked() {
    // Start game
    engine.setScene(&gameScene);
}

void onQuitButtonClicked() {
    // Quit game
    engine.stop();
}

// Create buttons
pixelroot32::graphics::ui::UIButton* startButton = new pixelroot32::graphics::ui::UIButton(
    "Start",
    0,  // index
    64.0f, 64.0f,  // position
    100.0f, 30.0f, // size
    onStartButtonClicked,
    pixelroot32::graphics::ui::TextAlignment::CENTER,
    2
);

pixelroot32::graphics::ui::UIButton* quitButton = new pixelroot32::graphics::ui::UIButton(
    "Quit",
    1,  // index
    64.0f, 100.0f,
    100.0f, 30.0f,
    onQuitButtonClicked
);

Public Methods

void setStyle(Color textCol, Color bgCol, bool drawBg)

Configures the button's visual style.

Parameters: - textCol (Color): Color of the text - bgCol (Color): Color of the background - drawBg (bool): Whether to draw the background rectangle

Returns: - void

Example:

button->setStyle(
    pixelroot32::graphics::Color::White,  // Text color
    pixelroot32::graphics::Color::Blue,   // Background color
    true                                   // Draw background
);

void setSelected(bool selected)

Sets the selection state (e.g., focused via D-pad).

Parameters: - selected (bool): true if selected

Returns: - void

Notes: - Used by layouts for D-pad navigation - Selected buttons typically have different visual style - Can be set manually or automatically by layouts

Example:

button->setSelected(true);  // Highlight button

bool getSelected() const

Checks if the button is currently selected.

Returns: - bool: true if selected

Example:

if (button->getSelected()) {
    // Button is focused
}

bool isFocusable() const override

Returns true (Buttons are always focusable).

Returns: - bool: Always true

void handleInput(const InputManager& input)

Handles input events. Checks for touch events within bounds or confirmation buttons if selected.

Parameters: - input (const pixelroot32::input::InputManager&): The input manager instance

Returns: - void

Notes: - Should be called every frame in update() - Checks if button is selected and action button is pressed - Triggers callback if conditions are met

Example:

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

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

void press()

Manually triggers the button's action.

Returns: - void

Notes: - Calls the button's callback function - Useful for programmatic button presses

Example:

button->press();  // Trigger button action

void update(unsigned long deltaTime) override

Updates the button state.

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

Returns: - void

Notes: - Called automatically by Scene if isEnabled is true - Handles input and updates button state - Override to add custom update logic

Example:

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

    // Custom update logic
    if (shouldPulse) {
        // Animate button
    }
}

void draw(Renderer& renderer) override

Renders the button.

Parameters: - renderer (pixelroot32::graphics::Renderer&): The renderer to use

Returns: - void

Notes: - Called automatically by Scene if isVisible is true - Draws background (if enabled) and text - Selected state may change appearance

Example:

// Drawing is handled automatically
// Override only for custom rendering

Usage Example

#include "graphics/ui/UIButton.h"
#include "core/Scene.h"

class MainMenuScene : public pixelroot32::core::Scene {
private:
    pixelroot32::graphics::ui::UIButton* startButton;
    pixelroot32::graphics::ui::UIButton* quitButton;

public:
    void init() override {
        // Start button
        startButton = new pixelroot32::graphics::ui::UIButton(
            "Start Game",
            0,  // index
            64.0f, 50.0f,  // position (centered)
            120.0f, 30.0f, // size
            [this]() {
                // Lambda callback
                engine.setScene(&gameScene);
            },
            pixelroot32::graphics::ui::TextAlignment::CENTER,
            2
        );
        startButton->setStyle(
            pixelroot32::graphics::Color::White,
            pixelroot32::graphics::Color::Blue,
            true
        );
        addEntity(startButton);

        // Quit button
        quitButton = new pixelroot32::graphics::ui::UIButton(
            "Quit",
            1,  // index
            64.0f, 90.0f,
            120.0f, 30.0f,
            [this]() {
                // Quit game
                engine.stop();
            }
        );
        quitButton->setStyle(
            pixelroot32::graphics::Color::White,
            pixelroot32::graphics::Color::Red,
            true
        );
        addEntity(quitButton);
    }

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

        // Buttons handle input automatically
        // Layouts handle navigation automatically
    }

    void draw(pixelroot32::graphics::Renderer& renderer) override {
        // Draw background
        renderer.drawFilledRectangle(0, 0, 128, 128, Color::Black);

        // Draw UI elements (buttons)
        Scene::draw(renderer);
    }
};

Button Navigation

Buttons can be navigated with D-pad when in layouts:

// Buttons in a vertical layout
pixelroot32::graphics::ui::UIVerticalLayout* layout = new UIVerticalLayout(64.0f, 50.0f);
layout->addChild(startButton);  // Index 0
layout->addChild(quitButton);   // Index 1

// D-pad navigation is automatic
// UP/DOWN moves selection
// Action button (A) triggers selected button

Performance Considerations

  • Input handling: handleInput() is fast; safe to call every frame
  • Rendering: Simple rectangle and text; very efficient
  • Memory: Each button consumes memory (stay within MAX_ENTITIES)

ESP32 Considerations

  • String storage: Button labels use std::string; consider memory usage
  • Callback functions: Use function pointers or lambdas (both efficient)

See Also