3#include "sdl_select_list.hpp"
4#include "../sdl_utils.hpp"
6static const Uint32 vpadding = 5;
8SdlSelectList::SdlSelectList(
const std::string& title,
const std::vector<std::string>& labels)
10 const size_t widget_height = 50;
11 const size_t widget_width = 600;
13 const size_t total_height = labels.size() * (widget_height + vpadding) + vpadding;
14 const size_t height = total_height + widget_height;
15 if (reset(title, widget_width, height))
17 SDL_FRect rect = { 0, 0, widget_width, widget_height };
18 for (
auto& label : labels)
20 _list.emplace_back(_renderer, label, rect);
21 rect.y += widget_height + vpadding;
24 const std::vector<int> buttonids = { INPUT_BUTTON_ACCEPT, INPUT_BUTTON_CANCEL };
25 const std::vector<std::string> buttonlabels = {
"accept",
"cancel" };
26 std::ignore = _buttons.populate(
27 _renderer, buttonlabels, buttonids, widget_width,
static_cast<Sint32
>(total_height),
28 static_cast<Sint32
>(widget_width / 2),
static_cast<Sint32
>(widget_height));
29 _buttons.set_highlight(0);
33SdlSelectList::~SdlSelectList() =
default;
35int SdlSelectList::run()
38 ssize_t CurrentActiveTextInput = 0;
41 if (!_window || !_renderer)
51 if (!SDL_WaitEventTimeout(&event, 30))
57 case SDL_EVENT_KEY_DOWN:
58 switch (event.key.key)
62 if (CurrentActiveTextInput > 0)
63 CurrentActiveTextInput--;
64 else if (_list.empty())
65 CurrentActiveTextInput = 0;
68 auto s = _list.size();
69 CurrentActiveTextInput =
70 WINPR_ASSERTING_INT_CAST(ssize_t, s) - 1;
75 if ((CurrentActiveTextInput < 0) || _list.empty())
76 CurrentActiveTextInput = 0;
79 auto s = _list.size();
80 CurrentActiveTextInput++;
83 CurrentActiveTextInput =
84 CurrentActiveTextInput %
85 WINPR_ASSERTING_INT_CAST(ssize_t, s);
93 res =
static_cast<int>(CurrentActiveTextInput);
95 case SDL_EVENT_WINDOW_OCCLUDED:
96 case SDL_EVENT_WINDOW_MINIMIZED:
97 case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
98 case SDL_EVENT_TERMINATING:
99 case SDL_EVENT_WINDOW_DESTROYED:
102 res = INPUT_BUTTON_CANCEL;
108 case SDL_EVENT_MOUSE_MOTION:
110 auto TextInputIndex = get_index(event.button);
112 if (TextInputIndex >= 0)
114 auto& cur = _list.at(WINPR_ASSERTING_INT_CAST(
size_t, TextInputIndex));
115 if (!cur.mouseover(
true))
119 _buttons.set_mouseover(event.button.x, event.button.y);
122 case SDL_EVENT_MOUSE_BUTTON_DOWN:
124 auto button = _buttons.get_selected(event.button);
128 if (button->id() == INPUT_BUTTON_CANCEL)
129 res = INPUT_BUTTON_CANCEL;
131 res =
static_cast<int>(CurrentActiveTextInput);
135 CurrentActiveTextInput = get_index(event.button);
140 res = INPUT_BUTTON_CANCEL;
146 }
while (running && SDL_PollEvent(&event));
149 if (CurrentActiveTextInput >= 0)
151 auto& cur = _list.at(WINPR_ASSERTING_INT_CAST(
size_t, CurrentActiveTextInput));
152 if (!cur.highlight(
true))
158 SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_USER);
167bool SdlSelectList::updateInternal()
169 for (
auto& cur : _list)
177ssize_t SdlSelectList::get_index(
const SDL_MouseButtonEvent& button)
179 const auto x = button.x;
180 const auto y = button.y;
181 for (
size_t i = 0; i < _list.size(); i++)
183 auto& cur = _list.at(i);
186 if ((x >= r.x) && (x <= r.x + r.w) && (y >= r.y) && (y <= r.y + r.h))
187 return WINPR_ASSERTING_INT_CAST(ssize_t, i);
192void SdlSelectList::reset_mouseover()
194 for (
auto& cur : _list)
196 cur.mouseover(
false);
200void SdlSelectList::reset_highlight()
202 for (
auto& cur : _list)
204 cur.highlight(
false);