FullscreenUI: Polish dialogs

This commit is contained in:
Stenzek 2025-06-14 01:19:46 +10:00
parent 77457a3b1d
commit 06da45b3f2
No known key found for this signature in database
3 changed files with 288 additions and 38 deletions

View File

@ -84,6 +84,7 @@ public:
using ImGuiFullscreen::ChoiceDialogOptions;
using ImGuiFullscreen::FocusResetType;
using ImGuiFullscreen::LAYOUT_CENTER_ALIGN_TEXT;
using ImGuiFullscreen::LAYOUT_FOOTER_HEIGHT;
using ImGuiFullscreen::LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE;
using ImGuiFullscreen::LAYOUT_LARGE_FONT_SIZE;
@ -2961,7 +2962,7 @@ void FullscreenUI::DrawIntRangeSetting(SettingsInterface* bsi, std::string_view
ImGui::PopStyleVar(2);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImVec2(0.5f, 0.0f)))
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
{
CloseFixedPopupDialog();
}
@ -3016,7 +3017,7 @@ void FullscreenUI::DrawFloatRangeSetting(SettingsInterface* bsi, std::string_vie
ImGui::PopStyleVar(2);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImVec2(0.5f, 0.0f)))
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
CloseFixedPopupDialog();
EndMenuButtons();
@ -3136,7 +3137,7 @@ void FullscreenUI::DrawFloatSpinBoxSetting(SettingsInterface* bsi, std::string_v
SetSettingsChanged(bsi);
}
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImVec2(0.5f, 0.0f)))
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
CloseFixedPopupDialog();
EndMenuButtons();
@ -3249,7 +3250,7 @@ bool FullscreenUI::DrawIntRectSetting(SettingsInterface* bsi, std::string_view t
ImGui::PopStyleVar(2);
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImVec2(0.5f, 0.0f)))
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
CloseFixedPopupDialog();
EndMenuButtons();
@ -3368,7 +3369,7 @@ void FullscreenUI::DrawIntSpinBoxSetting(SettingsInterface* bsi, std::string_vie
SetSettingsChanged(bsi);
}
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImVec2(0.5f, 0.0f)))
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
CloseFixedPopupDialog();
EndMenuButtons();
@ -5106,7 +5107,8 @@ void FullscreenUI::DrawControllerSettingsPage()
}
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImVec2(0.5f, 0.0f)))
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
LAYOUT_CENTER_ALIGN_TEXT))
CloseFixedPopupDialog();
EndMenuButtons();
@ -5983,7 +5985,7 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
ImVec2(0.5f, 0.0f)))
LAYOUT_CENTER_ALIGN_TEXT))
{
CloseFixedPopupDialog();
}
@ -6052,7 +6054,7 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
ImVec2(0.5f, 0.0f)))
LAYOUT_CENTER_ALIGN_TEXT))
{
CloseFixedPopupDialog();
}
@ -6466,7 +6468,8 @@ void FullscreenUI::DrawAchievementsLoginWindow()
const bool login_enabled = (std::strlen(username) > 0 && std::strlen(password) > 0 && !is_logging_in);
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_KEY, "Login"), login_enabled))
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_KEY, "Login"), login_enabled, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
LAYOUT_CENTER_ALIGN_TEXT))
{
ImGuiFullscreen::OpenBackgroundProgressDialog(LOGIN_PROGRESS_NAME, FSUI_STR("Logging in to RetroAchievements..."),
0, 0, 0);
@ -6490,8 +6493,11 @@ void FullscreenUI::DrawAchievementsLoginWindow()
});
}
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_TIMES, "Cancel"), !is_logging_in))
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_TIMES, "Cancel"), !is_logging_in,
LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
{
CloseFixedPopupDialog();
}
EndMenuButtons();
@ -6740,7 +6746,8 @@ void FullscreenUI::DrawPatchesOrCheatsSettingsPage(bool cheats)
SetSettingsChanged(bsi);
}
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImVec2(0.5f, 0.0f)))
if (MenuButtonWithoutSummary(FSUI_VSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
LAYOUT_CENTER_ALIGN_TEXT))
CloseFixedPopupDialog();
EndMenuButtons();
@ -7557,21 +7564,23 @@ bool FullscreenUI::OpenLoadStateSelectorForGameResume(const GameList::Entry* ent
void FullscreenUI::DrawResumeStateSelector()
{
if (!BeginFixedPopupDialog(LayoutScale(30.0f), LayoutScale(40.0f), LayoutScale(820.0f, 645.0f)))
if (!BeginFixedPopupDialog(LayoutScale(30.0f), LayoutScale(40.0f), ImVec2(LayoutScale(550.0f), 0.0f)))
{
ClearSaveStateEntryList();
return;
}
SaveStateListEntry& entry = s_state.save_state_selector_slots.front();
SmallString time;
TimeToPrintableString(&time, entry.timestamp);
ImGui::TextWrapped(
FSUI_CSTR("A resume save state created at %s was found.\n\nDo you want to load this save and continue?"),
time.c_str());
SmallString sick;
sick.format(FSUI_FSTR("Do you want to continue from the automatic save created at {:%c}?"),
fmt::localtime(entry.timestamp));
ImGui::PushFontWeight(UIStyle.BoldFontWeight);
ImGuiFullscreen::TextAlignedMultiLine(0.5f, IMSTR_START_END(sick));
ImGui::PopFontWeight();
const GPUTexture* image = entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture().get();
const float image_height = LayoutScale(250.0f);
const float image_height = LayoutScale(280.0f);
const float image_width =
image_height * (static_cast<float>(image->GetWidth()) / static_cast<float>(image->GetHeight()));
const ImVec2 pos(ImGui::GetCursorScreenPos() +
@ -7587,7 +7596,8 @@ void FullscreenUI::DrawResumeStateSelector()
ResetFocusHere();
BeginMenuButtons();
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_PLAY, "Load State")))
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_PLAY, "Load State"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
LAYOUT_CENTER_ALIGN_TEXT))
{
std::string game_path = std::move(entry.game_path);
std::string state_path = std::move(entry.state_path);
@ -7596,7 +7606,8 @@ void FullscreenUI::DrawResumeStateSelector()
DoStartPath(std::move(game_path), std::move(state_path));
}
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_LIGHTBULB, "Clean Boot")))
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_LIGHTBULB, "Clean Boot"), true,
LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
{
std::string game_path = std::move(entry.game_path);
ClearSaveStateEntryList();
@ -7604,7 +7615,8 @@ void FullscreenUI::DrawResumeStateSelector()
DoStartPath(std::move(game_path));
}
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_FOLDER_MINUS, "Delete State")))
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_FOLDER_MINUS, "Delete State"), true,
LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
{
if (FileSystem::DeleteFile(entry.state_path.c_str()))
{
@ -7619,10 +7631,13 @@ void FullscreenUI::DrawResumeStateSelector()
}
}
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_WINDOW_CLOSE, "Cancel")))
if (MenuButtonWithoutSummary(FSUI_ICONVSTR(ICON_FA_WINDOW_CLOSE, "Cancel"), true,
LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
{
CloseFixedPopupDialog();
}
EndMenuButtons();
ImGuiFullscreen::EndHorizontalMenuButtons();
SetStandardSelectionFooterText(false);
@ -8309,12 +8324,14 @@ void FullscreenUI::DrawGameGrid(const ImVec2& heading_size)
// ellipise title, remove one character to make room
draw_title.format("{}...", std::string_view(entry->title).substr(0, unclipped_size - 1));
RenderShadowedTextClipped(UIStyle.Font, UIStyle.MediumFontSize, UIStyle.NormalFontWeight, title_bb.Min,
title_bb.Max, text_color, draw_title, nullptr, ImVec2(0.5f, 0.0f), 0.0f, &title_bb);
title_bb.Max, text_color, draw_title, nullptr, LAYOUT_CENTER_ALIGN_TEXT, 0.0f,
&title_bb);
}
else
{
RenderShadowedTextClipped(UIStyle.Font, UIStyle.MediumFontSize, UIStyle.NormalFontWeight, title_bb.Min,
title_bb.Max, text_color, entry->title, nullptr, ImVec2(0.5f, 0.0f), 0.0f, &title_bb);
title_bb.Max, text_color, entry->title, nullptr, LAYOUT_CENTER_ALIGN_TEXT, 0.0f,
&title_bb);
}
if (pressed)
@ -9190,7 +9207,6 @@ TRANSLATE_NOOP("FullscreenUI", "9x");
TRANSLATE_NOOP("FullscreenUI", "9x (18x Speed)");
TRANSLATE_NOOP("FullscreenUI", "9x (for 4K)");
TRANSLATE_NOOP("FullscreenUI", "A cover already exists for this game. Are you sure that you want to overwrite it?");
TRANSLATE_NOOP("FullscreenUI", "A resume save state created at %s was found.\n\nDo you want to load this save and continue?");
TRANSLATE_NOOP("FullscreenUI", "AMOLED");
TRANSLATE_NOOP("FullscreenUI", "About");
TRANSLATE_NOOP("FullscreenUI", "Account");
@ -9364,6 +9380,7 @@ TRANSLATE_NOOP("FullscreenUI", "Displays DualShock/DualSense button icons in the
TRANSLATE_NOOP("FullscreenUI", "Displays popup messages on events such as achievement unlocks and leaderboard submissions.");
TRANSLATE_NOOP("FullscreenUI", "Displays popup messages when starting, submitting, or failing a leaderboard challenge.");
TRANSLATE_NOOP("FullscreenUI", "Dithering");
TRANSLATE_NOOP("FullscreenUI", "Do you want to continue from the automatic save created at {:%c}?");
TRANSLATE_NOOP("FullscreenUI", "Double-Click Toggles Fullscreen");
TRANSLATE_NOOP("FullscreenUI", "Download Covers");
TRANSLATE_NOOP("FullscreenUI", "Downloads covers from a user-specified URL template.");

View File

@ -207,12 +207,14 @@ struct ALIGN_TO_CACHE_LINE UIState
{
std::recursive_mutex shared_state_mutex;
u32 menu_button_index = 0;
CloseButtonState close_button_state = CloseButtonState::None;
ImGuiDir has_pending_nav_move = ImGuiDir_None;
FocusResetType focus_reset_queued = FocusResetType::None;
bool initialized = false;
u32 menu_button_index = 0;
ImVec2 horizontal_menu_button_size = {};
LRUCache<std::string, std::shared_ptr<GPUTexture>> texture_cache{128, true};
std::shared_ptr<GPUTexture> placeholder_texture;
std::deque<std::pair<std::string, Image>> texture_upload_queue;
@ -1554,6 +1556,101 @@ void ImGuiFullscreen::RenderShadowedTextClipped(ImFont* font, float font_size, f
text_size_if_known, align, wrap_width, clip_rect);
}
void ImGuiFullscreen::TextAlignedMultiLine(float align_x, const char* text, const char* text_end, float wrap_width)
{
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return;
ImGuiContext& g = *GImGui;
IM_ASSERT(text != NULL);
if (text_end == NULL)
text_end = text + strlen(text);
const ImVec2 text_pos = window->DC.CursorPos;
const ImRect clip_rect = window->ClipRect;
wrap_width = (wrap_width < 0.0f) ? ImGui::GetContentRegionAvail().x : wrap_width;
ImVec2 pos = text_pos;
const char* text_remaining = text;
while (text_remaining < text_end)
{
// Find the end of the current wrapped line
const char* line_end = text_remaining;
float line_width = 0.0f;
// Process text word by word to find natural line breaks
while (line_end < text_end)
{
const char* word_start = line_end;
const char* word_end = word_start;
// Handle explicit newlines
if (*line_end == '\n')
{
line_end++;
break;
}
// Find end of current word (including spaces)
while (word_end < text_end && *word_end != ' ' && *word_end != '\n')
word_end++;
// Include trailing space if present
if (word_end < text_end && *word_end == ' ')
word_end++;
// Calculate width if we add this word
ImVec2 word_size = ImGui::CalcTextSize(text_remaining, word_end, false, -1.0f);
// If adding this word would exceed wrap width, break here
if (word_size.x > wrap_width && line_end > text_remaining)
break;
line_end = word_end;
line_width = word_size.x;
}
// If we didn't advance at all, force at least one character to prevent infinite loop
if (line_end == text_remaining && line_end < text_end)
line_end++;
// Calculate actual line size for the determined line segment
ImVec2 line_size = ImGui::CalcTextSize(text_remaining, line_end, false, -1.0f);
// Calculate aligned position for this line
ImVec2 line_pos = pos;
if (align_x > 0.0f)
{
float offset_x = (wrap_width - line_size.x) * align_x;
line_pos.x += offset_x;
}
// Render the line
if (line_size.x > 0.0f)
{
ImGui::RenderTextClipped(line_pos, ImVec2(line_pos.x + line_size.x, line_pos.y + line_size.y), text_remaining,
line_end, &line_size, ImVec2(0.0f, 0.0f), &clip_rect);
}
// Move to next line
pos.y += g.FontSize + g.Style.ItemSpacing.y;
text_remaining = line_end;
// Skip trailing spaces at the beginning of the next line
while (text_remaining < text_end && *text_remaining == ' ')
text_remaining++;
}
// Update cursor position to account for the rendered text
ImVec2 text_size = ImVec2(wrap_width, pos.y - text_pos.y);
ImRect bb(text_pos, text_pos + text_size);
ImGui::ItemSize(text_size);
ImGui::ItemAdd(bb, 0);
}
void ImGuiFullscreen::MenuHeading(std::string_view title, bool draw_line /*= true*/)
{
const float line_thickness = draw_line ? LayoutScale(1.0f) : 0.0f;
@ -1970,7 +2067,7 @@ bool ImGuiFullscreen::RangeButton(std::string_view title, std::string_view summa
ImGui::PopStyleVar(2);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
if (MenuButtonWithoutSummary(ok_text, true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImVec2(0.5f, 0.0f)))
if (MenuButtonWithoutSummary(ok_text, true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
{
CloseFixedPopupDialog();
}
@ -2035,7 +2132,7 @@ bool ImGuiFullscreen::RangeButton(std::string_view title, std::string_view summa
ImGui::PopStyleVar(2);
if (MenuButtonWithoutSummary(ok_text, true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImVec2(0.5f, 0.0f)))
if (MenuButtonWithoutSummary(ok_text, true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, LAYOUT_CENTER_ALIGN_TEXT))
{
CloseFixedPopupDialog();
}
@ -2122,6 +2219,125 @@ bool ImGuiFullscreen::EnumChoiceButtonImpl(std::string_view title, std::string_v
return changed;
}
void ImGuiFullscreen::BeginHorizontalMenuButtons(u32 num_items, float max_item_width /* = 0.0f */,
float x_padding /* = LAYOUT_MENU_BUTTON_Y_PADDING */,
float y_padding /* = LAYOUT_MENU_BUTTON_Y_PADDING */,
float item_height /* = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY */,
float x_spacing /* = LAYOUT_MENU_BUTTON_X_PADDING */,
float x_margin /* = LAYOUT_MENU_WINDOW_X_PADDING */)
{
s_state.menu_button_index = 0;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, LayoutScale(x_padding, y_padding));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, LayoutScale(UIStyle.MenuBorders ? 1.0f : 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, LayoutScale(x_spacing, 0.0f));
ImGuiWindow* const window = ImGui::GetCurrentWindow();
const ImGuiStyle& style = ImGui::GetStyle();
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
const float available_width = ImGui::GetContentRegionAvail().x;
const float space_per_item = ImFloor(
std::max((available_width - LayoutScale(x_margin) - (style.ItemSpacing.x * static_cast<float>(num_items - 1))) /
static_cast<float>(num_items),
0.0f));
s_state.horizontal_menu_button_size =
ImVec2(space_per_item, LayoutScale(item_height) + (style.FramePadding.y * 2.0f));
s_state.horizontal_menu_button_size.x =
(max_item_width > 0.0f) ?
std::min(s_state.horizontal_menu_button_size.x, LayoutScale(max_item_width) + (style.FramePadding.x * 2.0f)) :
s_state.horizontal_menu_button_size.x;
const float left_padding =
ImFloor((available_width -
(((s_state.horizontal_menu_button_size.x + style.ItemSpacing.x) * static_cast<float>(num_items)) -
style.ItemSpacing.x)) *
0.5f);
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + left_padding);
// need to prerender the backgrounds for all inactive items, otherwise the animation overlaps it
const ImU32 frame_background = ImGui::GetColorU32(
DarkerColor((window->Flags & ImGuiWindowFlags_Popup) ? UIStyle.PopupBackgroundColor : UIStyle.BackgroundColor));
ImVec2 current_pos = ImGui::GetCursorScreenPos();
for (u32 i = 0; i < num_items; i++)
{
ImGui::RenderFrame(current_pos, current_pos + s_state.horizontal_menu_button_size, frame_background, false,
LayoutScale(MENU_ITEM_BORDER_ROUNDING));
current_pos.x += s_state.horizontal_menu_button_size.x + style.ItemSpacing.x;
}
PrerenderMenuButtonBorder();
}
void ImGuiFullscreen::EndHorizontalMenuButtons()
{
ImGui::PopStyleVar(4);
ImGui::GetCurrentWindow()->DC.LayoutType = ImGuiLayoutType_Vertical;
}
bool ImGuiFullscreen::HorizontalMenuButton(std::string_view title, bool enabled /* = true */,
const ImVec2& text_align /* = LAYOUT_CENTER_ALIGN_TEXT */)
{
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
const ImVec2 pos = window->DC.CursorPos;
const ImVec2& size = s_state.horizontal_menu_button_size;
ImRect bb(pos, pos + size);
const ImGuiID id = window->GetID(IMSTR_START_END(title));
ImGui::ItemSize(size);
if (enabled)
{
if (!ImGui::ItemAdd(bb, id))
return false;
}
else
{
if (ImGui::IsClippedEx(bb, id))
return false;
}
bool hovered;
bool held;
bool pressed;
if (enabled)
{
pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0);
if (hovered)
{
const ImU32 col = ImGui::GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered);
const float t = static_cast<float>(std::min(std::abs(std::sin(ImGui::GetTime() * 0.75) * 1.1), 1.0));
ImGui::PushStyleColor(ImGuiCol_Border, ImGui::GetColorU32(ImGuiCol_Border, t));
DrawMenuButtonFrame(bb.Min, bb.Max, col, true);
ImGui::PopStyleColor();
}
}
else
{
pressed = false;
held = false;
}
const ImGuiStyle& style = ImGui::GetStyle();
bb.Min += style.FramePadding;
bb.Max -= style.FramePadding;
const ImVec4& color = ImGui::GetStyle().Colors[enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled];
RenderShadowedTextClipped(UIStyle.Font, UIStyle.LargeFontSize, UIStyle.BoldFontWeight, bb.Min, bb.Max,
ImGui::GetColorU32(color), title, nullptr, text_align, 0.0f, &bb);
s_state.menu_button_index++;
return pressed;
}
void ImGuiFullscreen::BeginNavBar(float x_padding /*= LAYOUT_MENU_BUTTON_X_PADDING*/,
float y_padding /*= LAYOUT_MENU_BUTTON_Y_PADDING*/)
{
@ -3117,8 +3333,12 @@ void ImGuiFullscreen::MessageDialog::Draw()
for (s32 button_index = 0; button_index < static_cast<s32>(m_buttons.size()); button_index++)
{
if (!m_buttons[button_index].empty() && MenuButtonWithoutSummary(m_buttons[button_index]))
if (!m_buttons[button_index].empty() &&
MenuButtonWithoutSummary(m_buttons[button_index], true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
LAYOUT_CENTER_ALIGN_TEXT))
{
result = button_index;
}
}
EndMenuButtons();

View File

@ -54,6 +54,7 @@ static constexpr float LAYOUT_SMALL_POPUP_PADDING = 20.0f;
static constexpr float LAYOUT_LARGE_POPUP_PADDING = 30.0f;
static constexpr float LAYOUT_LARGE_POPUP_ROUNDING = 40.0f;
static constexpr float LAYOUT_WIDGET_FRAME_ROUNDING = 20.0f;
static constexpr ImVec2 LAYOUT_CENTER_ALIGN_TEXT = ImVec2(0.5f, 0.0f);
struct ALIGN_TO_CACHE_LINE UIStyles
{
@ -282,24 +283,26 @@ bool MenuButtonFrame(std::string_view str_id, bool enabled, float height, bool*
ImVec2* max, ImGuiButtonFlags flags = 0, float hover_alpha = 1.0f);
void DrawMenuButtonFrame(const ImVec2& p_min, const ImVec2& p_max, ImU32 fill_col, bool border = true);
void ResetMenuButtonFrame();
void RenderShadowedTextClipped(ImFont* font, float font_size, float font_weight, const ImVec2& pos_min, const ImVec2& pos_max, u32 color,
std::string_view text, const ImVec2* text_size_if_known = nullptr,
const ImVec2& align = ImVec2(0, 0), float wrap_width = 0.0f,
const ImRect* clip_rect = nullptr);
void RenderShadowedTextClipped(ImDrawList* draw_list, ImFont* font, float font_size, float font_weight, const ImVec2& pos_min,
void RenderShadowedTextClipped(ImFont* font, float font_size, float font_weight, const ImVec2& pos_min,
const ImVec2& pos_max, u32 color, std::string_view text,
const ImVec2* text_size_if_known = nullptr, const ImVec2& align = ImVec2(0, 0),
float wrap_width = 0.0f, const ImRect* clip_rect = nullptr);
void RenderShadowedTextClipped(ImDrawList* draw_list, ImFont* font, float font_size, float font_weight, const ImVec2& pos_min,
const ImVec2& pos_max, u32 color, std::string_view text,
void RenderShadowedTextClipped(ImDrawList* draw_list, ImFont* font, float font_size, float font_weight,
const ImVec2& pos_min, const ImVec2& pos_max, u32 color, std::string_view text,
const ImVec2* text_size_if_known = nullptr, const ImVec2& align = ImVec2(0, 0),
float wrap_width = 0.0f, const ImRect* clip_rect = nullptr);
void RenderShadowedTextClipped(ImDrawList* draw_list, ImFont* font, float font_size, float font_weight,
const ImVec2& pos_min, const ImVec2& pos_max, u32 color, std::string_view text,
const ImVec2* text_size_if_known, const ImVec2& align, float wrap_width,
const ImRect* clip_rect, float shadow_offset);
void TextAlignedMultiLine(float align_x, const char* text, const char* text_end = nullptr, float wrap_width = -1.0f);
void MenuHeading(std::string_view title, bool draw_line = true);
bool MenuHeadingButton(std::string_view title, std::string_view value = {}, bool enabled = true, bool draw_line = true);
bool MenuButton(std::string_view title, std::string_view summary, bool enabled = true,
float height = LAYOUT_MENU_BUTTON_HEIGHT, const ImVec2& text_align = ImVec2(0.0f, 0.0f));
bool MenuButtonWithoutSummary(std::string_view title, bool enabled = true,
float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, const ImVec2& text_align = ImVec2(0.0f, 0.0f));
float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
const ImVec2& text_align = ImVec2(0.0f, 0.0f));
bool MenuButtonWithValue(std::string_view title, std::string_view summary, std::string_view value, bool enabled = true,
float height = LAYOUT_MENU_BUTTON_HEIGHT);
bool MenuImageButton(std::string_view title, std::string_view summary, ImTextureID user_texture_id,
@ -344,6 +347,16 @@ ALWAYS_INLINE static bool EnumChoiceButton(std::string_view title, std::string_v
}
}
void BeginHorizontalMenuButtons(u32 num_items, float max_item_width = 0.0f,
float x_padding = LAYOUT_MENU_BUTTON_Y_PADDING,
float y_padding = LAYOUT_MENU_BUTTON_Y_PADDING,
float item_height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
float x_spacing = LAYOUT_MENU_BUTTON_X_PADDING,
float x_margin = LAYOUT_MENU_WINDOW_X_PADDING);
void EndHorizontalMenuButtons();
bool HorizontalMenuButton(std::string_view title, bool enabled = true,
const ImVec2& text_align = LAYOUT_CENTER_ALIGN_TEXT);
void BeginNavBar(float x_padding = LAYOUT_MENU_BUTTON_X_PADDING, float y_padding = LAYOUT_MENU_BUTTON_Y_PADDING);
void EndNavBar();
void NavTitle(std::string_view title, float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY);