FullscreenUI: More animation fixes

This commit is contained in:
Stenzek 2024-08-26 17:56:47 +10:00
parent 46a6681159
commit 940200f7f3
No known key found for this signature in database
4 changed files with 88 additions and 68 deletions

View File

@ -12776,6 +12776,8 @@ static void ImGui::NavUpdateCancelRequest()
// Close open popup/menu // Close open popup/menu
ClosePopupToLevel(g.OpenPopupStack.Size - 1, true); ClosePopupToLevel(g.OpenPopupStack.Size - 1, true);
} }
#if 0
// DUCKSTATION-CHANGE: We want to keep nav active, since we handle menu exits ourselves.
else else
{ {
// Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were
@ -12783,6 +12785,7 @@ static void ImGui::NavUpdateCancelRequest()
g.NavWindow->NavLastIds[0] = 0; g.NavWindow->NavLastIds[0] = 0;
g.NavId = 0; g.NavId = 0;
} }
#endif
} }
// Handle PageUp/PageDown/Home/End keys // Handle PageUp/PageDown/Home/End keys

View File

@ -2482,8 +2482,8 @@ void Achievements::DrawAchievementsWindow()
TRANSLATE_NOOP("Achievements", "Active Challenges"), TRANSLATE_NOOP("Achievements", "Almost There"), TRANSLATE_NOOP("Achievements", "Active Challenges"), TRANSLATE_NOOP("Achievements", "Almost There"),
}; };
ImGuiFullscreen::BeginMenuButtons();
ImGuiFullscreen::ResetFocusHere(); ImGuiFullscreen::ResetFocusHere();
ImGuiFullscreen::BeginMenuButtons();
for (u32 bucket_type : {RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE, for (u32 bucket_type : {RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE,
RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED, RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED, RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED, RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED,
@ -2948,8 +2948,8 @@ void Achievements::DrawLeaderboardsWindow()
ImVec2(display_size.x, display_size.y - heading_height - LayoutScale(ImGuiFullscreen::LAYOUT_FOOTER_HEIGHT)), ImVec2(display_size.x, display_size.y - heading_height - LayoutScale(ImGuiFullscreen::LAYOUT_FOOTER_HEIGHT)),
"leaderboards", background, 0.0f, ImVec2(ImGuiFullscreen::LAYOUT_MENU_WINDOW_X_PADDING, 0.0f), 0)) "leaderboards", background, 0.0f, ImVec2(ImGuiFullscreen::LAYOUT_MENU_WINDOW_X_PADDING, 0.0f), 0))
{ {
ImGuiFullscreen::BeginMenuButtons();
ImGuiFullscreen::ResetFocusHere(); ImGuiFullscreen::ResetFocusHere();
ImGuiFullscreen::BeginMenuButtons();
for (u32 bucket_index = 0; bucket_index < s_leaderboard_list->num_buckets; bucket_index++) for (u32 bucket_index = 0; bucket_index < s_leaderboard_list->num_buckets; bucket_index++)
{ {
@ -2969,14 +2969,19 @@ void Achievements::DrawLeaderboardsWindow()
ImVec2(display_size.x, display_size.y - heading_height - LayoutScale(ImGuiFullscreen::LAYOUT_FOOTER_HEIGHT)), ImVec2(display_size.x, display_size.y - heading_height - LayoutScale(ImGuiFullscreen::LAYOUT_FOOTER_HEIGHT)),
"leaderboard", background, 0.0f, ImVec2(ImGuiFullscreen::LAYOUT_MENU_WINDOW_X_PADDING, 0.0f), 0)) "leaderboard", background, 0.0f, ImVec2(ImGuiFullscreen::LAYOUT_MENU_WINDOW_X_PADDING, 0.0f), 0))
{ {
// Defer focus reset until loading finishes.
if (!s_is_showing_all_leaderboard_entries ||
(ImGuiFullscreen::IsFocusResetFromWindowChange() && !s_leaderboard_entry_lists.empty()))
{
ImGuiFullscreen::ResetFocusHere();
}
ImGuiFullscreen::BeginMenuButtons(); ImGuiFullscreen::BeginMenuButtons();
if (!s_is_showing_all_leaderboard_entries) if (!s_is_showing_all_leaderboard_entries)
{ {
if (s_leaderboard_nearby_entries) if (s_leaderboard_nearby_entries)
{ {
ImGuiFullscreen::ResetFocusHere();
for (u32 i = 0; i < s_leaderboard_nearby_entries->num_entries; i++) for (u32 i = 0; i < s_leaderboard_nearby_entries->num_entries; i++)
{ {
DrawLeaderboardEntry(s_leaderboard_nearby_entries->entries[i], DrawLeaderboardEntry(s_leaderboard_nearby_entries->entries[i],
@ -2999,9 +3004,6 @@ void Achievements::DrawLeaderboardsWindow()
} }
else else
{ {
if (ImGuiFullscreen::IsFocusResetFromWindowChange() && !s_leaderboard_entry_lists.empty())
ImGuiFullscreen::ResetFocusHere();
for (const rc_client_leaderboard_entry_list_t* list : s_leaderboard_entry_lists) for (const rc_client_leaderboard_entry_list_t* list : s_leaderboard_entry_lists)
{ {
for (u32 i = 0; i < list->num_entries; i++) for (u32 i = 0; i < list->num_entries; i++)

View File

@ -5345,10 +5345,10 @@ void FullscreenUI::DrawPauseMenu()
3, // Achievements 3, // Achievements
}; };
ResetFocusHere();
BeginMenuButtons(submenu_item_count[static_cast<u32>(s_current_pause_submenu)], 1.0f, BeginMenuButtons(submenu_item_count[static_cast<u32>(s_current_pause_submenu)], 1.0f,
ImGuiFullscreen::LAYOUT_MENU_BUTTON_X_PADDING, ImGuiFullscreen::LAYOUT_MENU_BUTTON_Y_PADDING, ImGuiFullscreen::LAYOUT_MENU_BUTTON_X_PADDING, ImGuiFullscreen::LAYOUT_MENU_BUTTON_Y_PADDING,
ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY); ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY);
ResetFocusHere();
switch (s_current_pause_submenu) switch (s_current_pause_submenu)
{ {
@ -5617,6 +5617,7 @@ bool FullscreenUI::OpenSaveStateSelector(bool is_loading)
if (PopulateSaveStateListEntries(System::GetGameTitle(), System::GetGameSerial()) > 0) if (PopulateSaveStateListEntries(System::GetGameTitle(), System::GetGameSerial()) > 0)
{ {
s_save_state_selector_open = true; s_save_state_selector_open = true;
QueueResetFocus(FocusResetType::PopupOpened);
return true; return true;
} }
@ -5626,6 +5627,9 @@ bool FullscreenUI::OpenSaveStateSelector(bool is_loading)
void FullscreenUI::CloseSaveStateSelector() void FullscreenUI::CloseSaveStateSelector()
{ {
if (s_save_state_selector_open)
QueueResetFocus(FocusResetType::PopupClosed);
ClearSaveStateEntryList(); ClearSaveStateEntryList();
s_save_state_selector_open = false; s_save_state_selector_open = false;
s_save_state_selector_loading = false; s_save_state_selector_loading = false;
@ -5674,14 +5678,13 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::PushStyleColor(ImGuiCol_ChildBg, ModAlpha(UIPrimaryColor, 0.9f)); ImGui::PushStyleColor(ImGuiCol_ChildBg, ModAlpha(UIPrimaryColor, 0.9f));
bool closed = false;
bool was_close_not_back = false;
if (ImGui::BeginChild("state_titlebar", heading_size, false, ImGuiWindowFlags_NavFlattened)) if (ImGui::BeginChild("state_titlebar", heading_size, false, ImGuiWindowFlags_NavFlattened))
{ {
BeginNavBar(); BeginNavBar();
if (NavButton(ICON_FA_BACKWARD, true, true)) if (NavButton(ICON_FA_BACKWARD, true, true))
{ closed = true;
CloseSaveStateSelector();
ReturnToPreviousWindow();
}
NavTitle(is_loading ? FSUI_CSTR("Load State") : FSUI_CSTR("Save State")); NavTitle(is_loading ? FSUI_CSTR("Load State") : FSUI_CSTR("Save State"));
EndNavBar(); EndNavBar();
@ -5692,13 +5695,15 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::PushStyleColor(ImGuiCol_ChildBg, ModAlpha(UIBackgroundColor, 0.9f)); ImGui::PushStyleColor(ImGuiCol_ChildBg, ModAlpha(UIBackgroundColor, 0.9f));
ImGui::SetCursorPos(ImVec2(0.0f, heading_size.y)); ImGui::SetCursorPos(ImVec2(0.0f, heading_size.y));
bool closed = false; if (IsFocusResetFromWindowChange())
bool close_handled = false; ImGui::SetNextWindowScroll(ImVec2(0.0f, 0.0f));
if (s_save_state_selector_open &&
ImGui::BeginChild("state_list",
if (ImGui::BeginChild("state_list",
ImVec2(io.DisplaySize.x, io.DisplaySize.y - LayoutScale(LAYOUT_FOOTER_HEIGHT) - heading_size.y), ImVec2(io.DisplaySize.x, io.DisplaySize.y - LayoutScale(LAYOUT_FOOTER_HEIGHT) - heading_size.y),
false, ImGuiWindowFlags_NavFlattened)) false, ImGuiWindowFlags_NavFlattened))
{ {
ResetFocusHere();
BeginMenuButtons(); BeginMenuButtons();
const ImGuiStyle& style = ImGui::GetStyle(); const ImGuiStyle& style = ImGui::GetStyle();
@ -5723,9 +5728,6 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::SetCursorPos(ImVec2(start_x, 0.0f)); ImGui::SetCursorPos(ImVec2(start_x, 0.0f));
for (u32 i = 0; i < s_save_state_selector_slots.size();) for (u32 i = 0; i < s_save_state_selector_slots.size();)
{ {
if (i == 0)
ResetFocusHere();
SaveStateListEntry& entry = s_save_state_selector_slots[i]; SaveStateListEntry& entry = s_save_state_selector_slots[i];
if (static_cast<s32>(i) == s_save_state_selector_submenu_index) if (static_cast<s32>(i) == s_save_state_selector_submenu_index)
{ {
@ -5768,6 +5770,7 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
DoSaveState(entry.slot, entry.global); DoSaveState(entry.slot, entry.global);
closed = true; closed = true;
was_close_not_back = true;
} }
if (!entry.path.empty() && ActiveButton(FSUI_ICONSTR(ICON_FA_FOLDER_MINUS, "Delete Save"), false, true, if (!entry.path.empty() && ActiveButton(FSUI_ICONSTR(ICON_FA_FOLDER_MINUS, "Delete Save"), false, true,
@ -5785,10 +5788,15 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
removed = true; removed = true;
if (s_save_state_selector_slots.empty()) if (s_save_state_selector_slots.empty())
{
closed = true; closed = true;
was_close_not_back = true;
}
else else
{
is_open = false; is_open = false;
} }
}
else else
{ {
ShowToast({}, fmt::format(FSUI_FSTR("Failed to delete {}."), ImGuiFullscreen::RemoveHash(entry.title))); ShowToast({}, fmt::format(FSUI_FSTR("Failed to delete {}."), ImGuiFullscreen::RemoveHash(entry.title)));
@ -5808,19 +5816,8 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::EndPopup(); ImGui::EndPopup();
} }
// don't let the back button flow through to the main window if (!is_open)
if (WantsToCloseMenu())
{
close_handled = true;
is_open = false;
}
if (!is_open || closed)
{
s_save_state_selector_submenu_index = -1; s_save_state_selector_submenu_index = -1;
if (!closed)
QueueResetFocus(FocusResetType::ViewChanged);
}
ImGui::PopStyleColor(3); ImGui::PopStyleColor(3);
ImGui::PopStyleVar(3); ImGui::PopStyleVar(3);
@ -5896,6 +5893,7 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
DoSaveState(entry.slot, entry.global); DoSaveState(entry.slot, entry.global);
closed = true; closed = true;
was_close_not_back = true;
} }
else if (hovered && else if (hovered &&
(ImGui::IsItemClicked(ImGuiMouseButton_Right) || ImGui::IsKeyPressed(ImGuiKey_NavGamepadMenu, false) || (ImGui::IsItemClicked(ImGuiMouseButton_Right) || ImGui::IsKeyPressed(ImGuiKey_NavGamepadMenu, false) ||
@ -5929,18 +5927,6 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::EndPopup(); ImGui::EndPopup();
ImGui::PopStyleVar(5); ImGui::PopStyleVar(5);
if (closed)
{
CloseSaveStateSelector();
ReturnToMainWindow();
}
else if (!close_handled && WantsToCloseMenu())
{
CloseSaveStateSelector();
ReturnToPreviousWindow();
}
else
{
if (IsGamepadInputSource()) if (IsGamepadInputSource())
{ {
SetFullscreenFooterText(std::array{std::make_pair(ICON_PF_XBOX_DPAD, FSUI_VSTR("Select State")), SetFullscreenFooterText(std::array{std::make_pair(ICON_PF_XBOX_DPAD, FSUI_VSTR("Select State")),
@ -5956,6 +5942,14 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
std::make_pair(ICON_PF_F1, FSUI_VSTR("Delete State")), std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Load State")), std::make_pair(ICON_PF_F1, FSUI_VSTR("Delete State")), std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Load State")),
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Cancel"))}); std::make_pair(ICON_PF_ESC, FSUI_VSTR("Cancel"))});
} }
if (WantsToCloseMenu() || closed)
{
CloseSaveStateSelector();
if (was_close_not_back)
ReturnToMainWindow();
else if (s_current_main_window != MainWindowType::GameList)
ReturnToPreviousWindow();
} }
} }
@ -5971,6 +5965,7 @@ bool FullscreenUI::OpenLoadStateSelectorForGameResume(const GameList::Entry* ent
s_save_state_selector_loading = true; s_save_state_selector_loading = true;
s_save_state_selector_open = true; s_save_state_selector_open = true;
s_save_state_selector_resuming = true; s_save_state_selector_resuming = true;
QueueResetFocus(FocusResetType::PopupOpened);
return true; return true;
} }
@ -6313,6 +6308,9 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
const GameList::Entry* selected_entry = nullptr; const GameList::Entry* selected_entry = nullptr;
PopulateGameListEntryList(); PopulateGameListEntryList();
if (IsFocusResetFromWindowChange())
ImGui::SetNextWindowScroll(ImVec2(0.0f, 0.0f));
if (BeginFullscreenColumnWindow(0.0f, -530.0f, "game_list_entries")) if (BeginFullscreenColumnWindow(0.0f, -530.0f, "game_list_entries"))
{ {
const ImVec2 image_size(LayoutScale(LAYOUT_MENU_BUTTON_HEIGHT, LAYOUT_MENU_BUTTON_HEIGHT)); const ImVec2 image_size(LayoutScale(LAYOUT_MENU_BUTTON_HEIGHT, LAYOUT_MENU_BUTTON_HEIGHT));
@ -6509,6 +6507,9 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
void FullscreenUI::DrawGameGrid(const ImVec2& heading_size) void FullscreenUI::DrawGameGrid(const ImVec2& heading_size)
{ {
if (IsFocusResetFromWindowChange())
ImGui::SetNextWindowScroll(ImVec2(0.0f, 0.0f));
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (!BeginFullscreenWindow( if (!BeginFullscreenWindow(
ImVec2(0.0f, heading_size.y), ImVec2(0.0f, heading_size.y),

View File

@ -593,12 +593,17 @@ bool ImGuiFullscreen::ResetFocusHere()
if (ImGui::FindBlockingModal(window)) if (ImGui::FindBlockingModal(window))
return false; return false;
// Only fully reset the window on window change, that way setting page changes don't spend a frame without focus.
if (s_focus_reset_queued == FocusResetType::ViewChanged)
window->LastFrameActive = 0;
s_focus_reset_queued = FocusResetType::None; s_focus_reset_queued = FocusResetType::None;
// Set the flag that we drew an active/hovered item active for a frame, because otherwise there's one frame where
// there'll be no frame drawn, which will cancel the animation. Also set the appearing flag, so that the default
// focus set does actually go through.
if (!GImGui->NavDisableHighlight && GImGui->NavDisableMouseHover)
{
window->Appearing = true;
s_has_hovered_menu_item = s_had_hovered_menu_item;
}
ImGui::SetWindowFocus(); ImGui::SetWindowFocus();
ImGui::NavInitWindow(window, true); ImGui::NavInitWindow(window, true);
@ -613,8 +618,7 @@ bool ImGuiFullscreen::IsFocusResetQueued()
bool ImGuiFullscreen::IsFocusResetFromWindowChange() bool ImGuiFullscreen::IsFocusResetFromWindowChange()
{ {
return (s_focus_reset_queued != FocusResetType::None && s_focus_reset_queued != FocusResetType::PopupOpened && return (s_focus_reset_queued != FocusResetType::None && s_focus_reset_queued != FocusResetType::PopupClosed);
s_focus_reset_queued != FocusResetType::PopupClosed);
} }
ImGuiFullscreen::FocusResetType ImGuiFullscreen::GetQueuedFocusResetType() ImGuiFullscreen::FocusResetType ImGuiFullscreen::GetQueuedFocusResetType()
@ -2181,6 +2185,9 @@ void ImGuiFullscreen::CloseFileSelector()
if (!s_file_selector_open) if (!s_file_selector_open)
return; return;
if (ImGui::IsPopupOpen(s_file_selector_title.c_str(), 0))
ImGui::ClosePopupToLevel(GImGui->OpenPopupStack.Size - 1, true);
s_file_selector_open = false; s_file_selector_open = false;
s_file_selector_directory = false; s_file_selector_directory = false;
std::string().swap(s_file_selector_title); std::string().swap(s_file_selector_title);
@ -2220,8 +2227,8 @@ void ImGuiFullscreen::DrawFileSelector()
{ {
ImGui::PushStyleColor(ImGuiCol_Text, UIBackgroundTextColor); ImGui::PushStyleColor(ImGuiCol_Text, UIBackgroundTextColor);
BeginMenuButtons();
ResetFocusHere(); ResetFocusHere();
BeginMenuButtons();
if (!s_file_selector_current_directory.empty()) if (!s_file_selector_current_directory.empty())
{ {
@ -2319,6 +2326,9 @@ void ImGuiFullscreen::CloseChoiceDialog()
if (!s_choice_dialog_open) if (!s_choice_dialog_open)
return; return;
if (ImGui::IsPopupOpen(s_choice_dialog_title.c_str(), 0))
ImGui::ClosePopupToLevel(GImGui->OpenPopupStack.Size - 1, true);
s_choice_dialog_open = false; s_choice_dialog_open = false;
s_choice_dialog_checkable = false; s_choice_dialog_checkable = false;
std::string().swap(s_choice_dialog_title); std::string().swap(s_choice_dialog_title);
@ -2353,7 +2363,7 @@ void ImGuiFullscreen::DrawChoiceDialog()
ImGuiCond_Always, ImVec2(0.5f, 0.5f)); ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::OpenPopup(s_choice_dialog_title.c_str()); ImGui::OpenPopup(s_choice_dialog_title.c_str());
bool is_open = !WantsToCloseMenu(); bool is_open = true;
s32 choice = -1; s32 choice = -1;
if (ImGui::BeginPopupModal(s_choice_dialog_title.c_str(), &is_open, if (ImGui::BeginPopupModal(s_choice_dialog_title.c_str(), &is_open,
@ -2361,8 +2371,8 @@ void ImGuiFullscreen::DrawChoiceDialog()
{ {
ImGui::PushStyleColor(ImGuiCol_Text, UIBackgroundTextColor); ImGui::PushStyleColor(ImGuiCol_Text, UIBackgroundTextColor);
BeginMenuButtons();
ResetFocusHere(); ResetFocusHere();
BeginMenuButtons();
if (s_choice_dialog_checkable) if (s_choice_dialog_checkable)
{ {
@ -2400,15 +2410,13 @@ void ImGuiFullscreen::DrawChoiceDialog()
ImGui::EndPopup(); ImGui::EndPopup();
} }
else
{
is_open = false;
}
ImGui::PopStyleColor(3); ImGui::PopStyleColor(3);
ImGui::PopStyleVar(3); ImGui::PopStyleVar(3);
ImGui::PopFont(); ImGui::PopFont();
is_open &= !WantsToCloseMenu();
if (choice >= 0) if (choice >= 0)
{ {
const auto& option = s_choice_dialog_options[choice]; const auto& option = s_choice_dialog_options[choice];
@ -2526,6 +2534,9 @@ void ImGuiFullscreen::CloseInputDialog()
if (!s_input_dialog_open) if (!s_input_dialog_open)
return; return;
if (ImGui::IsPopupOpen(s_input_dialog_title.c_str(), 0))
ImGui::ClosePopupToLevel(GImGui->OpenPopupStack.Size - 1, true);
s_input_dialog_open = false; s_input_dialog_open = false;
s_input_dialog_title = {}; s_input_dialog_title = {};
s_input_dialog_message = {}; s_input_dialog_message = {};
@ -2589,6 +2600,9 @@ void ImGuiFullscreen::CloseMessageDialog()
if (!s_message_dialog_open) if (!s_message_dialog_open)
return; return;
if (ImGui::IsPopupOpen(s_message_dialog_title.c_str(), 0))
ImGui::ClosePopupToLevel(GImGui->OpenPopupStack.Size - 1, true);
s_message_dialog_open = false; s_message_dialog_open = false;
s_message_dialog_title = {}; s_message_dialog_title = {};
s_message_dialog_message = {}; s_message_dialog_message = {};
@ -2626,8 +2640,8 @@ void ImGuiFullscreen::DrawMessageDialog()
if (ImGui::BeginPopupModal(win_id, &is_open, flags)) if (ImGui::BeginPopupModal(win_id, &is_open, flags))
{ {
BeginMenuButtons();
ResetFocusHere(); ResetFocusHere();
BeginMenuButtons();
ImGui::TextWrapped("%s", s_message_dialog_message.c_str()); ImGui::TextWrapped("%s", s_message_dialog_message.c_str());
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(20.0f)); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(20.0f));