5#include "sdl_selectlist.hpp" 
    7static const Uint32 vpadding = 5;
 
    9SdlSelectList::SdlSelectList(
const std::string& title, 
const std::vector<std::string>& labels)
 
   10    : _window(nullptr), _renderer(nullptr)
 
   12  const size_t widget_height = 50;
 
   13  const size_t widget_width = 600;
 
   15  const size_t total_height = labels.size() * (widget_height + vpadding) + vpadding;
 
   16  const size_t height = total_height + widget_height;
 
   17  assert(widget_width <= INT32_MAX);
 
   18  assert(height <= INT32_MAX);
 
   20  auto flags = WINPR_ASSERTING_INT_CAST(
 
   21      uint32_t, SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS);
 
   22  auto rc = SDL_CreateWindowAndRenderer(
static_cast<int>(widget_width), 
static_cast<int>(height),
 
   23                                        flags, &_window, &_renderer);
 
   25    widget_log_error(rc, 
"SDL_CreateWindowAndRenderer");
 
   28    SDL_SetWindowTitle(_window, title.c_str());
 
   30    SDL_Rect rect = { 0, 0, widget_width, widget_height };
 
   31    for (
auto& label : labels)
 
   33      _list.emplace_back(_renderer, label, rect);
 
   34      rect.y += widget_height + vpadding;
 
   37    const std::vector<int> buttonids = { INPUT_BUTTON_ACCEPT, INPUT_BUTTON_CANCEL };
 
   38    const std::vector<std::string> buttonlabels = { 
"accept", 
"cancel" };
 
   39    _buttons.populate(_renderer, buttonlabels, buttonids, widget_width,
 
   40                      static_cast<Sint32
>(total_height), 
static_cast<Sint32
>(widget_width / 2),
 
   41                      static_cast<Sint32
>(widget_height));
 
   42    _buttons.set_highlight(0);
 
   46SdlSelectList::~SdlSelectList()
 
   50  SDL_DestroyRenderer(_renderer);
 
   51  SDL_DestroyWindow(_window);
 
   54int SdlSelectList::run()
 
   57  ssize_t CurrentActiveTextInput = 0;
 
   60  if (!_window || !_renderer)
 
   66      if (!clear_window(_renderer))
 
   72      if (!_buttons.update(_renderer))
 
   76      SDL_WaitEvent(&event);
 
   80          switch (event.key.keysym.sym)
 
   84              if (CurrentActiveTextInput > 0)
 
   85                CurrentActiveTextInput--;
 
   87                CurrentActiveTextInput =
 
   88                    WINPR_ASSERTING_INT_CAST(ssize_t, _list.size() - 1);
 
   93              if (CurrentActiveTextInput < 0)
 
   94                CurrentActiveTextInput = 0;
 
   96                CurrentActiveTextInput++;
 
   98              const auto s = _list.size();
 
  100                CurrentActiveTextInput = 0;
 
  102                CurrentActiveTextInput =
 
  103                    CurrentActiveTextInput % WINPR_ASSERTING_INT_CAST(ssize_t, s);
 
  110              res = WINPR_ASSERTING_INT_CAST(
int, CurrentActiveTextInput);
 
  114              res = INPUT_BUTTON_CANCEL;
 
  120        case SDL_MOUSEMOTION:
 
  122          ssize_t TextInputIndex = get_index(event.button);
 
  124          if (TextInputIndex >= 0)
 
  126            auto& cur = _list[WINPR_ASSERTING_INT_CAST(
size_t, TextInputIndex)];
 
  127            if (!cur.set_mouseover(_renderer, 
true))
 
  131          _buttons.set_mouseover(event.button.x, event.button.y);
 
  134        case SDL_MOUSEBUTTONDOWN:
 
  136          auto button = _buttons.get_selected(event.button);
 
  140            if (button->id() == INPUT_BUTTON_CANCEL)
 
  141              res = INPUT_BUTTON_CANCEL;
 
  143              res = 
static_cast<int>(CurrentActiveTextInput);
 
  147            CurrentActiveTextInput = get_index(event.button);
 
  152          res = INPUT_BUTTON_CANCEL;
 
  160      if (CurrentActiveTextInput >= 0)
 
  162        auto& cur = _list[WINPR_ASSERTING_INT_CAST(
size_t, CurrentActiveTextInput)];
 
  163        if (!cur.set_highlight(_renderer, 
true))
 
  167      SDL_RenderPresent(_renderer);
 
  177ssize_t SdlSelectList::get_index(
const SDL_MouseButtonEvent& button)
 
  179  const Sint32 x = button.x;
 
  180  const Sint32 y = button.y;
 
  181  for (
size_t i = 0; i < _list.size(); i++)
 
  183    auto& cur = _list[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);
 
  192bool SdlSelectList::update_text()
 
  194  for (
auto& cur : _list)
 
  196    if (!cur.update_text(_renderer))
 
  203void SdlSelectList::reset_mouseover()
 
  205  for (
auto& cur : _list)
 
  207    cur.set_mouseover(_renderer, 
false);
 
  211void SdlSelectList::reset_highlight()
 
  213  for (
auto& cur : _list)
 
  215    cur.set_highlight(_renderer, 
false);