FreeRDP
SDL2/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_Rect rect = { static_cast<int>(curOffsetX), offsetY, width, height };
26  _list.emplace_back(renderer, labels[x], ids[x], rect);
27  }
28  return true;
29 }
30 
31 SdlButton* SdlButtonList::get_selected(const SDL_MouseButtonEvent& button)
32 {
33  const Sint32 x = button.x;
34  const Sint32 y = button.y;
35 
36  return get_selected(x, y);
37 }
38 
39 SdlButton* SdlButtonList::get_selected(Sint32 x, Sint32 y)
40 {
41  for (auto& btn : _list)
42  {
43  auto r = btn.rect();
44  if ((x >= r.x) && (x <= r.x + r.w) && (y >= r.y) && (y <= r.y + r.h))
45  return &btn;
46  }
47  return nullptr;
48 }
49 
50 bool SdlButtonList::set_highlight_next(bool reset)
51 {
52  if (reset)
53  _highlighted = nullptr;
54  else
55  {
56  auto next = _highlight_index++;
57  _highlight_index %= _list.size();
58  auto& element = _list[next];
59  _highlighted = &element;
60  }
61  return true;
62 }
63 
64 bool SdlButtonList::set_highlight(size_t index)
65 {
66  if (index >= _list.size())
67  {
68  _highlighted = nullptr;
69  return false;
70  }
71  auto& element = _list[index];
72  _highlighted = &element;
73  _highlight_index = ++index % _list.size();
74  return true;
75 }
76 
77 bool SdlButtonList::set_mouseover(Sint32 x, Sint32 y)
78 {
79  _mouseover = get_selected(x, y);
80  return _mouseover != nullptr;
81 }
82 
83 void SdlButtonList::clear()
84 {
85  _list.clear();
86  _mouseover = nullptr;
87  _highlighted = nullptr;
88  _highlight_index = 0;
89 }
90 
91 bool SdlButtonList::update(SDL_Renderer* renderer)
92 {
93  assert(renderer);
94 
95  for (auto& btn : _list)
96  {
97  if (!btn.update(renderer))
98  return false;
99  }
100 
101  if (_highlighted)
102  _highlighted->highlight(renderer);
103 
104  if (_mouseover)
105  _mouseover->mouseover(renderer);
106  return true;
107 }