Files
2ship2harkinian-Android/mm/2s2h/BenGui/UIWidgets.cpp
T
MalkierianandGitHub acc2fcb2e8 Custom Checkbox Tweaks (#454)
* Create custom checkbox to encompass custom label positioning while maintaining label click and hover actions (re: tooltips).

* Reimplemented Far and None for LabelPosition.

* clang
2024-05-23 09:42:39 -05:00

558 lines
23 KiB
C++

#include "UIWidgets.hpp"
#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui_internal.h>
#include <libultraship/libultraship.h>
#include <string>
#include <unordered_map>
#include <libultraship/libultra/types.h>
namespace UIWidgets {
// Automatically adds newlines to break up text longer than a specified number of characters
// Manually included newlines will still be respected and reset the line length
// If line is midword when it hits the limit, text should break at the last encountered space
std::string WrappedText(const char* text, unsigned int charactersPerLine) {
std::string newText(text);
const size_t tipLength = newText.length();
int lastSpace = -1;
int currentLineLength = 0;
for (unsigned int currentCharacter = 0; currentCharacter < tipLength; currentCharacter++) {
if (newText[currentCharacter] == '\n') {
currentLineLength = 0;
lastSpace = -1;
continue;
} else if (newText[currentCharacter] == ' ') {
lastSpace = currentCharacter;
}
if ((currentLineLength >= charactersPerLine) && (lastSpace >= 0)) {
newText[lastSpace] = '\n';
currentLineLength = currentCharacter - lastSpace - 1;
lastSpace = -1;
}
currentLineLength++;
}
return newText;
}
std::string WrappedText(const std::string& text, unsigned int charactersPerLine) {
return WrappedText(text.c_str(), charactersPerLine);
}
void Tooltip(const char* text) {
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s", WrappedText(text).c_str());
}
}
void PushStyleMenu(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(color.x, color.y, color.z, 0.5f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_PopupBg, UIWidgets::Colors::DarkGray);
ImGui::PushStyleColor(ImGuiCol_Border, UIWidgets::Colors::DarkGray);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8.0f, 15.0f));
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 3.0f);
}
void PopStyleMenu() {
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(4);
}
bool BeginMenu(const char* label, const ImVec4& color) {
bool dirty = false;
PushStyleMenu(color);
ImGui::SetNextWindowSizeConstraints(ImVec2(200.0f, 0.0f), ImVec2(FLT_MAX, FLT_MAX));
if (ImGui::BeginMenu(label)) {
dirty = true;
}
PopStyleMenu();
return dirty;
}
void PushStyleMenuItem(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(20.0f, 15.0f));
}
void PopStyleMenuItem() {
ImGui::PopStyleVar(1);
ImGui::PopStyleColor(1);
}
bool MenuItem(const char* label, const char* shortcut, const ImVec4& color) {
bool dirty = false;
PushStyleMenuItem(color);
if (ImGui::MenuItem(label, shortcut)) {
dirty = true;
}
PopStyleMenuItem();
return dirty;
}
void PushStyleButton(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(color.x, color.y, color.z, 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 8.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 5.0f);
}
void PopStyleButton() {
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(4);
}
bool Button(const char* label, const ButtonOptions& options) {
ImGui::BeginDisabled(options.disabled);
PushStyleButton(options.color);
bool dirty = ImGui::Button(label, options.size);
PopStyleButton();
ImGui::EndDisabled();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
}
return dirty;
}
bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<Ship::GuiWindow> windowPtr,
const ButtonOptions& options) {
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0));
std::string buttonText = label;
bool dirty = false;
if (CVarGetInteger(cvarName, 0)) {
buttonText = ICON_FA_WINDOW_CLOSE " " + buttonText;
} else {
buttonText = ICON_FA_EXTERNAL_LINK_SQUARE " " + buttonText;
}
if (Button(buttonText.c_str(), options)) {
windowPtr->ToggleVisibility();
dirty = true;
}
ImGui::PopStyleVar();
return dirty;
}
void PushStyleCheckbox(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(color.x, color.y, color.z, 0.8f));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.0f, 1.0f, 1.0f, 0.7f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 6.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 5.0f);
}
void PopStyleCheckbox() {
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(5);
}
void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash) {
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
// Hide anything after a '##' string
const char* text_display_end;
if (hide_text_after_hash) {
text_display_end = ImGui::FindRenderedTextEnd(text, text_end);
} else {
if (!text_end)
text_end = text + strlen(text); // FIXME-OPT
text_display_end = text_end;
}
if (text != text_display_end) {
window->DrawList->AddText(g.Font, g.FontSize, pos, ImGui::GetColorU32(ImGuiCol_Text), text, text_display_end);
if (g.LogEnabled)
ImGui::LogRenderedText(&pos, text, text_display_end);
}
}
bool Checkbox(const char* _label, bool* value, const CheckboxOptions& options) {
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
bool above = options.labelPosition == LabelPosition::Above;
bool lpFar = options.labelPosition == LabelPosition::Far;
bool right = options.alignment == ComponentAlignment::Right;
bool none = options.labelPosition == LabelPosition::None;
std::string labelStr = (none ? "##" : "");
labelStr.append(_label);
const char* label = labelStr.c_str();
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
const float square_sz = ImGui::GetFrameHeight();
ImVec2 pos = window->DC.CursorPos;
if (right) {
float labelOffsetX = (above ? 0 : (style.ItemInnerSpacing.x * 2.0f) + square_sz);
if (!lpFar) {
pos.x += ImGui::GetContentRegionAvail().x - (label_size.x + labelOffsetX);
}
}
float bbAboveX = lpFar ? ImGui::GetContentRegionAvail().x
: (label_size.x + (above ? 0 : (style.ItemInnerSpacing.x * 2.0f) + square_sz));
float bbAboveY = label_size.y + (above ? square_sz : 0) + (style.FramePadding.y * 2.0f);
const ImRect total_bb(pos, pos + ImVec2(bbAboveX, bbAboveY));
ImGui::ItemSize(total_bb, style.FramePadding.y);
if (!ImGui::ItemAdd(total_bb, id)) {
IMGUI_TEST_ENGINE_ITEM_INFO(id, label,
g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable |
(*value ? ImGuiItemStatusFlags_Checked : 0));
return false;
}
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(total_bb, id, &hovered, &held);
if (pressed) {
*value = !(*value);
ImGui::MarkItemEdited(id);
}
ImGui::BeginDisabled(options.disabled);
PushStyleCheckbox(options.color);
ImVec2 checkPos = pos;
ImVec2 labelPos = pos;
if (options.labelPosition == LabelPosition::Above) {
checkPos.y += label_size.y + (style.ItemInnerSpacing.y * 2.0f);
} else {
labelPos.y += (square_sz / 2) - (label_size.y / 2);
}
if (options.alignment == ComponentAlignment::Right) {
checkPos.x = total_bb.Max.x - square_sz;
} else {
float labelFarOffset = ImGui::GetContentRegionAvail().x - label_size.x;
float labelOffsetX = above ? 0 : (lpFar ? labelFarOffset : (style.ItemInnerSpacing.x * 2.0f) + square_sz);
labelPos.x += labelOffsetX;
}
const ImRect check_bb(checkPos, checkPos + ImVec2(square_sz, square_sz));
ImGui::RenderNavHighlight(total_bb, id);
ImGui::RenderFrame(check_bb.Min, check_bb.Max,
ImGui::GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive
: hovered ? ImGuiCol_FrameBgHovered
: ImGuiCol_FrameBg),
true, style.FrameRounding);
ImU32 check_col = ImGui::GetColorU32(ImGuiCol_CheckMark);
bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0;
if (mixed_value) {
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
// This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all
// widgets (not just checkbox)
ImVec2 pad(ImMax(1.0f, IM_TRUNC(square_sz / 3.6f)), ImMax(1.0f, IM_TRUNC(square_sz / 3.6f)));
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
} else if (*value) {
const float pad = ImMax(1.0f, IM_TRUNC(square_sz / 6.0f));
ImGui::RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
}
RenderText(labelPos, label, ImGui::FindRenderedTextEnd(label), true);
PopStyleCheckbox();
ImGui::EndDisabled();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
}
return pressed;
}
bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options) {
bool dirty = false;
bool value = (bool)CVarGetInteger(cvarName, options.defaultValue);
if (Checkbox(label, &value, options)) {
CVarSetInteger(cvarName, value);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
return dirty;
}
void PushStyleCombobox(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 0.8f));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(color.x, color.y, color.z, 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(color.x, color.y, color.z, 0.5f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 6.0f));
}
void PopStyleCombobox() {
ImGui::PopStyleVar(4);
ImGui::PopStyleColor(9);
}
void PushStyleSlider(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(1.0, 1.0, 1.0, 0.4f));
ImGui::PushStyleColor(ImGuiCol_SliderGrabActive, ImVec4(1.0, 1.0, 1.0, 0.5f));
ImGui::PushStyleVar(ImGuiStyleVar_GrabRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 8.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
}
void PopStyleSlider() {
ImGui::PopStyleVar(4);
ImGui::PopStyleColor(6);
}
bool SliderInt(const char* label, int32_t* value, int32_t min, int32_t max, const IntSliderOptions& options) {
bool dirty = false;
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
ImGui::PushID(label);
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleSlider(options.color);
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text(label, *value);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label, *value);
}
}
if (options.showButtons) {
if (Button("-", { .color = options.color, .size = Sizes::Inline }) && *value > min) {
*value -= options.step;
if (*value < min)
*value = min;
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
ImGui::SameLine(0, 3.0f);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - (ImGui::CalcTextSize("+").x + 20.0f + 3.0f));
} else {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
}
if (ImGui::SliderScalar(invisibleLabel, ImGuiDataType_S32, value, &min, &max, options.format, options.flags)) {
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
if (options.showButtons) {
ImGui::SameLine(0, 3.0f);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (Button("+", { .color = options.color, .size = Sizes::Inline }) && *value < max) {
*value += options.step;
if (*value > max)
*value = max;
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
}
PopStyleSlider();
ImGui::EndDisabled();
ImGui::EndGroup();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
}
ImGui::PopID();
return dirty;
}
bool CVarSliderInt(const char* label, const char* cvarName, int32_t min, int32_t max, const int32_t defaultValue,
const IntSliderOptions& options) {
bool dirty = false;
int32_t value = CVarGetInteger(cvarName, defaultValue);
if (SliderInt(label, &value, min, max, options)) {
CVarSetInteger(cvarName, value);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
return dirty;
}
bool SliderFloat(const char* label, float* value, float min, float max, const FloatSliderOptions& options) {
bool dirty = false;
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
float valueToDisplay = options.isPercentage ? *value * 100.0f : *value;
float maxToDisplay = options.isPercentage ? max * 100.0f : max;
float minToDisplay = options.isPercentage ? min * 100.0f : min;
ImGui::PushID(label);
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleSlider(options.color);
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text(label, valueToDisplay);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label, valueToDisplay);
}
}
if (options.showButtons) {
if (Button("-", { .color = options.color, .size = Sizes::Inline }) && *value > min) {
*value -= options.step;
if (*value < min)
*value = min;
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
ImGui::SameLine(0, 3.0f);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - (ImGui::CalcTextSize("+").x + 20.0f + 3.0f));
} else {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
}
if (ImGui::SliderScalar(invisibleLabel, ImGuiDataType_Float, &valueToDisplay, &minToDisplay, &maxToDisplay,
options.format, options.flags)) {
*value = options.isPercentage ? valueToDisplay / 100.0f : valueToDisplay;
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
if (options.showButtons) {
ImGui::SameLine(0, 3.0f);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (Button("+", { .color = options.color, .size = Sizes::Inline }) && *value < max) {
*value += options.step;
if (*value > max)
*value = max;
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
}
PopStyleSlider();
ImGui::EndDisabled();
ImGui::EndGroup();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
}
ImGui::PopID();
return dirty;
}
bool CVarSliderFloat(const char* label, const char* cvarName, float min, float max, const float defaultValue,
const FloatSliderOptions& options) {
bool dirty = false;
float value = CVarGetFloat(cvarName, defaultValue);
if (SliderFloat(label, &value, min, max, options)) {
CVarSetFloat(cvarName, value);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
return dirty;
}
bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaultColor) {
Color_RGBA8 color = CVarGetColor(cvarName, defaultColor);
ImVec4 colorVec = ImVec4(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f);
bool changed = false;
PushStyleCombobox(Colors::Gray);
if (ImGui::ColorEdit3(label, (float*)&colorVec, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoBorder)) {
color.r = (uint8_t)(colorVec.x * 255.0f);
color.g = (uint8_t)(colorVec.y * 255.0f);
color.b = (uint8_t)(colorVec.z * 255.0f);
color.a = (uint8_t)(colorVec.w * 255.0f);
CVarSetColor(cvarName, color);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
changed = true;
}
PopStyleCombobox();
return changed;
}
void DrawFlagArray32(const std::string& name, uint32_t& flags) {
ImGui::PushID(name.c_str());
for (int32_t flagIndex = 0; flagIndex < 32; flagIndex++) {
if ((flagIndex % 8) != 0) {
ImGui::SameLine();
}
ImGui::PushID(flagIndex);
uint32_t bitMask = 1 << flagIndex;
bool flag = (flags & bitMask) != 0;
std::string label = std::to_string(flagIndex);
if (UIWidgets::Checkbox(label.c_str(), &flag,
{ .tooltip = label.c_str(), .labelPosition = LabelPosition::None })) {
if (flag) {
flags |= bitMask;
} else {
flags &= ~bitMask;
}
}
ImGui::PopID();
}
ImGui::PopID();
}
void DrawFlagArray16(const std::string& name, uint16_t& flags) {
ImGui::PushID(name.c_str());
for (int16_t flagIndex = 0; flagIndex < 16; flagIndex++) {
if ((flagIndex % 8) != 0) {
ImGui::SameLine();
}
ImGui::PushID(flagIndex);
uint16_t bitMask = 1 << flagIndex;
bool flag = (flags & bitMask) != 0;
std::string label = std::to_string(flagIndex);
if (UIWidgets::Checkbox(label.c_str(), &flag,
{ .tooltip = label.c_str(), .labelPosition = LabelPosition::None })) {
if (flag) {
flags |= bitMask;
} else {
flags &= ~bitMask;
}
}
ImGui::PopID();
}
ImGui::PopID();
}
void DrawFlagArray8(const std::string& name, uint8_t& flags) {
ImGui::PushID(name.c_str());
for (int8_t flagIndex = 0; flagIndex < 8; flagIndex++) {
if ((flagIndex % 8) != 0) {
ImGui::SameLine();
}
ImGui::PushID(flagIndex);
uint8_t bitMask = 1 << flagIndex;
bool flag = (flags & bitMask) != 0;
std::string label = std::to_string(flagIndex);
if (UIWidgets::Checkbox(label.c_str(), &flag,
{ .tooltip = label.c_str(), .labelPosition = LabelPosition::None })) {
if (flag) {
flags |= bitMask;
} else {
flags &= ~bitMask;
}
}
ImGui::PopID();
}
ImGui::PopID();
}
} // namespace UIWidgets