From 11cb2217e0791cfc8a70869bc9f5363e80b554e4 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 21 Jun 2025 21:53:51 +1000 Subject: [PATCH] FullscreenUI: Polish range dialogs --- src/core/fullscreen_ui.cpp | 173 ++++++++++++++++++++++------------ src/util/imgui_fullscreen.cpp | 17 +++- src/util/imgui_fullscreen.h | 6 +- 3 files changed, 130 insertions(+), 66 deletions(-) diff --git a/src/core/fullscreen_ui.cpp b/src/core/fullscreen_ui.cpp index 36bddbfce..8b303b1dc 100644 --- a/src/core/fullscreen_ui.cpp +++ b/src/core/fullscreen_ui.cpp @@ -2904,11 +2904,30 @@ void FullscreenUI::DrawIntRangeSetting(SettingsInterface* bsi, std::string_view if (!IsFixedPopupDialogOpen(title) || !BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING), - LayoutScale(500.0f, 200.0f))) + LayoutScale(600.0f, 0.0f))) { return; } + ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight); + ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary)); + ImGui::PushFontWeight(UIStyle.BoldFontWeight); + ImGui::Text("%s: ", FSUI_CSTR("Value Range")); + ImGui::PopFontWeight(); + ImGui::SameLine(); + ImGui::Text(format, min_value); + ImGui::SameLine(); + ImGui::TextUnformatted(" - "); + ImGui::SameLine(); + ImGui::Text(format, max_value); + ImGui::PushFontWeight(UIStyle.BoldFontWeight); + ImGui::Text("%s: ", FSUI_CSTR("Default Value")); + ImGui::PopFontWeight(); + ImGui::SameLine(); + ImGui::Text(format, default_value); + ImGui::PopFont(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f)); + BeginMenuButtons(); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, LayoutScale(LAYOUT_WIDGET_FRAME_ROUNDING)); @@ -2952,11 +2971,30 @@ void FullscreenUI::DrawFloatRangeSetting(SettingsInterface* bsi, std::string_vie if (!IsFixedPopupDialogOpen(title) || !BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING), - LayoutScale(500.0f, 200.0f))) + LayoutScale(600.0f, 0.0f))) { return; } + ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight); + ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary)); + ImGui::PushFontWeight(UIStyle.BoldFontWeight); + ImGui::Text("%s: ", FSUI_CSTR("Value Range")); + ImGui::PopFontWeight(); + ImGui::SameLine(); + ImGui::Text(format, min_value * multiplier); + ImGui::SameLine(); + ImGui::TextUnformatted(" - "); + ImGui::SameLine(); + ImGui::Text(format, max_value * multiplier); + ImGui::PushFontWeight(UIStyle.BoldFontWeight); + ImGui::Text("%s: ", FSUI_CSTR("Default Value")); + ImGui::PopFontWeight(); + ImGui::SameLine(); + ImGui::Text(format, default_value * multiplier); + ImGui::PopFont(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f)); + BeginMenuButtons(); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, LayoutScale(LAYOUT_WIDGET_FRAME_ROUNDING)); @@ -3009,11 +3047,30 @@ void FullscreenUI::DrawFloatSpinBoxSetting(SettingsInterface* bsi, std::string_v if (!IsFixedPopupDialogOpen(title) || !BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING), - LayoutScale(500.0f, 200.0f))) + LayoutScale(650.0f, 0.0f))) { return; } + ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight); + ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary)); + ImGui::PushFontWeight(UIStyle.BoldFontWeight); + ImGui::Text("%s: ", FSUI_CSTR("Value Range")); + ImGui::PopFontWeight(); + ImGui::SameLine(); + ImGui::Text(format, min_value * multiplier); + ImGui::SameLine(); + ImGui::TextUnformatted(" - "); + ImGui::SameLine(); + ImGui::Text(format, max_value * multiplier); + ImGui::PushFontWeight(UIStyle.BoldFontWeight); + ImGui::Text("%s: ", FSUI_CSTR("Default Value")); + ImGui::PopFontWeight(); + ImGui::SameLine(); + ImGui::Text(format, default_value * multiplier); + ImGui::PopFont(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f)); + BeginMenuButtons(); float dlg_value = value.value_or(default_value) * multiplier; @@ -3049,40 +3106,31 @@ void FullscreenUI::DrawFloatSpinBoxSetting(SettingsInterface* bsi, std::string_v } else { - const ImVec2& padding(ImGui::GetStyle().FramePadding); - ImVec2 button_pos(ImGui::GetCursorPos()); - - // Align value text in middle. - ImGui::SetCursorPosY(button_pos.y + padding.y); - ImGui::TextUnformatted(str_value); + BeginHorizontalMenuButtons(5); + HorizontalMenuButton(str_value, false); float step = 0; - if (FloatingButton(ICON_FA_CHEVRON_UP, padding.x, button_pos.y, 1.0f, 0.0f, true, &button_pos, true)) - { + ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); + if (HorizontalMenuButton(ICON_FA_CHEVRON_UP)) step = step_value; - } - if (FloatingButton(ICON_FA_CHEVRON_DOWN, button_pos.x - padding.x, button_pos.y, -1.0f, 0.0f, true, &button_pos, - true)) - { + if (HorizontalMenuButton(ICON_FA_CHEVRON_DOWN)) step = -step_value; - } - if (FloatingButton(ICON_FA_KEYBOARD, button_pos.x - padding.x, button_pos.y, -1.0f, 0.0f, true, &button_pos)) - { + ImGui::PopItemFlag(); + if (HorizontalMenuButton(ICON_FA_KEYBOARD)) manual_input = true; - } - if (FloatingButton(ICON_FA_TRASH, button_pos.x - padding.x, button_pos.y, -1.0f, 0.0f, true, &button_pos)) + if (HorizontalMenuButton(ICON_FA_ARROW_ROTATE_LEFT)) { dlg_value = default_value * multiplier; dlg_value_changed = true; } + EndHorizontalMenuButtons(10.0f); + if (step != 0) { dlg_value += step * multiplier; dlg_value_changed = true; } - - ImGui::SetCursorPosY(button_pos.y + (padding.y * 2.0f) + UIStyle.LargeFontSize + LayoutScale(10.0f)); } if (dlg_value_changed) @@ -3241,11 +3289,30 @@ void FullscreenUI::DrawIntSpinBoxSetting(SettingsInterface* bsi, std::string_vie if (!IsFixedPopupDialogOpen(title) || !BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING), - LayoutScale(500.0f, 200.0f))) + LayoutScale(650.0f, 0.0f))) { return; } + ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight); + ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary)); + ImGui::PushFontWeight(UIStyle.BoldFontWeight); + ImGui::Text("%s: ", FSUI_CSTR("Value Range")); + ImGui::PopFontWeight(); + ImGui::SameLine(); + ImGui::Text(format, min_value); + ImGui::SameLine(); + ImGui::TextUnformatted(" - "); + ImGui::SameLine(); + ImGui::Text(format, max_value); + ImGui::PushFontWeight(UIStyle.BoldFontWeight); + ImGui::Text("%s: ", FSUI_CSTR("Default Value")); + ImGui::PopFontWeight(); + ImGui::SameLine(); + ImGui::Text(format, default_value); + ImGui::PopFont(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f)); + BeginMenuButtons(); s32 dlg_value = static_cast(value.value_or(default_value)); @@ -3275,40 +3342,31 @@ void FullscreenUI::DrawIntSpinBoxSetting(SettingsInterface* bsi, std::string_vie } else { - const ImVec2& padding(ImGui::GetStyle().FramePadding); - ImVec2 button_pos(ImGui::GetCursorPos()); - - // Align value text in middle. - ImGui::SetCursorPosY(button_pos.y + ((UIStyle.LargeFontSize + padding.y * 2.0f) - UIStyle.LargeFontSize) * 0.5f); - ImGui::TextUnformatted(str_value); + BeginHorizontalMenuButtons(5); + HorizontalMenuButton(str_value, false); s32 step = 0; - if (FloatingButton(ICON_FA_CHEVRON_UP, padding.x, button_pos.y, 1.0f, 0.0f, true, &button_pos, true)) - { + ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); + if (HorizontalMenuButton(ICON_FA_CHEVRON_UP)) step = step_value; - } - if (FloatingButton(ICON_FA_CHEVRON_DOWN, button_pos.x - padding.x, button_pos.y, -1.0f, 0.0f, true, &button_pos, - true)) - { + if (HorizontalMenuButton(ICON_FA_CHEVRON_DOWN)) step = -step_value; - } - if (FloatingButton(ICON_FA_KEYBOARD, button_pos.x - padding.x, button_pos.y, -1.0f, 0.0f, true, &button_pos)) - { + ImGui::PopItemFlag(); + if (HorizontalMenuButton(ICON_FA_KEYBOARD)) manual_input = true; - } - if (FloatingButton(ICON_FA_TRASH, button_pos.x - padding.x, button_pos.y, -1.0f, 0.0f, true, &button_pos)) + if (HorizontalMenuButton(ICON_FA_ARROW_ROTATE_LEFT)) { dlg_value = default_value; dlg_value_changed = true; } + EndHorizontalMenuButtons(10.0f); + if (step != 0) { dlg_value += step; dlg_value_changed = true; } - - ImGui::SetCursorPosY(button_pos.y + (padding.y * 2.0f) + UIStyle.LargeFontSize + LayoutScale(10.0f)); } if (dlg_value_changed) @@ -6612,44 +6670,36 @@ void FullscreenUI::DrawPatchesOrCheatsSettingsPage(bool cheats) if (IsFixedPopupDialogOpen(title) && BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING), - LayoutScale(500.0f, 200.0f))) + LayoutScale(600.0f, 0.0f))) { BeginMenuButtons(); bool range_value_changed = false; - const ImVec2& padding(ImGui::GetStyle().FramePadding); - ImVec2 button_pos(ImGui::GetCursorPos()); - - // Align value text in middle. - ImGui::SetCursorPosY(button_pos.y + - ((UIStyle.LargeFontSize + padding.y * 2.0f) - UIStyle.LargeFontSize) * 0.5f); - ImGui::TextUnformatted(visible_value.c_str(), visible_value.end_ptr()); + BeginHorizontalMenuButtons(4); + HorizontalMenuButton(visible_value, false); s32 step = 0; - if (FloatingButton(ICON_FA_CHEVRON_UP, padding.x, button_pos.y, 1.0f, 0.0f, true, &button_pos, true)) - { + ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); + if (HorizontalMenuButton(ICON_FA_CHEVRON_UP)) step = step_value; - } - if (FloatingButton(ICON_FA_CHEVRON_DOWN, button_pos.x - padding.x, button_pos.y, -1.0f, 0.0f, true, &button_pos, - true)) - { + if (HorizontalMenuButton(ICON_FA_CHEVRON_DOWN)) step = -step_value; - } - if (FloatingButton(ICON_FA_TRASH, button_pos.x - padding.x, button_pos.y, -1.0f, 0.0f, true, &button_pos)) + ImGui::PopItemFlag(); + if (HorizontalMenuButton(ICON_FA_ARROW_ROTATE_LEFT)) { range_value = ci.option_range_start - 1; range_value_changed = true; } + EndHorizontalMenuButtons(10.0f); + if (step != 0) { range_value += step; range_value_changed = true; } - ImGui::SetCursorPosY(button_pos.y + (padding.y * 2.0f) + UIStyle.LargeFontSize + LayoutScale(10.0f)); - if (range_value_changed) { const auto it = std::find(enable_list.begin(), enable_list.end(), ci.name); @@ -9247,6 +9297,7 @@ TRANSLATE_NOOP("FullscreenUI", "Deadzone"); TRANSLATE_NOOP("FullscreenUI", "Debugging Settings"); TRANSLATE_NOOP("FullscreenUI", "Default"); TRANSLATE_NOOP("FullscreenUI", "Default Boot"); +TRANSLATE_NOOP("FullscreenUI", "Default Value"); TRANSLATE_NOOP("FullscreenUI", "Default View"); TRANSLATE_NOOP("FullscreenUI", "Default: Disabled"); TRANSLATE_NOOP("FullscreenUI", "Default: Enabled"); @@ -9491,7 +9542,6 @@ TRANSLATE_NOOP("FullscreenUI", "Multitap Mode"); TRANSLATE_NOOP("FullscreenUI", "Mute All Sound"); TRANSLATE_NOOP("FullscreenUI", "Mute CD Audio"); TRANSLATE_NOOP("FullscreenUI", "Navigate"); -TRANSLATE_NOOP("FullscreenUI", "No Binding"); TRANSLATE_NOOP("FullscreenUI", "No Game Selected"); TRANSLATE_NOOP("FullscreenUI", "No Vibration"); TRANSLATE_NOOP("FullscreenUI", "No cheats are available for this game."); @@ -9791,6 +9841,7 @@ TRANSLATE_NOOP("FullscreenUI", "Uses perspective-correct interpolation for textu TRANSLATE_NOOP("FullscreenUI", "Uses screen positions to resolve PGXP data. May improve visuals in some games."); TRANSLATE_NOOP("FullscreenUI", "Uses separate game settings for each disc of multi-disc games. Can only be set on the first/main disc."); TRANSLATE_NOOP("FullscreenUI", "Utilizes the chosen frame rate regardless of the game's setting."); +TRANSLATE_NOOP("FullscreenUI", "Value Range"); TRANSLATE_NOOP("FullscreenUI", "Value: {} | Default: {} | Minimum: {} | Maximum: {}"); TRANSLATE_NOOP("FullscreenUI", "Vertex Cache"); TRANSLATE_NOOP("FullscreenUI", "Vertical Sync (VSync)"); diff --git a/src/util/imgui_fullscreen.cpp b/src/util/imgui_fullscreen.cpp index 2341e0f0b..0df307747 100644 --- a/src/util/imgui_fullscreen.cpp +++ b/src/util/imgui_fullscreen.cpp @@ -631,6 +631,7 @@ bool ImGuiFullscreen::UpdateLayoutScale() UIStyle.RcpLayoutScale = 1.0f / UIStyle.LayoutScale; UIStyle.LargeFontSize = LayoutScale(LAYOUT_LARGE_FONT_SIZE); UIStyle.MediumFontSize = LayoutScale(LAYOUT_MEDIUM_FONT_SIZE); + UIStyle.MediumLargeFontSize = LayoutScale(LAYOUT_MEDIUM_LARGE_FONT_SIZE); return (UIStyle.LayoutScale != old_scale); @@ -644,6 +645,7 @@ bool ImGuiFullscreen::UpdateLayoutScale() UIStyle.RcpLayoutScale = 1.0f / UIStyle.LayoutScale; UIStyle.LargeFontSize = LayoutScale(LAYOUT_LARGE_FONT_SIZE); UIStyle.MediumFontSize = LayoutScale(LAYOUT_MEDIUM_FONT_SIZE); + UIStyle.MediumLargeFontSize = LayoutScale(LAYOUT_MEDIUM_LARGE_FONT_SIZE); return (UIStyle.LayoutScale != old_scale); #endif @@ -1573,8 +1575,12 @@ void ImGuiFullscreen::MenuButtonBounds::CalcBB() frame_bb = ImRect(pos - padding, br_pos + padding); title_bb = ImRect(pos, ImVec2(pos.x + title_size.x, pos.y + title_size.y)); + + // give the title the full bounding box if there's no value if (value_size.x > 0.0f) value_bb = ImRect(ImVec2(br_pos.x - value_size.x, pos.y), br_pos); + else + title_bb.Max.x = br_pos.x; if (summary_size.x > 0.0f) { @@ -2304,14 +2310,19 @@ void ImGuiFullscreen::BeginHorizontalMenuButtons(u32 num_items, float max_item_w PrerenderMenuButtonBorder(); } -void ImGuiFullscreen::EndHorizontalMenuButtons() +void ImGuiFullscreen::EndHorizontalMenuButtons(float add_vertical_spacing /*= -1.0f*/) { ImGui::PopStyleVar(4); ImGui::GetCurrentWindow()->DC.LayoutType = ImGuiLayoutType_Vertical; + + const float dummy_height = ImGui::GetCurrentWindowRead()->DC.CurrLineSize.y + + ((add_vertical_spacing > 0.0f) ? LayoutScale(add_vertical_spacing) : 0.0f); + ImGui::ItemSize(ImVec2(0.0f, (dummy_height > 0.0f) ? dummy_height : ImGui::GetFontSize())); } bool ImGuiFullscreen::HorizontalMenuButton(std::string_view title, bool enabled /* = true */, - const ImVec2& text_align /* = LAYOUT_CENTER_ALIGN_TEXT */) + const ImVec2& text_align /* = LAYOUT_CENTER_ALIGN_TEXT */, + ImGuiButtonFlags flags /*= 0 */) { ImGuiWindow* window = ImGui::GetCurrentWindow(); if (window->SkipItems) @@ -2340,7 +2351,7 @@ bool ImGuiFullscreen::HorizontalMenuButton(std::string_view title, bool enabled bool pressed; if (enabled) { - pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0); + pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, flags); if (hovered) { const ImU32 col = ImGui::GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered); diff --git a/src/util/imgui_fullscreen.h b/src/util/imgui_fullscreen.h index a402eab08..0ca45509d 100644 --- a/src/util/imgui_fullscreen.h +++ b/src/util/imgui_fullscreen.h @@ -35,6 +35,7 @@ static constexpr float LAYOUT_SCREEN_WIDTH = 1280.0f; static constexpr float LAYOUT_SCREEN_HEIGHT = 720.0f; static constexpr float LAYOUT_LARGE_FONT_SIZE = 26.0f; static constexpr float LAYOUT_MEDIUM_FONT_SIZE = 16.0f; +static constexpr float LAYOUT_MEDIUM_LARGE_FONT_SIZE = 21.0f; static constexpr float LAYOUT_SMALL_FONT_SIZE = 10.0f; static constexpr float LAYOUT_MENU_BUTTON_X_PADDING = 15.0f; static constexpr float LAYOUT_MENU_BUTTON_Y_PADDING = 10.0f; @@ -88,6 +89,7 @@ struct ALIGN_TO_CACHE_LINE UIStyles float LayoutPaddingTop; float LargeFontSize; float MediumFontSize; + float MediumLargeFontSize; static constexpr float NormalFontWeight = 0.0f; static constexpr float BoldFontWeight = 500.0f; @@ -349,9 +351,9 @@ void BeginHorizontalMenuButtons(u32 num_items, float max_item_width = 0.0f, float y_padding = LAYOUT_MENU_BUTTON_Y_PADDING, float x_spacing = LAYOUT_MENU_BUTTON_X_PADDING, float x_margin = LAYOUT_MENU_WINDOW_X_PADDING); -void EndHorizontalMenuButtons(); +void EndHorizontalMenuButtons(float add_vertical_spacing = -1.0f); bool HorizontalMenuButton(std::string_view title, bool enabled = true, - const ImVec2& text_align = LAYOUT_CENTER_ALIGN_TEXT); + const ImVec2& text_align = LAYOUT_CENTER_ALIGN_TEXT, ImGuiButtonFlags flags = 0); void BeginNavBar(float x_padding = LAYOUT_MENU_BUTTON_X_PADDING, float y_padding = LAYOUT_MENU_BUTTON_Y_PADDING); void EndNavBar();