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);
17 auto flags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS;
18 auto rc = SDL_CreateWindowAndRenderer(
static_cast<int>(widget_width),
static_cast<int>(height),
19 flags, &_window, &_renderer);
21 widget_log_error(rc,
"SDL_CreateWindowAndRenderer");
24 SDL_SetWindowTitle(_window, title.c_str());
26 SDL_Rect rect = { 0, 0, widget_width, widget_height };
27 for (
auto& label : labels)
29 _list.emplace_back(_renderer, label, rect);
30 rect.y += widget_height + vpadding;
33 const std::vector<int> buttonids = { INPUT_BUTTON_ACCEPT, INPUT_BUTTON_CANCEL };
34 const std::vector<std::string> buttonlabels = {
"accept",
"cancel" };
35 _buttons.populate(_renderer, buttonlabels, buttonids, widget_width,
36 static_cast<Sint32
>(total_height),
static_cast<Sint32
>(widget_width / 2),
37 static_cast<Sint32
>(widget_height));
38 _buttons.set_highlight(0);
42 SdlSelectList::~SdlSelectList()
46 SDL_DestroyRenderer(_renderer);
47 SDL_DestroyWindow(_window);
50 int SdlSelectList::run()
53 ssize_t CurrentActiveTextInput = 0;
56 if (!_window || !_renderer)
62 if (!clear_window(_renderer))
68 if (!_buttons.update(_renderer))
72 SDL_WaitEvent(&event);
76 switch (event.key.keysym.sym)
80 if (CurrentActiveTextInput > 0)
81 CurrentActiveTextInput--;
83 CurrentActiveTextInput = _list.size() - 1;
87 if (CurrentActiveTextInput < 0)
88 CurrentActiveTextInput = 0;
90 CurrentActiveTextInput++;
91 CurrentActiveTextInput = CurrentActiveTextInput % _list.size();
97 res =
static_cast<int>(CurrentActiveTextInput);
101 res = INPUT_BUTTON_CANCEL;
107 case SDL_MOUSEMOTION:
109 ssize_t TextInputIndex = get_index(event.button);
111 if (TextInputIndex >= 0)
113 auto& cur = _list[TextInputIndex];
114 if (!cur.set_mouseover(_renderer,
true))
118 _buttons.set_mouseover(event.button.x, event.button.y);
121 case SDL_MOUSEBUTTONDOWN:
123 auto button = _buttons.get_selected(event.button);
127 if (button->id() == INPUT_BUTTON_CANCEL)
128 res = INPUT_BUTTON_CANCEL;
130 res =
static_cast<int>(CurrentActiveTextInput);
134 CurrentActiveTextInput = get_index(event.button);
139 res = INPUT_BUTTON_CANCEL;
147 if (CurrentActiveTextInput >= 0)
149 auto& cur = _list[CurrentActiveTextInput];
150 if (!cur.set_highlight(_renderer,
true))
154 SDL_RenderPresent(_renderer);
164 ssize_t SdlSelectList::get_index(
const SDL_MouseButtonEvent& button)
166 const Sint32 x = button.x;
167 const Sint32 y = button.y;
168 for (
size_t i = 0; i < _list.size(); i++)
170 auto& cur = _list[i];
173 if ((x >= r.x) && (x <= r.x + r.w) && (y >= r.y) && (y <= r.y + r.h))
179 bool SdlSelectList::update_text()
181 for (
auto& cur : _list)
183 if (!cur.update_text(_renderer))
190 void SdlSelectList::reset_mouseover()
192 for (
auto& cur : _list)
194 cur.set_mouseover(_renderer,
false);
198 void SdlSelectList::reset_highlight()
200 for (
auto& cur : _list)
202 cur.set_highlight(_renderer,
false);