2 #include "sdl_selectlist.hpp"
4 static const Uint32 vpadding = 5;
6 SdlSelectList::SdlSelectList(
const std::string& title,
const std::vector<std::string>& labels)
7 : _window(nullptr), _renderer(nullptr)
9 const size_t widget_height = 50;
10 const size_t widget_width = 600;
12 const size_t total_height = labels.size() * (widget_height + vpadding) + vpadding;
13 const size_t height = total_height + widget_height;
14 assert(widget_width <= INT32_MAX);
15 assert(height <= INT32_MAX);
16 auto rc = SDL_CreateWindowAndRenderer(
17 title.c_str(),
static_cast<int>(widget_width),
static_cast<int>(height),
18 SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS, &_window,
21 widget_log_error(rc,
"SDL_CreateWindowAndRenderer");
24 SDL_FRect rect = { 0, 0, widget_width, widget_height };
25 for (
auto& label : labels)
27 _list.emplace_back(_renderer, label, rect);
28 rect.y += widget_height + vpadding;
31 const std::vector<int> buttonids = { INPUT_BUTTON_ACCEPT, INPUT_BUTTON_CANCEL };
32 const std::vector<std::string> buttonlabels = {
"accept",
"cancel" };
33 _buttons.populate(_renderer, buttonlabels, buttonids, widget_width,
34 static_cast<Sint32
>(total_height),
static_cast<Sint32
>(widget_width / 2),
35 static_cast<Sint32
>(widget_height));
36 _buttons.set_highlight(0);
40 SdlSelectList::~SdlSelectList()
44 SDL_DestroyRenderer(_renderer);
45 SDL_DestroyWindow(_window);
48 int SdlSelectList::run()
51 ssize_t CurrentActiveTextInput = 0;
54 if (!_window || !_renderer)
60 if (!clear_window(_renderer))
66 if (!_buttons.update(_renderer))
70 SDL_WaitEvent(&event);
73 case SDL_EVENT_KEY_DOWN:
74 switch (event.key.key)
78 if (CurrentActiveTextInput > 0)
79 CurrentActiveTextInput--;
81 CurrentActiveTextInput = _list.size() - 1;
85 if (CurrentActiveTextInput < 0)
86 CurrentActiveTextInput = 0;
88 CurrentActiveTextInput++;
89 CurrentActiveTextInput = CurrentActiveTextInput % _list.size();
95 res =
static_cast<int>(CurrentActiveTextInput);
99 res = INPUT_BUTTON_CANCEL;
105 case SDL_EVENT_MOUSE_MOTION:
107 ssize_t TextInputIndex = get_index(event.button);
109 if (TextInputIndex >= 0)
111 auto& cur = _list[TextInputIndex];
112 if (!cur.set_mouseover(_renderer,
true))
116 _buttons.set_mouseover(event.button.x, event.button.y);
119 case SDL_EVENT_MOUSE_BUTTON_DOWN:
121 auto button = _buttons.get_selected(event.button);
125 if (button->id() == INPUT_BUTTON_CANCEL)
126 res = INPUT_BUTTON_CANCEL;
128 res =
static_cast<int>(CurrentActiveTextInput);
132 CurrentActiveTextInput = get_index(event.button);
137 res = INPUT_BUTTON_CANCEL;
145 if (CurrentActiveTextInput >= 0)
147 auto& cur = _list[CurrentActiveTextInput];
148 if (!cur.set_highlight(_renderer,
true))
152 SDL_RenderPresent(_renderer);
162 ssize_t SdlSelectList::get_index(
const SDL_MouseButtonEvent& button)
164 const auto x = button.x;
165 const auto y = button.y;
166 for (
size_t i = 0; i < _list.size(); i++)
168 auto& cur = _list[i];
171 if ((x >= r.x) && (x <= r.x + r.w) && (y >= r.y) && (y <= r.y + r.h))
177 bool SdlSelectList::update_text()
179 for (
auto& cur : _list)
181 if (!cur.update_text(_renderer))
188 void SdlSelectList::reset_mouseover()
190 for (
auto& cur : _list)
192 cur.set_mouseover(_renderer,
false);
196 void SdlSelectList::reset_highlight()
198 for (
auto& cur : _list)
200 cur.set_highlight(_renderer,
false);