diff --git a/src/port/ui/ImguiUI.cpp b/src/port/ui/ImguiUI.cpp index b06d14a5..62a5a871 100644 --- a/src/port/ui/ImguiUI.cpp +++ b/src/port/ui/ImguiUI.cpp @@ -80,14 +80,26 @@ static const char* filters[3] = { void DrawSettingsMenu(){ if(UIWidgets::BeginMenu("Settings")){ if (UIWidgets::BeginMenu("Audio")) { - UIWidgets::PaddedEnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true); - if (UIWidgets::PaddedEnhancementSliderFloat("Main Music Volume: %d %%", "##Main_Music_Vol", "gMainMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { + UIWidgets::CVarSliderFloat("Master Volume", "gGameMasterVolume", 0.0f, 1.0f, 1.0f, { + .isPercentage = true, + .format = "%.0f%%", + }); + if (UIWidgets::CVarSliderFloat("Main Music Volume", "gMainMusicVolume", 0.0f, 1.0f, 1.0f, { + .isPercentage = true, + .format = "%.0f%%", + })) { audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f)); } - if (UIWidgets::PaddedEnhancementSliderFloat("Sound Effects Volume: %d %%", "##Sound_Effect_Vol", "gSFXMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { + if (UIWidgets::CVarSliderFloat("Sound Effects Volume", "gSFXMusicVolume", 0.0f, 1.0f, 1.0f, { + .isPercentage = true, + .format = "%.0f%%", + })) { audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f)); } - if (UIWidgets::PaddedEnhancementSliderFloat("Environment Volume: %d %%", "##Environment_Vol", "gEnvironmentVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { + if (UIWidgets::CVarSliderFloat("Environment Volume", "gEnvironmentVolume", 0.0f, 1.0f, 1.0f, { + .isPercentage = true, + .format = "%.0f%%", + })) { audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f)); } @@ -134,8 +146,12 @@ void DrawSettingsMenu(){ UIWidgets::CVarCheckbox("Show Inputs", "gInputEnabled", { .tooltip = "Shows currently pressed inputs on the bottom right of the screen" }); - UIWidgets::PaddedEnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false, true, true, false); - UIWidgets::Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting"); + if (CVarGetInteger("gInputEnabled", 0)) { + UIWidgets::CVarSliderFloat("Input Scale", "gInputScale", 1.0f, 3.0f, 1.0f, { + .format = "%.1fx", + .tooltip = "Sets the on screen size of the displayed inputs from the Show Inputs setting" + }); + } ImGui::EndMenu(); } diff --git a/src/port/ui/UIWidgets.cpp b/src/port/ui/UIWidgets.cpp index dea9ffc5..7ddc6dad 100644 --- a/src/port/ui/UIWidgets.cpp +++ b/src/port/ui/UIWidgets.cpp @@ -889,30 +889,29 @@ namespace UIWidgets { ImGui::PopStyleColor(6); } - bool CVarSliderInt(const char* label, const char* cvarName, int32_t min, int32_t max, const int32_t defaultValue, const SliderOptions& options){ + 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(); - int32_t value = CVarGetInteger(cvarName, defaultValue); 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); + 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); + ImGui::Text(label, *value); } } if (options.showButtons) { - if (Button("-", { .size = Sizes::Inline, .color = options.color }) && value > min) { - value--; - CVarSetInteger(cvarName, value); + if (Button("-", { .size = Sizes::Inline, .color = options.color }) && *value > min) { + *value -= options.step; + if (*value < min) *value = min; LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); dirty = true; } @@ -921,17 +920,16 @@ namespace UIWidgets { } else { ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); } - if (ImGui::SliderScalar(invisibleLabel, ImGuiDataType_S32, &value, &min, &max, options.format, options.flags)) { - CVarSetInteger(cvarName, value); + if (ImGui::SliderScalar(invisibleLabel, ImGuiDataType_S32, value, &min, &max, options.format, options.flags)) { LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); dirty = true; } if (options.showButtons) { ImGui::SameLine(0, 3.0f); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (Button("+", { .size = Sizes::Inline, .color = options.color }) && value < max) { - value++; - CVarSetInteger(cvarName, value); + if (Button("+", { .size = Sizes::Inline, .color = options.color }) && *value < max) { + *value += options.step; + if (*value > max) *value = max; LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); dirty = true; } @@ -947,4 +945,87 @@ namespace UIWidgets { 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); + LUS::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("-", { .size = Sizes::Inline, .color = options.color }) && *value > min) { + *value -= options.step; + if (*value < min) *value = min; + LUS::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; + LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + dirty = true; + } + if (options.showButtons) { + ImGui::SameLine(0, 3.0f); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (Button("+", { .size = Sizes::Inline, .color = options.color }) && *value < max) { + *value += options.step; + if (*value > max) *value = max; + LUS::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)); + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) { + ImGui::SetTooltip("%s", WrappedText(options.tooltip)); + } + 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); + LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + dirty = true; + } + return dirty; + } } diff --git a/src/port/ui/UIWidgets.h b/src/port/ui/UIWidgets.h index 58b8f2dd..2d398f61 100644 --- a/src/port/ui/UIWidgets.h +++ b/src/port/ui/UIWidgets.h @@ -170,23 +170,40 @@ namespace UIWidgets { void PushStyleCombobox(const ImVec4& color = Colors::Indigo); void PopStyleCombobox(); - bool Combobox(const char* label, std::span comboArray, const ComboboxOptions& options = {}); + bool Combobox(const char* label, uint8_t* value, std::span comboArray, const ComboboxOptions& options = {}); bool CVarCombobox(const char* label, const char* cvarName, std::span comboArray, const ComboboxOptions& options = {}); - struct SliderOptions { - const ImVec4 color = Colors::Green; + struct IntSliderOptions { + const ImVec4 color = Colors::Gray; const char* tooltip = ""; bool disabled = false; const char* disabledTooltip = ""; bool showButtons = true; ImGuiSliderFlags flags = 0; const char* format = "%d"; + const uint32_t step = 1; + ComponentAlignment alignment = ComponentAlignment::Left; + LabelPosition labelPosition = LabelPosition::Above; + }; + + struct FloatSliderOptions { + const ImVec4 color = Colors::Gray; + const char* tooltip = ""; + bool disabled = false; + const char* disabledTooltip = ""; + bool showButtons = true; + ImGuiSliderFlags flags = 0; + const char* format = "%f"; + const float step = 0.01f; + bool isPercentage = false; // Multiplies visual value by 100 ComponentAlignment alignment = ComponentAlignment::Left; LabelPosition labelPosition = LabelPosition::Above; }; void PushStyleSlider(const ImVec4& color = Colors::Indigo); void PopStyleSlider(); - bool CVarSliderInt(const char* label, const char* cvarName, int32_t min, int32_t max, const int32_t defaultValue, const SliderOptions& options = {}); - bool CVarSliderFloat(const char* label, const char* cvarName, float min, float max, const float defaultValue, const SliderOptions& options = {}); + bool SliderInt(const char* label, int32_t* value, int32_t min, int32_t max, const IntSliderOptions& options = {}); + bool CVarSliderInt(const char* label, const char* cvarName, int32_t min, int32_t max, const int32_t defaultValue, const IntSliderOptions& options = {}); + bool SliderFloat(const char* label, float* value, float min, float max, const FloatSliderOptions& options = {}); + bool CVarSliderFloat(const char* label, const char* cvarName, float min, float max, const float defaultValue, const FloatSliderOptions& options = {}); } \ No newline at end of file