FullscreenUI: Add 'Toggle Pause Menu' hotkey

pull/3800/head
Stenzek 1 week ago
parent 5005991435
commit e0e6920234
No known key found for this signature in database

@ -142,6 +142,7 @@ struct Locals
MainWindowType current_main_window = MainWindowType::None;
PauseSubMenu current_pause_submenu = PauseSubMenu::None;
MainWindowType previous_main_window = MainWindowType::None;
MainWindowType toggled_main_window = MainWindowType::None;
bool initialized = false;
bool background_loaded = false;
bool was_paused_on_quick_menu_open = false;
@ -245,6 +246,7 @@ void FullscreenUI::OnSystemStarting()
BeginTransition(LONG_TRANSITION_TIME, []() {
ClearSaveStateEntryList();
s_locals.current_main_window = MainWindowType::None;
s_locals.toggled_main_window = MainWindowType::None;
QueueResetFocus(FocusResetType::ViewChanged);
UpdateRunIdleState();
});
@ -295,6 +297,7 @@ void FullscreenUI::OnSystemDestroyed()
s_locals.was_paused_on_quick_menu_open = false;
s_locals.current_pause_submenu = PauseSubMenu::None;
s_locals.toggled_main_window = MainWindowType::None;
ReturnToMainWindow(TransitionEffect::Fade, LONG_TRANSITION_TIME);
});
}
@ -314,9 +317,17 @@ void FullscreenUI::PauseAndOpenMenuFromCoreThread(void (*callback)())
return;
Initialize();
if (!CanCurrentMainWindowStack() || !SetPendingMainWindowSwitch())
if (!SetPendingMainWindowSwitch())
return;
// Explicit open actions supersede a menu which was hidden by PauseAndToggleMenuFromCoreThread().
if (s_locals.toggled_main_window != MainWindowType::None)
{
s_locals.toggled_main_window = MainWindowType::None;
s_locals.previous_main_window = MainWindowType::None;
s_locals.current_pause_submenu = PauseSubMenu::None;
}
s_locals.was_paused_on_quick_menu_open = was_paused;
callback();
});
@ -340,6 +351,76 @@ void FullscreenUI::OpenPauseMenu()
});
}
void FullscreenUI::PauseAndToggleMenuFromCoreThread(void (*open_callback)(), void (*restored_callback)(),
float transition_time)
{
DebugAssert(Host::IsOnCoreThread());
if (!System::IsValid())
return;
const bool was_paused = System::IsPaused();
VideoThread::RunOnThread([open_callback, restored_callback, transition_time, was_paused]() {
Initialize();
// Dialogs cannot be hidden safely, since doing so would leave their callbacks pending while the game is running.
// A pending switch means another action already owns the current transition.
if (AreAnyDialogsOpen() || !SetPendingMainWindowSwitch())
return;
// Hide the current window without disturbing the state it owns.
if (s_locals.current_main_window != MainWindowType::None)
{
s_locals.toggled_main_window = s_locals.current_main_window;
BeginTransition(TransitionEffect::ZoomOut, SHORT_TRANSITION_TIME, []() {
s_locals.current_main_window = MainWindowType::None;
s_locals.has_pending_window_switch = false;
UpdateRunIdleState();
FixStateIfPaused();
UnpauseForMenuClose();
});
return;
}
// Restore the hidden window, or invoke the requested open action when there is no saved window. Start the
// transition before requesting the pause so an extra frame does not display the pause icon.
s_locals.was_paused_on_quick_menu_open = was_paused;
const bool restoring = (s_locals.toggled_main_window != MainWindowType::None);
BeginTransition(TransitionEffect::ZoomIn, transition_time, [open_callback, restored_callback, restoring]() {
ForceKeyNavEnabled();
EnqueueSoundEffect(SFX_NAV_ACTIVATE);
if (restoring)
{
s_locals.current_main_window = std::exchange(s_locals.toggled_main_window, MainWindowType::None);
s_locals.has_pending_window_switch = false;
UpdateRunIdleState();
FixStateIfPaused();
if (restored_callback)
restored_callback();
}
else
{
open_callback();
}
});
if (!was_paused)
Host::RunOnCoreThread([]() { System::PauseSystem(true); });
});
}
void FullscreenUI::TogglePauseMenu()
{
PauseAndToggleMenuFromCoreThread(
[]() {
UpdateAchievementsPauseScreenInfo();
s_locals.current_pause_submenu = PauseSubMenu::None;
SwitchToMainWindow(MainWindowType::PauseMenu);
},
&UpdateAchievementsPauseScreenInfo);
}
void FullscreenUI::OpenCheatsMenu()
{
PauseAndOpenMenuFromCoreThread([]() {
@ -382,6 +463,7 @@ void FullscreenUI::ClosePauseMenu(TransitionEffect effect /*= TransitionEffect::
if (!VideoThread::HasGPUBackend())
return;
s_locals.toggled_main_window = MainWindowType::None;
BeginTransition(effect, transition_time, []() {
s_locals.current_pause_submenu = PauseSubMenu::None;
SwitchToMainWindow(MainWindowType::None);
@ -398,6 +480,7 @@ void FullscreenUI::ClosePauseMenuImmediately()
CancelTransition();
UnpauseForMenuClose();
s_locals.toggled_main_window = MainWindowType::None;
s_locals.current_pause_submenu = PauseSubMenu::None;
s_locals.has_pending_window_switch = false;
SwitchToMainWindow(MainWindowType::None);
@ -504,6 +587,7 @@ void FullscreenUI::ReturnToMainWindow(TransitionEffect effect, float transition_
{
BeginTransition(effect, transition_time, []() {
s_locals.previous_main_window = MainWindowType::None;
s_locals.toggled_main_window = MainWindowType::None;
s_locals.current_pause_submenu = PauseSubMenu::None;
s_locals.has_pending_window_switch = false;
@ -544,6 +628,7 @@ void FullscreenUI::Shutdown()
s_locals.current_main_window = MainWindowType::None;
s_locals.current_pause_submenu = PauseSubMenu::None;
s_locals.previous_main_window = MainWindowType::None;
s_locals.toggled_main_window = MainWindowType::None;
s_locals.was_paused_on_quick_menu_open = false;
s_locals.has_pending_window_switch = false;

@ -45,10 +45,11 @@ void UpdateRunIdleState();
#ifndef __ANDROID__
void OpenPauseMenu();
void TogglePauseMenu();
void OpenCheatsMenu();
void OpenDiscChangeMenu();
void OpenAchievementsWindow();
void OpenLeaderboardsWindow();
void ToggleAchievementsWindow();
void ToggleLeaderboardsWindow();
class BackgroundProgressCallback final : public ProgressCallback
{

@ -64,6 +64,8 @@ bool AreAnyDialogsOpen();
bool AreAnyDialogsInteractable();
void PauseAndOpenMenuFromCoreThread(void (*callback)());
void PauseAndToggleMenuFromCoreThread(void (*open_callback)(), void (*restored_callback)() = nullptr,
float transition_time = SHORT_TRANSITION_TIME);
void ClosePauseMenu(TransitionEffect effect = TransitionEffect::Fade, float transition_time = SHORT_TRANSITION_TIME);
void ClosePauseMenuImmediately();

@ -135,6 +135,13 @@ static constexpr const HotkeyInfo s_hotkey_list[] = {
FullscreenUI::OpenPauseMenu();
}},
{"TogglePauseMenu", TRANSLATE_NOOP("Hotkeys", "Interface"), TRANSLATE_NOOP("Hotkeys", "Toggle Pause Menu"),
[](InputButtonEvent event) {
if (event == InputButtonEvent::Released && System::CanPauseSystem(true))
FullscreenUI::TogglePauseMenu();
},
true},
{"OpenCheatsMenu", TRANSLATE_NOOP("Hotkeys", "Interface"), TRANSLATE_NOOP("Hotkeys", "Open Cheat Settings"),
[](InputButtonEvent event) {
if (event == InputButtonEvent::Released && System::CanPauseSystem(true))
@ -144,13 +151,13 @@ static constexpr const HotkeyInfo s_hotkey_list[] = {
{"OpenAchievements", TRANSLATE_NOOP("Hotkeys", "Interface"), TRANSLATE_NOOP("Hotkeys", "Open Achievement List"),
[](InputButtonEvent event) {
if (event == InputButtonEvent::Released && System::CanPauseSystem(true))
FullscreenUI::OpenAchievementsWindow();
FullscreenUI::ToggleAchievementsWindow();
}},
{"OpenLeaderboards", TRANSLATE_NOOP("Hotkeys", "Interface"), TRANSLATE_NOOP("Hotkeys", "Open Leaderboard List"),
[](InputButtonEvent event) {
if (event == InputButtonEvent::Released && System::CanPauseSystem(true))
FullscreenUI::OpenLeaderboardsWindow();
FullscreenUI::ToggleLeaderboardsWindow();
}},
{"Screenshot", TRANSLATE_NOOP("Hotkeys", "Interface"), TRANSLATE_NOOP("Hotkeys", "Save Screenshot"),

Loading…
Cancel
Save