FreeRDP
SDL3/dialogs/sdl_buttons.cpp
1 #include <cassert>
2 #include <algorithm>
3 
4 #include "sdl_buttons.hpp"
5 
6 static const Uint32 hpadding = 10;
7 
8 SdlButtonList::~SdlButtonList() = default;
9 
10 bool SdlButtonList::populate(SDL_Renderer* renderer, const std::vector<std::string>& labels,
11  const std::vector<int>& ids, Sint32 total_width, Sint32 offsetY,
12  Sint32 width, Sint32 height)
13 {
14  assert(renderer);
15  assert(width >= 0);
16  assert(height >= 0);
17  assert(labels.size() == ids.size());
18 
19  _list.clear();
20  size_t button_width = ids.size() * (width + hpadding) + hpadding;
21  size_t offsetX = total_width - std::min<size_t>(total_width, button_width);
22  for (size_t x = 0; x < ids.size(); x++)
23  {
24  const size_t curOffsetX = offsetX + x * (static_cast<size_t>(width) + hpadding);
25  const SDL_FRect rect = { static_cast<float>(curOffsetX), static_cast<float>(offsetY),
26  static_cast<float>(width), static_cast<float>(height) };
27  _list.emplace_back(renderer, labels[x], ids[x], rect);
28  }
29  return true;
30 }
31 
32 SdlButton* SdlButtonList::get_selected(const SDL_MouseButtonEvent& button)
33 {
34  const auto x = button.x;
35  const auto y = button.y;
36 
37  return get_selected(x, y);
38 }
39 
40 SdlButton* SdlButtonList::get_selected(float x, float y)
41 {
42  for (auto& btn : _list)
43  {
44  auto r = btn.rect();
45  if ((x >= r.x) && (x <= r.x + r.w) && (y >= r.y) && (y <= r.y + r.h))
46  return &btn;
47  }
48  return nullptr;
49 }
50 
51 bool SdlButtonList::set_highlight_next(bool reset)
52 {
53  if (reset)
54  _highlighted = nullptr;
55  else
56  {
57  auto next = _highlight_index++;
58  _highlight_index %= _list.size();
59  auto& element = _list[next];
60  _highlighted = &element;
61  }
62  return true;
63 }
64 
65 bool SdlButtonList::set_highlight(size_t index)
66 {
67  if (index >= _list.size())
68  {
69  _highlighted = nullptr;
70  return false;
71  }
72  auto& element = _list[index];
73  _highlighted = &element;
74  _highlight_index = ++index % _list.size();
75  return true;
76 }
77 
78 bool SdlButtonList::set_mouseover(float x, float y)
79 {
80  _mouseover = get_selected(x, y);
81  return _mouseover != nullptr;
82 }
83 
84 void SdlButtonList::clear()
85 {
86  _list.clear();
87  _mouseover = nullptr;
88  _highlighted = nullptr;
89  _highlight_index = 0;
90 }
91 
92 bool SdlButtonList::update(SDL_Renderer* renderer)
93 {
94  assert(renderer);
95 
96  for (auto& btn : _list)
97  {
98  if (!btn.update(renderer))
99  return false;
100  }
101 
102  if (_highlighted)
103  _highlighted->highlight(renderer);
104 
105  if (_mouseover)
106  _mouseover->mouseover(renderer);
107  return true;
108 }