ml::docs | Your First App Manifests Events Plugins Scenes Graphics Resources
← All Tutorials
Beginner 4 sections ~15 min C++17/20

Buttons & Controls

Three built-in button types — rectangle, circle, and convex — each combining a shape background with a centered text label and the full trait set.

Introduction

Three Built-in Button Types

All button types are instances of ml::Button<T, S>, where T is the background shape and S is its size parameter. The label is an sf::Text that re-centers automatically on every setPosition() call.

TypeBackgroundSize paramWith manifest
ml::RectangleButtonml::Rectanglesf::Vector2f (w×h)RectangleButtonWith<M>
ml::CircleButtonml::Circlefloat (radius)CircleButtonWith<M>
ml::ConvexButtonml::Convexstd::size_t (points)ConvexButtonWith<M>

1Core Concepts

RectangleButton

RectangleButton — full example cpp
ml::RectangleButton btn;

// Shape
btn.setSize({200.f, 55.f});
btn.setRadius(8.f);                           // rounded corners
btn.setFillColor(sf::Color(83, 74, 183));
btn.setOutlineColor(sf::Color(124, 106, 247));
btn.setOutlineThickness(1.5f);
btn.setPosition({100.f, 200.f});

// Label
btn.setString("Start Game");
btn.setCharacterSize(18);
btn.setTextColor(sf::Color::White);
btn.setFont(Resources::get(Fonts::Main));

// Events
btn.onClick([this]{ startGame(); });
btn.onHover([&btn]{ btn.setFillColor(sf::Color(100, 90, 200)); });
btn.onUnhover([&btn]{ btn.setFillColor(sf::Color(83, 74, 183)); });

addComponent(btn);

2Core Concepts

CircleButton and ConvexButton

CircleButton and ConvexButton examples cpp
// CircleButton — size param is the radius
ml::CircleButton circleBtn(ml::FontManager<>::getDefault(), 40.f, "OK");
circleBtn.setFillColor(sf::Color(200, 80, 80));
circleBtn.setTextColor(sf::Color::White);
circleBtn.setPosition({300.f, 300.f});
circleBtn.onClick([]{ confirm(); });
addComponent(circleBtn);

// ConvexButton — size param is point count
ml::ConvexButton hex(ml::FontManager<>::getDefault(), 6, "HEX");
hex.setPoint(0, {60.f,   0.f});
hex.setPoint(1, {120.f, 30.f});
hex.setPoint(2, {120.f, 90.f});
hex.setPoint(3, {60.f, 120.f});
hex.setPoint(4, {0.f,   90.f});
hex.setPoint(5, {0.f,   30.f});
hex.setFillColor(sf::Color(50, 140, 80));
hex.onClick([]{ activate(); });
addComponent(hex);

3Core Concepts

Full Label API

MethodDescription
setString(sf::String)Set the label text
getString()Return the label text
setCharacterSize(unsigned)Set font size in points
setFont(sf::Font&)Set the font (lvalue only — rvalue overload is deleted)
setTextColor(sf::Color)Set label fill color
setTextOutlineColor(sf::Color)Set label outline color
setTextOutlineThickness(float)Set label outline thickness
setLetterSpacing(float)Letter spacing multiplier
setStyle(uint32_t)sf::Text::Style bitmask (Bold, Italic, etc.)
findCharacterPos(index)World-space position of a character in the label
Buttons with manifest states cpp
struct MenuManifest : public ml::Manifest {
    static constexpr const char* name = "Menu";
    static constexpr const char* version = "1.0.0";
    enum class Flag  { Locked };
    enum class State { Normal, Hovered, Disabled };
};

class MenuButton : public ml::RectangleButtonWith
{
public:
    void setup(const std::string& text) {
        setString(text);
        setSize({180.f, 48.f});
        setFillColor(sf::Color(40, 40, 60));
        setTextColor(sf::Color::White);

        onHover([this]{
            if (!checkFlag(Flag::Locked))
                setFillColor(sf::Color(60, 60, 90));
        });
        onUnhover([this]{
            if (!checkFlag(Flag::Locked))
                setFillColor(sf::Color(40, 40, 60));
        });
    }

    void lock() {
        enableFlag(Flag::Locked);
        setState(State::Disabled);
        setFillColor(sf::Color(25, 25, 35));
        setTextColor(sf::Color(80, 80, 80));
    }
};