Mario Kart 64
Loading...
Searching...
No Matches
UIWidgets.h
Go to the documentation of this file.
1#ifndef UIWidgets_hpp
2#define UIWidgets_hpp
3
4#include <string>
5#include <vector>
6#include <span>
7#include <stdint.h>
8#define IMGUI_DEFINE_MATH_OPERATORS
9#include <imgui.h>
10#include <libultraship/libultraship.h>
11#include <unordered_map>
12#include "port/ShipUtils.h"
13
14namespace UIWidgets {
15
16 using SectionFunc = void(*)();
17
18 struct TextFilters {
19 static int FilterNumbers(ImGuiInputTextCallbackData* data) {
20 if (data->EventChar < 256 && strchr("1234567890", (char)data->EventChar)) {
21 return 0;
22 }
23 return 1;
24 }
25
26 static int FilterAlphaNum(ImGuiInputTextCallbackData* data) {
27 const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789";
28 if (data->EventChar < 256 && strchr(alphanum, (char)data->EventChar)) {
29 return 0;
30 }
31 return 1;
32 }
33 };
34
35 std::string WrappedText(const char* text, unsigned int charactersPerLine = 60);
36 std::string WrappedText(const std::string& text, unsigned int charactersPerLine = 60);
37 void Tooltip(const char* text);
38
39 // mostly in order for colors usable by the menu without custom text color
64
65 const std::unordered_map<Colors, ImVec4> ColorValues = {
66 { Colors::Pink, ImVec4(0.87f, 0.3f, 0.87f, 1.0f) },
67 { Colors::Red, ImVec4(0.55f, 0.0f, 0.0f, 1.0f) },
68 { Colors::DarkRed, ImVec4(0.3f, 0.0f, 0.0f, 1.0f) },
69 { Colors::Orange, ImVec4(0.85f, 0.55f, 0.0f, 1.0f) },
70 { Colors::Yellow, ImVec4(0.95f, 0.95f, 0.0f, 1.0f) },
71 { Colors::Green, ImVec4(0.0f, 0.55f, 0.0f, 1.0f) },
72 { Colors::DarkGreen, ImVec4(0.0f, 0.3f, 0.0f, 1.0f) },
73 { Colors::Cyan, ImVec4(0.0f, 0.9f, 0.9f, 1.0f) },
74 { Colors::LightBlue, ImVec4(0.0f, 0.24f, 0.8f, 1.0f) },
75 { Colors::Blue, ImVec4(0.08f, 0.03f, 0.65f, 1.0f) },
76 { Colors::DarkBlue, ImVec4(0.03f, 0.0f, 0.5f, 1.0f) },
77 { Colors::Indigo, ImVec4(0.35f, 0.0f, 0.87f, 1.0f) },
78 { Colors::Violet, ImVec4(0.5f, 0.0f, 0.9f, 1.0f) },
79 { Colors::Purple, ImVec4(0.31f, 0.0f, 0.67f, 1.0f) },
80 { Colors::Brown, ImVec4(0.37f, 0.18f, 0.0f, 1.0f) },
81 { Colors::LightGray, ImVec4(0.75f, 0.75f, 0.75f, 1.0f) },
82 { Colors::Gray, ImVec4(0.45f, 0.45f, 0.45f, 1.0f) },
83 { Colors::DarkGray, ImVec4(0.15f, 0.15f, 0.15f, 1.0f) },
84 { Colors::Black, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)},
85 { Colors::White, ImVec4(1.0f, 1.0f, 1.0f, 1.0f) },
86 { Colors::NoColor, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)},
87 };
88
89 namespace Sizes {
90 const ImVec2 Inline = ImVec2(0.0f, 0.0f);
91 const ImVec2 Fill = ImVec2(-1.0f, 0.0f);
92 }
93
101
106
108 const char* tooltip = "";
109 bool disabled = false;
110 const char* disabledTooltip = "";
112
114 color = color = color_;
115 return *this;
116 }
117 WidgetOptions& Tooltip(const char* tooltip_) {
118 tooltip = tooltip_;
119 return *this;
120 }
121 WidgetOptions& Disabled(bool disabled_) {
122 disabled = disabled_;
123 return *this;
124 }
125 };
126
130
131 ButtonOptions& Size(ImVec2 size_) {
132 size = size_;
133 return *this;
134 }
135 ButtonOptions& Tooltip(const char* tooltip_) {
136 WidgetOptions::tooltip = tooltip_;
137 return *this;
138 }
140 WidgetOptions::color = color = color_;
141 return *this;
142 }
143 };
144
146 bool defaultValue = false; // Only applicable to CVarCheckbox
150
151 CheckboxOptions& DefaultValue(bool defaultValue_) {
152 defaultValue = defaultValue_;
153 return *this;
154 }
156 alignment = alignment_;
157 return *this;
158 }
160 labelPosition = labelPosition_;
161 return *this;
162 }
163 CheckboxOptions& Tooltip(const char* tooltip_) {
164 WidgetOptions::tooltip = tooltip_;
165 return *this;
166 }
168 WidgetOptions::color = color = color_;
169 return *this;
170 }
171 };
172
174 std::unordered_map<int32_t, const char*> comboMap = {};
175 uint32_t defaultIndex = 0; // Only applicable to CVarCombobox
178 ImGuiComboFlags flags = 0;
180
181 ComboboxOptions& ComboMap(std::unordered_map<int32_t, const char*> comboMap_) {
182 comboMap = comboMap_;
183 return *this;
184 }
185 ComboboxOptions& DefaultIndex(uint32_t defaultIndex_) {
186 defaultIndex = defaultIndex_;
187 return *this;
188 }
190 alignment = alignment_;
191 return *this;
192 }
194 labelPosition = labelPosition_;
195 return *this;
196 }
197 ComboboxOptions& Tooltip(const char* tooltip_) {
198 WidgetOptions::tooltip = tooltip_;
199 return *this;
200 }
202 WidgetOptions::color = color = color_;
203 return *this;
204 }
205 };
206
208 bool showButtons = true;
209 const char* format = "%d";
210 int32_t step = 1;
211 int32_t min = 1;
212 int32_t max = 10;
213 int32_t defaultValue = 1;
217 ImGuiSliderFlags flags = 0;
218
219 IntSliderOptions& ShowButtons(bool showButtons_) {
220 showButtons = showButtons_;
221 return *this;
222 }
223 IntSliderOptions& Format(const char* format_) {
224 format = format_;
225 return *this;
226 }
227 IntSliderOptions& Step(int32_t step_) {
228 step = step_;
229 return *this;
230 }
231 IntSliderOptions& Min(int32_t min_) {
232 min = min_;
233 return *this;
234 }
235 IntSliderOptions& Max(int32_t max_) {
236 max = max_;
237 return *this;
238 }
239 IntSliderOptions& DefaultValue(int32_t defaultValue_) {
240 defaultValue = defaultValue_;
241 return *this;
242 }
244 alignment = alignment_;
245 return *this;
246 }
248 labelPosition = labelPosition_;
249 return *this;
250 }
251 IntSliderOptions& Tooltip(const char* tooltip_) {
252 WidgetOptions::tooltip = tooltip_;
253 return *this;
254 }
256 WidgetOptions::color = color = color_;
257 return *this;
258 }
259 };
260
262 bool showButtons = true;
263 const char* format = "%f";
264 float step = 0.01f;
265 float min = 0.01f;
266 float max = 10.0f;
267 float defaultValue = 1.0f;
268 bool isPercentage = false; // Multiplies visual value by 100
272 ImGuiSliderFlags flags = 0;
273
274 FloatSliderOptions& ShowButtons(bool showButtons_) {
275 showButtons = showButtons_;
276 return *this;
277 }
278 FloatSliderOptions& Format(const char* format_) {
279 format = format_;
280 return *this;
281 }
282 FloatSliderOptions& Step(float step_) {
283 step = step_;
284 return *this;
285 }
286 FloatSliderOptions& Min(float min_) {
287 min = min_;
288 return *this;
289 }
290 FloatSliderOptions& Max(float max_) {
291 max = max_;
292 return *this;
293 }
294 FloatSliderOptions& DefaultValue(float defaultValue_) {
295 defaultValue = defaultValue_;
296 return *this;
297 }
299 alignment = alignment_;
300 return *this;
301 }
303 labelPosition = labelPosition_;
304 return *this;
305 }
306 FloatSliderOptions& IsPercentage(bool isPercentage_ = true) {
307 isPercentage = isPercentage_;
308 format = "%.0f";
309 min = 0.0f;
310 max = 1.0f;
311 return *this;
312 }
313 FloatSliderOptions& Tooltip(const char* tooltip_) {
314 WidgetOptions::tooltip = tooltip_;
315 return *this;
316 }
318 WidgetOptions::color = color = color_;
319 return *this;
320 }
321 };
322
323 void PushStyleMenu(const ImVec4& color);
324 void PushStyleMenu(Colors color = Colors::LightBlue);
325 void PopStyleMenu();
326 bool BeginMenu(const char* label, Colors color = Colors::LightBlue);
327
328 void PushStyleMenuItem(const ImVec4& color);
329 void PushStyleMenuItem(Colors color = Colors::LightBlue);
330 void PopStyleMenuItem();
331 bool MenuItem(const char* label, const char* shortcut = NULL, Colors color = Colors::LightBlue);
332
333 void PushStyleButton(const ImVec4& color);
334 void PushStyleButton(Colors color = Colors::Gray);
335 void PopStyleButton();
336 bool Button(const char* label, const ButtonOptions& options = {});
337 bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<Ship::GuiWindow> windowPtr, const ButtonOptions& options = {});
338
339 void PushStyleCheckbox(const ImVec4& color);
341 void PopStyleCheckbox();
342 void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash);
343 bool Checkbox(const char* label, bool* v, const CheckboxOptions& options = {});
344 bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options = {});
345
346 void PushStyleCombobox(const ImVec4& color);
348 void PopStyleCombobox();
349
350 /*using ComboVariant = std::variant<const std::unordered_map<int32_t, const char*>&, const std::vector<const char*>&>;
351
352 bool Combobox(const char* label, int32_t* value, ComboVariant comboSource, const ComboboxOptions& options = {}) {
353 bool dirty = false;
354 float startX = ImGui::GetCursorPosX();
355 std::string invisibleLabelStr = "##" + std::string(label);
356 const char* invisibleLabel = invisibleLabelStr.c_str();
357 ImGui::PushID(label);
358 ImGui::BeginGroup();
359 ImGui::BeginDisabled(options.disabled);
360 PushStyleCombobox(options.color);
361 if (options.alignment == ComponentAlignment::Left) {
362 if (options.labelPosition == LabelPosition::Above) {
363 ImGui::Text("%s", label);
364 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
365 } else if (options.labelPosition == LabelPosition::Near) {
366 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2);
367 } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
368 ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x);
369 }
370 } else if (options.alignment == ComponentAlignment::Right) {
371 if (options.labelPosition == LabelPosition::Above) {
372 ImGui::NewLine();
373 ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
374 ImGui::Text("%s", label);
375 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
376 } else if (options.labelPosition == LabelPosition::Near) {
377 ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2);
378 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
379 } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
380 float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4;
381 ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
382 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
383 }
384 }
385 if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) {
386 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
387 for (const auto& pair : comboMap) {
388 if (strlen(pair.second) > 1) {
389 if (ImGui::Selectable(pair.second, pair.first == *value)) {
390 *value = pair.first;
391 dirty = true;
392 }
393 }
394 }
395 ImGui::PopStyleVar();
396 ImGui::EndCombo();
397 }
398 if (options.alignment == ComponentAlignment::Left) {
399 if (options.labelPosition == LabelPosition::Near) {
400 ImGui::SameLine();
401 ImGui::Text("%s", label);
402 } else if (options.labelPosition == LabelPosition::Far) {
403 ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
404 ImGui::Text("%s", label);
405 }
406 } else if (options.alignment == ComponentAlignment::Right) {
407 if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
408 ImGui::SameLine(startX);
409 ImGui::Text("%s", label);
410 }
411 }
412 PopStyleCombobox();
413 ImGui::EndDisabled();
414 ImGui::EndGroup();
415 if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) {
416 ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
417 } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) {
418 ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
419 }
420 ImGui::PopID();
421 return dirty;
422 }
423
424 bool CVarCombobox(const char* label, const char* cvarName, ComboVariant comboSource, const ComboboxOptions& options = {}) {
425 bool dirty = false;
426 int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
427 if (Combobox(label, &value, comboSource, options)) {
428 CVarSetInteger(cvarName, value);
429 Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
430 ShipInit::Init(cvarName);
431 dirty = true;
432 }
433 return dirty;
434 }*/
435
436 template <typename T>
437 bool Combobox(const char* label, T* value, const std::unordered_map<T, const char*>& comboMap, const ComboboxOptions& options = {}) {
438 bool dirty = false;
439 float startX = ImGui::GetCursorPosX();
440 std::string invisibleLabelStr = "##" + std::string(label);
441 const char* invisibleLabel = invisibleLabelStr.c_str();
442 ImGui::PushID(label);
443 ImGui::BeginGroup();
444 ImGui::BeginDisabled(options.disabled);
445 PushStyleCombobox(options.color);
446 if (options.alignment == ComponentAlignment::Left) {
447 if (options.labelPosition == LabelPosition::Above) {
448 ImGui::Text("%s", label);
449 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
450 } else if (options.labelPosition == LabelPosition::Near) {
451 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2);
452 } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
453 ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x);
454 }
455 } else if (options.alignment == ComponentAlignment::Right) {
456 if (options.labelPosition == LabelPosition::Above) {
457 ImGui::NewLine();
458 ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
459 ImGui::Text("%s", label);
460 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
461 } else if (options.labelPosition == LabelPosition::Near) {
462 ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2);
463 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
464 } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
465 float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4;
466 ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
467 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
468 }
469 }
470 if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) {
471 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
472 for (const auto& pair : comboMap) {
473 if (strlen(pair.second) > 1) {
474 if (ImGui::Selectable(pair.second, pair.first == *value)) {
475 *value = pair.first;
476 dirty = true;
477 }
478 }
479 }
480 ImGui::PopStyleVar();
481 ImGui::EndCombo();
482 }
483 if (options.alignment == ComponentAlignment::Left) {
484 if (options.labelPosition == LabelPosition::Near) {
485 ImGui::SameLine();
486 ImGui::Text("%s", label);
487 } else if (options.labelPosition == LabelPosition::Far) {
488 ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
489 ImGui::Text("%s", label);
490 }
491 } else if (options.alignment == ComponentAlignment::Right) {
492 if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
493 ImGui::SameLine(startX);
494 ImGui::Text("%s", label);
495 }
496 }
498 ImGui::EndDisabled();
499 ImGui::EndGroup();
500 if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) {
501 ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
502 } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) {
503 ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
504 }
505 ImGui::PopID();
506 return dirty;
507 }
508
509 template <typename T = size_t>
510 bool Combobox(const char* label, T* value, const std::vector<const char*>& comboVector, const ComboboxOptions& options = {}) {
511 bool dirty = false;
512 float startX = ImGui::GetCursorPosX();
513 size_t currentValueIndex = static_cast<size_t>(*value);
514 std::string invisibleLabelStr = "##" + std::string(label);
515 const char* invisibleLabel = invisibleLabelStr.c_str();
516 ImGui::PushID(label);
517 ImGui::BeginGroup();
518 ImGui::BeginDisabled(options.disabled);
519 PushStyleCombobox(options.color);
520 if (options.alignment == ComponentAlignment::Left) {
521 if (options.labelPosition == LabelPosition::Above) {
522 ImGui::Text(label);
523 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
524 } else if (options.labelPosition == LabelPosition::Near) {
525 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2);
526 } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
527 ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboVector.at(currentValueIndex)).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x);
528 }
529 } else if (options.alignment == ComponentAlignment::Right) {
530 if (options.labelPosition == LabelPosition::Above) {
531 ImGui::NewLine();
532 ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
533 ImGui::Text(label);
534 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
535 } else if (options.labelPosition == LabelPosition::Near) {
536 ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2);
537 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
538 } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
539 float width = ImGui::CalcTextSize(comboVector.at(currentValueIndex)).x + ImGui::GetStyle().FramePadding.x * 4;
540 ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
541 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
542 }
543 }
544 if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex), options.flags)) {
545 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
546 for (size_t i = 0; i < comboVector.size(); ++i) {
547 auto newValue = static_cast<T>(i);
548 if (strlen(comboVector.at(i)) > 1) {
549 if (ImGui::Selectable(comboVector.at(i), newValue == *value)) {
550 *value = newValue;
551 dirty = true;
552 }
553 }
554 }
555 ImGui::PopStyleVar();
556 ImGui::EndCombo();
557 }
558 if (options.alignment == ComponentAlignment::Left) {
559 if (options.labelPosition == LabelPosition::Near) {
560 ImGui::SameLine();
561 ImGui::Text(label);
562 } else if (options.labelPosition == LabelPosition::Far) {
563 ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
564 ImGui::Text(label);
565 }
566 } else if (options.alignment == ComponentAlignment::Right) {
567 if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
568 ImGui::SameLine(startX);
569 ImGui::Text(label);
570 }
571 }
573 ImGui::EndDisabled();
574 ImGui::EndGroup();
575 if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) {
576 ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
577 } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) {
578 ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
579 }
580 ImGui::PopID();
581 return dirty;
582 }
583
584 template <typename T = size_t, size_t N>
585 bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const ComboboxOptions& options = {}) {
586 bool dirty = false;
587 float startX = ImGui::GetCursorPosX();
588 size_t currentValueIndex = static_cast<size_t>(*value);
589 if (currentValueIndex >= N) {
590 currentValueIndex = 0;
591 }
592 std::string invisibleLabelStr = "##" + std::string(label);
593 const char* invisibleLabel = invisibleLabelStr.c_str();
594 ImGui::PushID(label);
595 ImGui::BeginGroup();
596 ImGui::BeginDisabled(options.disabled);
597 PushStyleCombobox(options.color);
598 if (options.alignment == ComponentAlignment::Left) {
599 if (options.labelPosition == LabelPosition::Above) {
600 ImGui::Text("%s", label);
601 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
602 } else if (options.labelPosition == LabelPosition::Near) {
603 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2);
604 } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
605 ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboArray[currentValueIndex]).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x);
606 }
607 } else if (options.alignment == ComponentAlignment::Right) {
608 if (options.labelPosition == LabelPosition::Above) {
609 ImGui::NewLine();
610 ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
611 ImGui::Text("%s", label);
612 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
613 } else if (options.labelPosition == LabelPosition::Near) {
614 ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2);
615 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
616 } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
617 float width = ImGui::CalcTextSize(comboArray[currentValueIndex]).x + ImGui::GetStyle().FramePadding.x * 4;
618 ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
619 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
620 }
621 }
622 if (ImGui::BeginCombo(invisibleLabel, comboArray[currentValueIndex], options.flags)) {
623 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
624 for (size_t i = 0; i < N; ++i) {
625 auto newValue = static_cast<T>(i);
626 if (strlen(comboArray[i]) > 1) {
627 if (ImGui::Selectable(comboArray[i], newValue == *value)) {
628 *value = newValue;
629 dirty = true;
630 }
631 }
632 }
633 ImGui::PopStyleVar();
634 ImGui::EndCombo();
635 }
636 if (options.alignment == ComponentAlignment::Left) {
637 if (options.labelPosition == LabelPosition::Near) {
638 ImGui::SameLine();
639 ImGui::Text("%s", label);
640 } else if (options.labelPosition == LabelPosition::Far) {
641 ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
642 ImGui::Text("%s", label);
643 }
644 } else if (options.alignment == ComponentAlignment::Right) {
645 if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
646 ImGui::SameLine(startX);
647 ImGui::Text("%s", label);
648 }
649 }
651 ImGui::EndDisabled();
652 ImGui::EndGroup();
653 if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) {
654 ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
655 } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) {
656 ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
657 }
658 ImGui::PopID();
659 return dirty;
660 }
661
662 template <typename T = int32_t>
663 bool CVarCombobox(const char* label, const char* cvarName, const std::unordered_map<T, const char*>& comboMap, const ComboboxOptions& options = {}) {
664 bool dirty = false;
665 int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
666 if (Combobox<T>(label, &value, comboMap, options)) {
667 CVarSetInteger(cvarName, value);
668 Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
669 dirty = true;
670 }
671 return dirty;
672 }
673
674 template <typename T = int32_t>
675 bool CVarCombobox(const char* label, const char* cvarName, const std::vector<const char*>& comboVector, const ComboboxOptions& options = {}) {
676 bool dirty = false;
677 int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
678 if (Combobox<T>(label, &value, comboVector, options)) {
679 CVarSetInteger(cvarName, value);
680 Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
681 dirty = true;
682 }
683 return dirty;
684 }
685
686 template <typename T = int32_t, size_t N>
687 bool CVarCombobox(const char* label, const char* cvarName, const char* (&comboArray)[N], const ComboboxOptions& options = {}) {
688 bool dirty = false;
689 int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
690 if (Combobox<T>(label, &value, comboArray, options)) {
691 CVarSetInteger(cvarName, value);
692 Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
693 dirty = true;
694 }
695 return dirty;
696 }
697
699 void PopStyleSlider();
700 bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& options = {});
701 bool CVarSliderInt(const char* label, const char* cvarName, const IntSliderOptions& options = {});
702 bool SliderFloat(const char* label, float* value, const FloatSliderOptions& options = {});
703 bool CVarSliderFloat(const char* label, const char* cvarName, const FloatSliderOptions& options = {});
704 bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaultColor);
705 void DrawFlagArray32(const std::string& name, uint32_t& flags);
706 void DrawFlagArray16(const std::string& name, uint16_t& flags);
707 void DrawFlagArray8(const std::string& name, uint8_t& flags);
708 void DrawFlagArray8Mask(const std::string& name, uint8_t& flags);
709}
710
711#endif /* UIWidgets_hpp */
bool Ship_IsCStringEmpty(const char *str)
Definition ShipUtils.cpp:10
#define NULL
Definition miniaudio.h:3851
Definition UIWidgets.h:89
const ImVec2 Inline
Definition UIWidgets.h:90
const ImVec2 Fill
Definition UIWidgets.h:91
Definition UIWidgets.cpp:11
bool CVarCheckbox(const char *label, const char *cvarName, const CheckboxOptions &options)
Definition UIWidgets.cpp:289
std::string WrappedText(const char *text, unsigned int charactersPerLine)
Definition UIWidgets.cpp:16
bool MenuItem(const char *label, const char *shortcut, Colors color)
Definition UIWidgets.cpp:94
LabelPosition
Definition UIWidgets.h:94
@ Above
Definition UIWidgets.h:97
@ Far
Definition UIWidgets.h:96
@ Near
Definition UIWidgets.h:95
@ Within
Definition UIWidgets.h:99
@ None
Definition UIWidgets.h:98
ComponentAlignment
Definition UIWidgets.h:102
@ Left
Definition UIWidgets.h:103
@ Right
Definition UIWidgets.h:104
void DrawFlagArray16(const std::string &name, uint16_t &flags)
Definition UIWidgets.cpp:564
bool Checkbox(const char *_label, bool *value, const CheckboxOptions &options)
Definition UIWidgets.cpp:197
void DrawFlagArray8Mask(const std::string &name, uint8_t &flags)
Definition UIWidgets.cpp:610
void PopStyleButton()
Definition UIWidgets.cpp:118
bool WindowButton(const char *label, const char *cvarName, std::shared_ptr< Ship::GuiWindow > windowPtr, const ButtonOptions &options)
Definition UIWidgets.cpp:138
bool SliderInt(const char *label, int32_t *value, const IntSliderOptions &options)
Definition UIWidgets.cpp:344
void PushStyleCheckbox(const ImVec4 &color)
Definition UIWidgets.cpp:156
void PopStyleCheckbox()
Definition UIWidgets.cpp:171
void Tooltip(const char *text)
Definition UIWidgets.cpp:45
void PushStyleSlider(Colors color_)
Definition UIWidgets.cpp:325
bool CVarSliderFloat(const char *label, const char *cvarName, const FloatSliderOptions &options)
Definition UIWidgets.cpp:512
void PushStyleMenuItem(const ImVec4 &color)
Definition UIWidgets.cpp:80
void PushStyleButton(const ImVec4 &color)
Definition UIWidgets.cpp:104
void PushStyleMenu(const ImVec4 &color)
Definition UIWidgets.cpp:51
void DrawFlagArray8(const std::string &name, uint8_t &flags)
Definition UIWidgets.cpp:587
void PopStyleMenu()
Definition UIWidgets.cpp:64
void PopStyleMenuItem()
Definition UIWidgets.cpp:89
bool CVarSliderInt(const char *label, const char *cvarName, const IntSliderOptions &options)
Definition UIWidgets.cpp:402
void PushStyleCombobox(const ImVec4 &color)
Definition UIWidgets.cpp:300
bool SliderFloat(const char *label, float *value, const FloatSliderOptions &options)
Definition UIWidgets.cpp:451
void PopStyleSlider()
Definition UIWidgets.cpp:339
Colors
Definition UIWidgets.h:40
@ Blue
Definition UIWidgets.h:47
@ Red
Definition UIWidgets.h:41
@ DarkRed
Definition UIWidgets.h:42
@ Purple
Definition UIWidgets.h:51
@ DarkGray
Definition UIWidgets.h:54
@ Violet
Definition UIWidgets.h:50
@ LightGray
Definition UIWidgets.h:60
@ Brown
Definition UIWidgets.h:52
@ Green
Definition UIWidgets.h:44
@ Gray
Definition UIWidgets.h:53
@ DarkBlue
Definition UIWidgets.h:48
@ White
Definition UIWidgets.h:61
@ Indigo
Definition UIWidgets.h:49
@ NoColor
Definition UIWidgets.h:62
@ Pink
Definition UIWidgets.h:56
@ Cyan
Definition UIWidgets.h:58
@ Orange
Definition UIWidgets.h:43
@ Yellow
Definition UIWidgets.h:57
@ DarkGreen
Definition UIWidgets.h:45
@ Black
Definition UIWidgets.h:59
@ LightBlue
Definition UIWidgets.h:46
bool Combobox(const char *label, T *value, const std::unordered_map< T, const char * > &comboMap, const ComboboxOptions &options={})
Definition UIWidgets.h:437
const std::unordered_map< Colors, ImVec4 > ColorValues
Definition UIWidgets.h:65
void PopStyleCombobox()
Definition UIWidgets.cpp:320
void RenderText(ImVec2 pos, const char *text, const char *text_end, bool hide_text_after_hash)
Definition UIWidgets.cpp:176
bool CVarColorPicker(const char *label, const char *cvarName, Color_RGBA8 defaultColor)
Definition UIWidgets.cpp:523
void(*)() SectionFunc
Definition UIWidgets.h:16
bool BeginMenu(const char *label, Colors color)
Definition UIWidgets.cpp:69
bool CVarCombobox(const char *label, const char *cvarName, const std::unordered_map< T, const char * > &comboMap, const ComboboxOptions &options={})
Definition UIWidgets.h:663
void DrawFlagArray32(const std::string &name, uint32_t &flags)
Definition UIWidgets.cpp:541
bool Button(const char *label, const ButtonOptions &options)
Definition UIWidgets.cpp:123
size_t strlen(const char *str)
Definition string.c:14
char * strchr(const char *str, s32 ch)
Definition string.c:22
Definition UIWidgets.h:127
ButtonOptions & Size(ImVec2 size_)
Definition UIWidgets.h:131
ButtonOptions & Tooltip(const char *tooltip_)
Definition UIWidgets.h:135
ImVec2 size
Definition UIWidgets.h:128
Colors color
Definition UIWidgets.h:129
ButtonOptions & Color(Colors color_)
Definition UIWidgets.h:139
Definition UIWidgets.h:145
CheckboxOptions & LabelPosition(LabelPosition labelPosition_)
Definition UIWidgets.h:159
LabelPosition labelPosition
Definition UIWidgets.h:148
CheckboxOptions & Color(Colors color_)
Definition UIWidgets.h:167
CheckboxOptions & ComponentAlignment(ComponentAlignment alignment_)
Definition UIWidgets.h:155
Colors color
Definition UIWidgets.h:149
CheckboxOptions & DefaultValue(bool defaultValue_)
Definition UIWidgets.h:151
CheckboxOptions & Tooltip(const char *tooltip_)
Definition UIWidgets.h:163
bool defaultValue
Definition UIWidgets.h:146
ComponentAlignment alignment
Definition UIWidgets.h:147
Definition UIWidgets.h:173
std::unordered_map< int32_t, const char * > comboMap
Definition UIWidgets.h:174
ImGuiComboFlags flags
Definition UIWidgets.h:178
ComboboxOptions & Tooltip(const char *tooltip_)
Definition UIWidgets.h:197
ComboboxOptions & Color(Colors color_)
Definition UIWidgets.h:201
ComponentAlignment alignment
Definition UIWidgets.h:176
Colors color
Definition UIWidgets.h:179
uint32_t defaultIndex
Definition UIWidgets.h:175
ComboboxOptions & ComboMap(std::unordered_map< int32_t, const char * > comboMap_)
Definition UIWidgets.h:181
ComboboxOptions & ComponentAlignment(ComponentAlignment alignment_)
Definition UIWidgets.h:189
ComboboxOptions & LabelPosition(LabelPosition labelPosition_)
Definition UIWidgets.h:193
LabelPosition labelPosition
Definition UIWidgets.h:177
ComboboxOptions & DefaultIndex(uint32_t defaultIndex_)
Definition UIWidgets.h:185
Definition UIWidgets.h:261
const char * format
Definition UIWidgets.h:263
FloatSliderOptions & DefaultValue(float defaultValue_)
Definition UIWidgets.h:294
FloatSliderOptions & Tooltip(const char *tooltip_)
Definition UIWidgets.h:313
FloatSliderOptions & ComponentAlignment(ComponentAlignment alignment_)
Definition UIWidgets.h:298
float min
Definition UIWidgets.h:265
FloatSliderOptions & Format(const char *format_)
Definition UIWidgets.h:278
ComponentAlignment alignment
Definition UIWidgets.h:269
FloatSliderOptions & IsPercentage(bool isPercentage_=true)
Definition UIWidgets.h:306
FloatSliderOptions & Step(float step_)
Definition UIWidgets.h:282
FloatSliderOptions & ShowButtons(bool showButtons_)
Definition UIWidgets.h:274
Colors color
Definition UIWidgets.h:271
FloatSliderOptions & Color(Colors color_)
Definition UIWidgets.h:317
float defaultValue
Definition UIWidgets.h:267
LabelPosition labelPosition
Definition UIWidgets.h:270
bool showButtons
Definition UIWidgets.h:262
ImGuiSliderFlags flags
Definition UIWidgets.h:272
FloatSliderOptions & LabelPosition(LabelPosition labelPosition_)
Definition UIWidgets.h:302
bool isPercentage
Definition UIWidgets.h:268
float step
Definition UIWidgets.h:264
FloatSliderOptions & Min(float min_)
Definition UIWidgets.h:286
float max
Definition UIWidgets.h:266
FloatSliderOptions & Max(float max_)
Definition UIWidgets.h:290
Definition UIWidgets.h:207
Colors color
Definition UIWidgets.h:216
IntSliderOptions & LabelPosition(LabelPosition labelPosition_)
Definition UIWidgets.h:247
IntSliderOptions & ComponentAlignment(ComponentAlignment alignment_)
Definition UIWidgets.h:243
const char * format
Definition UIWidgets.h:209
IntSliderOptions & DefaultValue(int32_t defaultValue_)
Definition UIWidgets.h:239
ImGuiSliderFlags flags
Definition UIWidgets.h:217
IntSliderOptions & Min(int32_t min_)
Definition UIWidgets.h:231
LabelPosition labelPosition
Definition UIWidgets.h:215
IntSliderOptions & Tooltip(const char *tooltip_)
Definition UIWidgets.h:251
int32_t step
Definition UIWidgets.h:210
IntSliderOptions & Color(Colors color_)
Definition UIWidgets.h:255
int32_t max
Definition UIWidgets.h:212
int32_t min
Definition UIWidgets.h:211
IntSliderOptions & ShowButtons(bool showButtons_)
Definition UIWidgets.h:219
IntSliderOptions & Step(int32_t step_)
Definition UIWidgets.h:227
int32_t defaultValue
Definition UIWidgets.h:213
bool showButtons
Definition UIWidgets.h:208
ComponentAlignment alignment
Definition UIWidgets.h:214
IntSliderOptions & Format(const char *format_)
Definition UIWidgets.h:223
IntSliderOptions & Max(int32_t max_)
Definition UIWidgets.h:235
Definition UIWidgets.h:18
static int FilterAlphaNum(ImGuiInputTextCallbackData *data)
Definition UIWidgets.h:26
static int FilterNumbers(ImGuiInputTextCallbackData *data)
Definition UIWidgets.h:19
Definition UIWidgets.h:107
WidgetOptions & Tooltip(const char *tooltip_)
Definition UIWidgets.h:117
const char * disabledTooltip
Definition UIWidgets.h:110
const char * tooltip
Definition UIWidgets.h:108
WidgetOptions & Disabled(bool disabled_)
Definition UIWidgets.h:121
Colors color
Definition UIWidgets.h:111
WidgetOptions & Color(Colors color_)
Definition UIWidgets.h:113
bool disabled
Definition UIWidgets.h:109