From 91f874cbaddf5e31a865161e0bb7ed3cda79954b Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:30:33 +0000 Subject: [PATCH] Implemented max width for button guide strings for localisation (#421) * button_guide: implemented max width for localisation * button_guide: implemented max width for dual icon strings * button_guide: scale max width internally --- UnleashedRecomp/patches/CHudPause_patches.cpp | 2 +- UnleashedRecomp/ui/achievement_menu.cpp | 2 +- UnleashedRecomp/ui/button_guide.cpp | 114 +++++++++--------- UnleashedRecomp/ui/button_guide.h | 14 ++- UnleashedRecomp/ui/installer_wizard.cpp | 8 +- UnleashedRecomp/ui/message_window.cpp | 10 +- UnleashedRecomp/ui/options_menu.cpp | 8 +- 7 files changed, 81 insertions(+), 77 deletions(-) diff --git a/UnleashedRecomp/patches/CHudPause_patches.cpp b/UnleashedRecomp/patches/CHudPause_patches.cpp index 50e0d54..51990fa 100644 --- a/UnleashedRecomp/patches/CHudPause_patches.cpp +++ b/UnleashedRecomp/patches/CHudPause_patches.cpp @@ -172,7 +172,7 @@ PPC_FUNC(sub_824B0930) if (*SWA::SGlobals::ms_IsRenderHud && pHudPause->m_IsShown && !pHudPause->m_Submenu && pHudPause->m_Transition == SWA::eTransitionType_Undefined) { - ButtonGuide::Open(Button("Achievements_Name", EButtonIcon::Back, EButtonAlignment::Left, EFontQuality::Low)); + ButtonGuide::Open(Button("Achievements_Name", FLT_MAX, EButtonIcon::Back, EButtonAlignment::Left, EFontQuality::Low)); g_isClosed = false; } else if (!g_isClosed) diff --git a/UnleashedRecomp/ui/achievement_menu.cpp b/UnleashedRecomp/ui/achievement_menu.cpp index 2de46b9..9a7bd3a 100644 --- a/UnleashedRecomp/ui/achievement_menu.cpp +++ b/UnleashedRecomp/ui/achievement_menu.cpp @@ -763,7 +763,7 @@ void AchievementMenu::Open() return std::get<1>(a) > std::get<1>(b); }); - ButtonGuide::Open(Button("Common_Back", EButtonIcon::B)); + ButtonGuide::Open(Button("Common_Back", FLT_MAX, EButtonIcon::B)); ResetSelection(); Game_PlaySound("sys_actstg_pausewinopen"); diff --git a/UnleashedRecomp/ui/button_guide.cpp b/UnleashedRecomp/ui/button_guide.cpp index 9a7a8d1..e5457ed 100644 --- a/UnleashedRecomp/ui/button_guide.cpp +++ b/UnleashedRecomp/ui/button_guide.cpp @@ -153,70 +153,67 @@ ImFont* GetFont(EFontQuality fontQuality) static void DrawGuide(float* offset, ImVec2 regionMin, ImVec2 regionMax, EButtonIcon icon, EButtonAlignment alignment, ImVec2 iconMin, ImVec2 iconMax, EFontQuality fontQuality, - ImVec2 textSize, float fontSize, const char* text) + float textWidth, float maxTextWidth, float textScale, float fontSize, const char* text) { auto drawList = ImGui::GetBackgroundDrawList(); - auto _icon = icon; auto iconWidth = Scale(g_iconWidths[icon]); - auto dualIconMarginX = Scale(25); - - if (icon == EButtonIcon::LBRB) - { - _icon = EButtonIcon::LB; - } - else if (icon == EButtonIcon::LTRT) - { - _icon = EButtonIcon::LT; - } - else - { - dualIconMarginX = 0; - } - - if (icon == EButtonIcon::LBRB || icon == EButtonIcon::LTRT) - { - iconMin = alignment == EButtonAlignment::Left - ? ImVec2(/* X */ regionMin.x + *offset - dualIconMarginX * 3, /* Y */ iconMin.y) - : ImVec2(/* X */ regionMax.x - *offset - textSize.x - iconWidth, /* Y */ iconMin.y); - - iconMax = alignment == EButtonAlignment::Left - ? ImVec2(iconMin.x + iconWidth, iconMax.y) - : ImVec2(iconMin.x, iconMax.y); - } - - auto btnIcon = GetButtonIcon(_icon); - drawList->AddImage(std::get<1>(btnIcon), iconMin, iconMax, GET_UV_COORDS(std::get<0>(btnIcon))); - auto font = GetFont(fontQuality); + auto textMarginY = regionMin.y + Scale(8.89f); - auto textMarginX = alignment == EButtonAlignment::Left - ? regionMin.x + *offset + dualIconMarginX - : regionMax.x - *offset - dualIconMarginX * 2; - - auto textMarginY = regionMin.y + Scale(8); - - ImVec2 textPosition = { textMarginX, textMarginY }; - - DrawTextWithOutline(font, fontSize, textPosition, IM_COL32_WHITE, text, 4, IM_COL32_BLACK); - - // Add extra luminance to low quality text. - if (fontQuality == EFontQuality::Low) - drawList->AddText(font, fontSize, textPosition, IM_COL32(255, 255, 255, 127), text); + ImVec2 textPos; if (icon == EButtonIcon::LBRB || icon == EButtonIcon::LTRT) { - auto btnIcon = GetButtonIcon(icon == EButtonIcon::LBRB ? EButtonIcon::RB : EButtonIcon::RT); + auto iconMarginX = Scale(16); + + iconMin = alignment == EButtonAlignment::Left + ? ImVec2(/* X */ regionMin.x + *offset - maxTextWidth + iconMarginX, /* Y */ iconMin.y) + : ImVec2(/* X */ regionMax.x - *offset - maxTextWidth + iconMarginX - iconWidth, /* Y */ iconMin.y); + + iconMax = ImVec2(iconMin.x + iconWidth, iconMax.y); + + // Left button. + auto btnIcon = GetButtonIcon(icon == EButtonIcon::LBRB ? EButtonIcon::LB : EButtonIcon::LT); + drawList->AddImage(std::get<1>(btnIcon), iconMin, iconMax, GET_UV_COORDS(std::get<0>(btnIcon))); auto dualIconMin = alignment == EButtonAlignment::Left - ? ImVec2(/* X */ regionMin.x + *offset + textSize.x + dualIconMarginX * 2, /* Y */ iconMin.y) - : ImVec2(/* X */ regionMax.x - *offset + textSize.x - dualIconMarginX, /* Y */ iconMin.y); + ? ImVec2(/* X */ regionMin.x + *offset + maxTextWidth - iconMarginX, /* Y */ iconMin.y) + : ImVec2(/* X */ regionMax.x - *offset + maxTextWidth - iconMarginX - iconWidth, /* Y */ iconMin.y); auto dualIconMax = ImVec2(dualIconMin.x + iconWidth, iconMax.y); + // Right button. + btnIcon = GetButtonIcon(icon == EButtonIcon::LBRB ? EButtonIcon::RB : EButtonIcon::RT); drawList->AddImage(std::get<1>(btnIcon), dualIconMin, dualIconMax, GET_UV_COORDS(std::get<0>(btnIcon))); - *offset += dualIconMarginX + iconWidth; + textPos = { (iconMax.x + ((dualIconMin.x - iconMax.x) - maxTextWidth + std::max(0.0f, maxTextWidth - textWidth)) / 2) + Scale(2), textMarginY}; + + *offset += iconWidth; } + else + { + auto btnIcon = GetButtonIcon(icon); + + drawList->AddImage(std::get<1>(btnIcon), iconMin, iconMax, GET_UV_COORDS(std::get<0>(btnIcon))); + + auto textMarginX = alignment == EButtonAlignment::Left + ? regionMin.x + *offset + : regionMax.x - *offset; + + textPos = { textMarginX, textMarginY }; + } + + SetScale({ textScale, 1.0f }); + SetOrigin(textPos); + + DrawTextWithOutline(font, fontSize, textPos, IM_COL32_WHITE, text, 4, IM_COL32_BLACK); + + // Add extra luminance to low quality text. + if (fontQuality == EFontQuality::Low) + drawList->AddText(font, fontSize, textPos, IM_COL32(255, 255, 255, 127), text); + + SetScale({ 1.0f, 1.0f }); + SetOrigin({ 0.0f, 0.0f }); } void ButtonGuide::Init() @@ -241,10 +238,9 @@ void ButtonGuide::Draw() ImVec2 regionMin = { g_aspectRatioOffsetX + Scale(g_sideMargins), g_aspectRatioOffsetY * 2.0f + Scale(720.0f - 102.0f) }; ImVec2 regionMax = { g_aspectRatioOffsetX + Scale(1280.0f - g_sideMargins), g_aspectRatioOffsetY * 2.0f + Scale(720.0f) }; - auto textMarginX = Scale(57); - auto textMarginY = Scale(8); + auto textMarginX = Scale(21.25f); auto iconMarginX = Scale(4); - auto fontSize = Scale(22.5f); + auto fontSize = Scale(21.8f); auto offsetLeft = 0.0f; auto offsetRight = 0.0f; @@ -263,15 +259,17 @@ void ButtonGuide::Draw() auto str = Localise(btn.Name.c_str()).c_str(); auto iconWidth = Scale(g_iconWidths[btn.Icon]); auto iconHeight = Scale(g_iconHeights[btn.Icon]); - auto textSize = g_fntNewRodin->CalcTextSizeA(fontSize, FLT_MAX, 0, str); + auto textWidth = g_fntNewRodin->CalcTextSizeA(fontSize, FLT_MAX, 0, str).x; + auto maxWidth = btn.MaxWidth == FLT_MAX ? textWidth : Scale(btn.MaxWidth); + auto textScale = std::min(1.0f, maxWidth / textWidth); if (i > 0) - offsetLeft += textSize.x + iconWidth + textMarginX; + offsetLeft += maxWidth + iconWidth + textMarginX; ImVec2 iconMin = { regionMin.x + offsetLeft - iconWidth - iconMarginX, regionMin.y }; ImVec2 iconMax = { regionMin.x + offsetLeft - iconMarginX, regionMin.y + iconHeight }; - DrawGuide(&offsetLeft, regionMin, regionMax, btn.Icon, btn.Alignment, iconMin, iconMax, btn.FontQuality, textSize, fontSize, str); + DrawGuide(&offsetLeft, regionMin, regionMax, btn.Icon, btn.Alignment, iconMin, iconMax, btn.FontQuality, textWidth, maxWidth, textScale, fontSize, str); } // Draw right aligned icons. @@ -288,15 +286,17 @@ void ButtonGuide::Draw() auto str = Localise(btn.Name.c_str()).c_str(); auto iconWidth = Scale(g_iconWidths[btn.Icon]); auto iconHeight = Scale(g_iconHeights[btn.Icon]); - auto textSize = g_fntNewRodin->CalcTextSizeA(fontSize, FLT_MAX, 0, str); + auto textWidth = g_fntNewRodin->CalcTextSizeA(fontSize, FLT_MAX, 0, str).x; + auto maxWidth = btn.MaxWidth == FLT_MAX ? textWidth : Scale(btn.MaxWidth); + auto textScale = std::min(1.0f, maxWidth / textWidth); if (i < g_buttons.size() - 1) - offsetRight += textSize.x + iconWidth + textMarginX; + offsetRight += maxWidth + iconWidth + textMarginX; ImVec2 iconMin = { regionMax.x - offsetRight - iconWidth - iconMarginX, regionMin.y }; ImVec2 iconMax = { regionMax.x - offsetRight - iconMarginX, regionMin.y + iconHeight }; - DrawGuide(&offsetRight, regionMin, regionMax, btn.Icon, btn.Alignment, iconMin, iconMax, btn.FontQuality, textSize, fontSize, str); + DrawGuide(&offsetRight, regionMin, regionMax, btn.Icon, btn.Alignment, iconMin, iconMax, btn.FontQuality, textWidth, maxWidth, textScale, fontSize, str); } } diff --git a/UnleashedRecomp/ui/button_guide.h b/UnleashedRecomp/ui/button_guide.h index 0849314..81e6dcd 100644 --- a/UnleashedRecomp/ui/button_guide.h +++ b/UnleashedRecomp/ui/button_guide.h @@ -40,19 +40,23 @@ class Button { public: std::string Name{}; + float MaxWidth{ FLT_MAX }; EButtonIcon Icon{}; EButtonAlignment Alignment{ EButtonAlignment::Right }; EFontQuality FontQuality{ EFontQuality::High }; bool* Visibility{ nullptr }; - Button(std::string name, EButtonIcon icon, EButtonAlignment alignment, EFontQuality fontQuality = EFontQuality::High, bool* visibility = nullptr) - : Name(name), Icon(icon), Alignment(alignment), FontQuality(fontQuality), Visibility(visibility) {} + Button(std::string name, float maxWidth, EButtonIcon icon, EButtonAlignment alignment, EFontQuality fontQuality = EFontQuality::High, bool* visibility = nullptr) + : Name(name), MaxWidth(maxWidth), Icon(icon), Alignment(alignment), FontQuality(fontQuality), Visibility(visibility) {} - Button(std::string name, EButtonIcon icon, EButtonAlignment alignment, bool* visibility) : Name(name), Icon(icon), Alignment(alignment), Visibility(visibility) {} + Button(std::string name, float maxWidth, EButtonIcon icon, EButtonAlignment alignment, bool* visibility) + : Name(name), MaxWidth(maxWidth), Icon(icon), Alignment(alignment), Visibility(visibility) {} - Button(std::string name, EButtonIcon icon, bool* visibility) : Name(name), Icon(icon), Visibility(visibility) {} + Button(std::string name, float maxWidth, EButtonIcon icon, bool* visibility) + : Name(name), MaxWidth(maxWidth), Icon(icon), Visibility(visibility) {} - Button(std::string name, EButtonIcon icon) : Name(name), Icon(icon) {} + Button(std::string name, float maxWidth, EButtonIcon icon) + : Name(name), MaxWidth(maxWidth), Icon(icon) {} }; class ButtonGuide diff --git a/UnleashedRecomp/ui/installer_wizard.cpp b/UnleashedRecomp/ui/installer_wizard.cpp index a4dcd98..7fc70a2 100644 --- a/UnleashedRecomp/ui/installer_wizard.cpp +++ b/UnleashedRecomp/ui/installer_wizard.cpp @@ -872,7 +872,7 @@ static void DrawDescriptionContainer() if (g_currentPage == WizardPage::InstallSucceeded && textAlpha >= 1.0) { - ButtonGuide::Open(Button("Common_Select", selectIcon)); + ButtonGuide::Open(Button("Common_Select", 115.0f, selectIcon)); } else if (g_currentPage != WizardPage::Installing && textAlpha >= 1.0) { @@ -884,15 +884,15 @@ static void DrawDescriptionContainer() std::array buttons = { - Button("Common_Select", selectIcon), - Button(backKey, backIcon) + Button("Common_Select", 115.0f, selectIcon), + Button(backKey, FLT_MAX, backIcon) }; ButtonGuide::Open(buttons); } else if (g_currentPage == WizardPage::Installing) { - ButtonGuide::Open(Button("Common_Cancel", backIcon)); + ButtonGuide::Open(Button("Common_Cancel", FLT_MAX, backIcon)); } else { diff --git a/UnleashedRecomp/ui/message_window.cpp b/UnleashedRecomp/ui/message_window.cpp index 6cadfe0..5502eb8 100644 --- a/UnleashedRecomp/ui/message_window.cpp +++ b/UnleashedRecomp/ui/message_window.cpp @@ -245,7 +245,7 @@ void DrawNextButtonGuide(bool isController, bool isKeyboard) if (App::s_isInit) icon = EButtonIcon::A; - ButtonGuide::Open(Button("Common_Next", icon)); + ButtonGuide::Open(Button("Common_Next", FLT_MAX, icon)); } static void ResetSelection() @@ -425,8 +425,8 @@ void MessageWindow::Draw() std::array buttons = { - Button("Common_Select", selectIcon), - Button("Common_Back", backIcon), + Button("Common_Select", 115.0f, selectIcon), + Button("Common_Back", FLT_MAX, backIcon), }; ButtonGuide::Open(buttons); @@ -470,8 +470,8 @@ void MessageWindow::Draw() std::array buttons = { - Button("Common_Select", EButtonIcon::LMB), - Button("Common_Back", EButtonIcon::Escape), + Button("Common_Select", 115.0f, EButtonIcon::LMB), + Button("Common_Back", FLT_MAX, EButtonIcon::Escape), }; ButtonGuide::Open(buttons); diff --git a/UnleashedRecomp/ui/options_menu.cpp b/UnleashedRecomp/ui/options_menu.cpp index 453e8c4..5d45341 100644 --- a/UnleashedRecomp/ui/options_menu.cpp +++ b/UnleashedRecomp/ui/options_menu.cpp @@ -1790,10 +1790,10 @@ void OptionsMenu::Open(bool isPause, SWA::EMenuType pauseMenuType) std::array buttons = { - Button("Common_Switch", EButtonIcon::LBRB, EButtonAlignment::Left, &g_isControlsVisible), - Button("Common_Reset", EButtonIcon::X, &g_canReset), - Button("Common_Select", EButtonIcon::A, &g_isControlsVisible), - Button("Common_Back", EButtonIcon::B, &g_isControlsVisible) + Button("Common_Switch", 115.0f, EButtonIcon::LBRB, EButtonAlignment::Left, &g_isControlsVisible), + Button("Common_Reset", 110.0f, EButtonIcon::X, &g_canReset), + Button("Common_Select", 115.0f, EButtonIcon::A, &g_isControlsVisible), + Button("Common_Back", 65.0f, EButtonIcon::B, &g_isControlsVisible) }; ButtonGuide::Open(buttons);