Plutonium framework API 0.3.0 UI framework libraries for libnx

elm_Menu.hpp
Go to the documentation of this file.
1
2/*
3
4 Plutonium library
5
6 @file Menu.hpp
7 @brief A Menu is a very useful Element for option browsing or selecting.
8 @author XorTroll
9
10 @copyright Plutonium project - an easy-to-use UI framework for Nintendo Switch homebrew
11
12*/
13
14#pragma once
15#include <pu/ui/elm/elm_Element.hpp>
16#include <chrono>
17#include <functional>
18
19 namespace pu::ui::elm {
20
21 class MenuItem {
22 public:
23 using OnKeyCallback = std::function<void()>;
24 static constexpr Color DefaultColor = { 10, 10, 10, 0xFF };
25
26 private:
27 std::string name;
28 Color items_clr;
29 std::string icon_path;
30 std::vector<OnKeyCallback> on_key_cbs;
31 std::vector<u64> on_key_cb_keys;
32
33 public:
34 MenuItem(const std::string &name) : name(name), items_clr(DefaultColor) {}
35 PU_SMART_CTOR(MenuItem)
36
37 inline std::string GetName() {
38 return this->name;
39 }
40
41 inline void SetName(const std::string &name) {
42 this->name = name;
43 }
44
45 inline Color GetColor() {
46 return this->items_clr;
47 }
48
49 inline void SetColor(const Color items_clr) {
50 this->items_clr = items_clr;
51 }
52
53 void AddOnKey(OnKeyCallback on_key_cb, const u64 key = HidNpadButton_A);
54
55 inline i32 GetOnKeyCallbackCount() {
56 return this->on_key_cbs.size();
57 }
58
59 inline OnKeyCallback GetOnKeyCallback(const i32 idx) {
60 if(idx < this->on_key_cbs.size()) {
61 return this->on_key_cbs.at(idx);
62 }
63 else {
64 return {};
65 }
66 }
67
68 inline u64 GetOnKeyCallbackKey(const i32 idx) {
69 if(idx < this->on_key_cb_keys.size()) {
70 return this->on_key_cb_keys.at(idx);
71 }
72 else {
73 return {};
74 }
75 }
76
77 inline std::string GetIconPath() {
78 return this->icon_path;
79 }
80
81 void SetIcon(const std::string &icon_path);
82
83 inline bool HasIcon() {
84 return !this->icon_path.empty();
85 }
86 };
87
88 class Menu : public Element {
89 public:
90 static constexpr Color DefaultScrollbarColor = { 110, 110, 110, 0xFF };
91
92 static constexpr u8 ItemAlphaIncrement = 48;
93
94 static constexpr float IconItemSizesFactor = 0.8f;
95
96 static constexpr u32 IconMargin = 25;
97 static constexpr u32 TextMargin = 25;
98
99 static constexpr u8 LightScrollbarColorFactor = 30;
100
101 static constexpr u32 ScrollbarWidth = 20;
102
103 static constexpr u32 ShadowHeight = 5;
104 static constexpr u8 ShadowBaseAlpha = 160;
105
106 using OnSelectionChangedCallback = std::function<void()>;
107
108 private:
109 i32 x;
110 i32 y;
111 i32 w;
112 i32 items_h;
113 i32 items_to_show;
114 i32 selected_item_idx;
115 i32 selected_item_alpha;
116 i32 prev_selected_item_idx;
117 i32 prev_selected_item_alpha;
118 i32 advanced_item_count;
119 Color scrollbar_clr;
120 Color items_clr;
121 Color items_focus_clr;
122 bool cooldown_enabled;
123 bool item_touched;
124 u8 move_mode;
125 std::chrono::time_point<std::chrono::steady_clock> move_start_time;
126 OnSelectionChangedCallback on_selection_changed_cb;
127 std::vector<MenuItem::Ref> items;
128 std::string font_name;
129 std::vector<sdl2::Texture> loaded_name_texs;
130 std::vector<sdl2::Texture> loaded_icon_texs;
131
132 void ReloadItemRenders();
133
134 inline Color MakeItemsFocusColor(const u8 alpha) {
135 return { this->items_focus_clr.r, this->items_focus_clr.g, this->items_focus_clr.b, alpha };
136 }
137
138 inline constexpr Color MakeLighterScrollbarColor() {
139 i32 base_r = this->scrollbar_clr.r - LightScrollbarColorFactor;
140 if(base_r < 0) {
141 base_r = 0;
142 }
143 i32 base_g = this->scrollbar_clr.g - LightScrollbarColorFactor;
144 if(base_g < 0) {
145 base_g = 0;
146 }
147 i32 base_b = this->scrollbar_clr.b - LightScrollbarColorFactor;
148 if(base_b < 0) {
149 base_b = 0;
150 }
151
152 return { static_cast<u8>(base_r), static_cast<u8>(base_g), static_cast<u8>(base_b), this->scrollbar_clr.a };
153 }
154
155 inline void HandleOnSelectionChanged() {
156 if(this->on_selection_changed_cb) {
157 (this->on_selection_changed_cb)();
158 }
159 }
160
161 inline void RunSelectedItemCallback(const u64 keys) {
162 auto item = this->items.at(this->selected_item_idx);
163 const auto cb_count = item->GetOnKeyCallbackCount();
164 for(i32 i = 0; i < cb_count; i++) {
165 if(keys & item->GetOnKeyCallbackKey(i)) {
166 if(!this->cooldown_enabled) {
167 auto cb = item->GetOnKeyCallback(i);
168 if(cb) {
169 cb();
170 }
171 }
172 }
173 }
174 this->cooldown_enabled = false;
175 }
176
177 public:
178 Menu(const i32 x, const i32 y, const i32 width, const Color items_clr, const Color items_focus_clr, const i32 items_height, const i32 items_to_show);
179 PU_SMART_CTOR(Menu)
180
181 inline i32 GetX() override {
182 return this->x;
183 }
184
185 inline void SetX(const i32 x) {
186 this->x = x;
187 }
188
189 inline i32 GetY() override {
190 return this->y;
191 }
192
193 inline void SetY(const i32 y) {
194 this->y = y;
195 }
196
197 inline i32 GetWidth() override {
198 return this->w;
199 }
200
201 inline void SetWidth(const i32 width) {
202 this->w = width;
203 }
204
205 inline i32 GetHeight() override {
206 return this->items_h * this->items_to_show;
207 }
208
209 inline i32 GetItemsHeight() {
210 return this->items_h;
211 }
212
213 inline void SetItemsHeight(const i32 items_height) {
214 this->items_h = items_height;
215 }
216
217 inline i32 GetNumberOfItemsToShow() {
218 return this->items_to_show;
219 }
220
221 inline void SetNumberOfItemsToShow(const i32 items_to_show) {
222 this->items_to_show = items_to_show;
223 }
224
225 inline Color GetItemsColor() {
226 return this->items_clr;
227 }
228
229 inline void SetItemsColor(const Color items_clr) {
230 this->items_clr = items_clr;
231 }
232
233 inline Color GetItemsFocusColor() {
234 return this->items_focus_clr;
235 }
236
237 inline void SetItemsFocusColor(const Color items_focus_clr) {
238 this->items_focus_clr = items_focus_clr;
239 }
240
241 inline Color GetScrollbarColor() {
242 return this->scrollbar_clr;
243 }
244
245 inline void SetScrollbarColor(const Color scrollbar_clr) {
246 this->scrollbar_clr = scrollbar_clr;
247 }
248
249 inline void SetOnSelectionChanged(OnSelectionChangedCallback on_selection_changed_cb) {
250 this->on_selection_changed_cb = on_selection_changed_cb;
251 }
252
253 inline void AddItem(MenuItem::Ref &item) {
254 this->items.push_back(item);
255 }
256
257 inline void ClearItems() {
258 this->items.clear();
259 }
260
261 inline void SetCooldownEnabled(const bool enabled) {
262 this->cooldown_enabled = enabled;
263 }
264
265 inline MenuItem::Ref &GetSelectedItem() {
266 return this->items.at(this->selected_item_idx);
267 }
268
269 inline std::vector<MenuItem::Ref> &GetItems() {
270 return this->items;
271 }
272
273 inline i32 GetSelectedIndex() {
274 return this->selected_item_idx;
275 }
276
277 void SetSelectedIndex(const i32 idx);
278
279 void OnRender(render::Renderer::Ref &drawer, const i32 x, const i32 y) override;
280 void OnInput(const u64 keys_down, const u64 keys_up, const u64 keys_held, const TouchPoint touch_pos) override;
281 };
282}
pu::ui::elm::Element
Definition: elm_Element.hpp:37
elm_Element.hpp
pu::ui::elm
Definition: elm_Button.hpp:18
pu::i32
s32 i32
Definition: pu_Include.hpp:28
PU_SMART_CTOR
#define PU_SMART_CTOR(type)
Definition: pu_Include.hpp:19
pu::ui::Color
Definition: ui_Types.hpp:44
pu::ui::Color::g
u8 g
Definition: ui_Types.hpp:46
pu::ui::Color::a
u8 a
Definition: ui_Types.hpp:48
pu::ui::Color::r
u8 r
Definition: ui_Types.hpp:45
pu::ui::Color::b
u8 b
Definition: ui_Types.hpp:47
pu::ui::TouchPoint
Definition: ui_Types.hpp:62