Files
FreeRDP/client/SDL/SDL3/dialogs/sdl_buttons.cpp
2026-02-10 19:27:48 +01:00

109 lines
2.5 KiB
C++

#include <cassert>
#include <algorithm>
#include "sdl_buttons.hpp"
static const Uint32 hpadding = 10;
SdlButtonList::~SdlButtonList() = default;
bool SdlButtonList::populate(std::shared_ptr<SDL_Renderer>& renderer,
const std::vector<std::string>& labels, const std::vector<int>& ids,
Sint32 total_width, Sint32 offsetY, Sint32 width, Sint32 height)
{
assert(renderer);
assert(width >= 0);
assert(height >= 0);
assert(labels.size() == ids.size());
_list.clear();
size_t button_width = ids.size() * (static_cast<size_t>(width) + hpadding) + hpadding;
size_t offsetX = static_cast<size_t>(total_width) -
std::min<size_t>(static_cast<size_t>(total_width), button_width);
for (size_t x = 0; x < ids.size(); x++)
{
const size_t curOffsetX = offsetX + x * (static_cast<size_t>(width) + hpadding);
const SDL_FRect rect = { static_cast<float>(curOffsetX), static_cast<float>(offsetY),
static_cast<float>(width), static_cast<float>(height) };
auto button = std::make_shared<SdlButton>(renderer, labels.at(x), ids.at(x), rect);
_list.emplace_back(button);
}
return true;
}
std::shared_ptr<SdlButton> SdlButtonList::get_selected(const SDL_MouseButtonEvent& button)
{
const auto x = button.x;
const auto y = button.y;
return get_selected(x, y);
}
std::shared_ptr<SdlButton> SdlButtonList::get_selected(float x, float y)
{
for (auto& btn : _list)
{
auto r = btn->rect();
if ((x >= r.x) && (x <= r.x + r.w) && (y >= r.y) && (y <= r.y + r.h))
return btn;
}
return nullptr;
}
bool SdlButtonList::set_highlight_next(bool reset)
{
if (reset)
_highlighted = nullptr;
else
{
auto next = _highlight_index++;
_highlight_index %= _list.size();
auto& element = _list.at(next);
_highlighted = element;
}
return true;
}
bool SdlButtonList::set_highlight(size_t index)
{
if (index >= _list.size())
{
_highlighted = nullptr;
return false;
}
auto& element = _list.at(index);
_highlighted = element;
_highlight_index = ++index % _list.size();
return true;
}
bool SdlButtonList::set_mouseover(float x, float y)
{
_mouseover = get_selected(x, y);
return _mouseover != nullptr;
}
void SdlButtonList::clear()
{
_list.clear();
_mouseover = nullptr;
_highlighted = nullptr;
_highlight_index = 0;
}
bool SdlButtonList::update()
{
for (auto& btn : _list)
{
if (!btn->highlight(btn == _highlighted))
return false;
if (!btn->mouseover(btn == _mouseover))
return false;
if (!btn->update())
return false;
}
return true;
}