mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-08 04:25:37 +00:00
FullscreenUI: Rewrite popup dialog handling
Add animations, fix background dimming.
This commit is contained in:
parent
576658b6eb
commit
0687e59bda
@ -82,6 +82,8 @@ using ImGuiFullscreen::FocusResetType;
|
||||
using ImGuiFullscreen::LAYOUT_FOOTER_HEIGHT;
|
||||
using ImGuiFullscreen::LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE;
|
||||
using ImGuiFullscreen::LAYOUT_LARGE_FONT_SIZE;
|
||||
using ImGuiFullscreen::LAYOUT_LARGE_POPUP_PADDING;
|
||||
using ImGuiFullscreen::LAYOUT_LARGE_POPUP_ROUNDING;
|
||||
using ImGuiFullscreen::LAYOUT_MEDIUM_FONT_SIZE;
|
||||
using ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT;
|
||||
using ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY;
|
||||
@ -89,10 +91,11 @@ using ImGuiFullscreen::LAYOUT_MENU_BUTTON_X_PADDING;
|
||||
using ImGuiFullscreen::LAYOUT_MENU_BUTTON_Y_PADDING;
|
||||
using ImGuiFullscreen::LAYOUT_SCREEN_HEIGHT;
|
||||
using ImGuiFullscreen::LAYOUT_SCREEN_WIDTH;
|
||||
using ImGuiFullscreen::LAYOUT_SMALL_POPUP_PADDING;
|
||||
using ImGuiFullscreen::UIStyle;
|
||||
|
||||
using ImGuiFullscreen::AddNotification;
|
||||
using ImGuiFullscreen::BeginFixedPopupModal;
|
||||
using ImGuiFullscreen::BeginFixedPopupDialog;
|
||||
using ImGuiFullscreen::BeginFullscreenColumns;
|
||||
using ImGuiFullscreen::BeginFullscreenColumnWindow;
|
||||
using ImGuiFullscreen::BeginFullscreenWindow;
|
||||
@ -101,8 +104,10 @@ using ImGuiFullscreen::BeginMenuButtons;
|
||||
using ImGuiFullscreen::BeginNavBar;
|
||||
using ImGuiFullscreen::CancelPendingMenuClose;
|
||||
using ImGuiFullscreen::CenterImage;
|
||||
using ImGuiFullscreen::CloseFixedPopupDialog;
|
||||
using ImGuiFullscreen::CloseFixedPopupDialogImmediately;
|
||||
using ImGuiFullscreen::DarkerColor;
|
||||
using ImGuiFullscreen::EndFixedPopupModal;
|
||||
using ImGuiFullscreen::EndFixedPopupDialog;
|
||||
using ImGuiFullscreen::EndFullscreenColumns;
|
||||
using ImGuiFullscreen::EndFullscreenColumnWindow;
|
||||
using ImGuiFullscreen::EndFullscreenWindow;
|
||||
@ -116,6 +121,8 @@ using ImGuiFullscreen::GetCachedTexture;
|
||||
using ImGuiFullscreen::GetCachedTextureAsync;
|
||||
using ImGuiFullscreen::GetPlaceholderTexture;
|
||||
using ImGuiFullscreen::HorizontalMenuItem;
|
||||
using ImGuiFullscreen::IsAnyFixedPopupDialogOpen;
|
||||
using ImGuiFullscreen::IsFixedPopupDialogOpen;
|
||||
using ImGuiFullscreen::IsFocusResetFromWindowChange;
|
||||
using ImGuiFullscreen::IsFocusResetQueued;
|
||||
using ImGuiFullscreen::IsGamepadInputSource;
|
||||
@ -137,6 +144,7 @@ using ImGuiFullscreen::NavTitle;
|
||||
using ImGuiFullscreen::OpenChoiceDialog;
|
||||
using ImGuiFullscreen::OpenConfirmMessageDialog;
|
||||
using ImGuiFullscreen::OpenFileSelector;
|
||||
using ImGuiFullscreen::OpenFixedPopupDialog;
|
||||
using ImGuiFullscreen::OpenInfoMessageDialog;
|
||||
using ImGuiFullscreen::OpenInputStringDialog;
|
||||
using ImGuiFullscreen::PopPrimaryColor;
|
||||
@ -226,7 +234,6 @@ static void DrawPauseMenu();
|
||||
static void ExitFullscreenAndOpenURL(std::string_view url);
|
||||
static void CopyTextToClipboard(std::string title, std::string_view text);
|
||||
static void DrawAboutWindow();
|
||||
static void OpenAboutWindow();
|
||||
static void FixStateIfPaused();
|
||||
static void GetStandardSelectionFooterText(SmallStringBase& dest, bool back_instead_of_cancel);
|
||||
|
||||
@ -430,7 +437,8 @@ struct SaveStateListEntry
|
||||
static void InitializePlaceholderSaveStateListEntry(SaveStateListEntry* li, s32 slot, bool global);
|
||||
static bool InitializeSaveStateListEntryFromSerial(SaveStateListEntry* li, const std::string& serial, s32 slot,
|
||||
bool global);
|
||||
static bool InitializeSaveStateListEntryFromPath(SaveStateListEntry* li, std::string path, s32 slot, bool global);
|
||||
static bool InitializeSaveStateListEntryFromPath(SaveStateListEntry* li, std::string path, s32 slot, bool global,
|
||||
std::string* media_path);
|
||||
static void ClearSaveStateEntryList();
|
||||
static u32 PopulateSaveStateListEntries(const std::string& serial,
|
||||
std::optional<ExtendedSaveStateInfo> undo_save_state);
|
||||
@ -492,6 +500,9 @@ static constexpr std::array s_theme_names = {
|
||||
static constexpr std::array s_theme_values = {"", "Dark", "Light", "AMOLED", "CobaltSky",
|
||||
"GreyMatter", "GreenGiant", "PinkyPals", "DarkRuby", "PurpleRain"};
|
||||
|
||||
static constexpr std::string_view RESUME_STATE_SELECTOR_DIALOG_NAME = "##resume_state_selector";
|
||||
static constexpr std::string_view ABOUT_DIALOG_NAME = "##about_duckstation";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// State
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -507,8 +518,6 @@ struct ALIGN_TO_CACHE_LINE UIState
|
||||
bool tried_to_initialize = false;
|
||||
bool pause_menu_was_open = false;
|
||||
bool was_paused_on_quick_menu_open = false;
|
||||
bool about_window_open = false;
|
||||
bool achievements_login_window_open = false;
|
||||
std::string current_game_title;
|
||||
std::string current_game_serial;
|
||||
std::string current_game_path;
|
||||
@ -562,7 +571,6 @@ struct ALIGN_TO_CACHE_LINE UIState
|
||||
s32 save_state_selector_submenu_index = -1;
|
||||
bool save_state_selector_open = false;
|
||||
bool save_state_selector_loading = true;
|
||||
bool save_state_selector_resuming = false;
|
||||
|
||||
// Lazily populated cover images.
|
||||
std::unordered_map<std::string, std::string> cover_image_map;
|
||||
@ -755,8 +763,8 @@ bool FullscreenUI::HasActiveWindow()
|
||||
|
||||
bool FullscreenUI::AreAnyDialogsOpen()
|
||||
{
|
||||
return (s_state.save_state_selector_open || s_state.about_window_open ||
|
||||
s_state.input_binding_type != InputBindingInfo::Type::Unknown || ImGuiFullscreen::IsChoiceDialogOpen() ||
|
||||
return (s_state.save_state_selector_open || s_state.input_binding_type != InputBindingInfo::Type::Unknown ||
|
||||
ImGuiFullscreen::IsAnyFixedPopupDialogOpen() || ImGuiFullscreen::IsChoiceDialogOpen() ||
|
||||
ImGuiFullscreen::IsInputDialogOpen() || ImGuiFullscreen::IsFileSelectorOpen() ||
|
||||
ImGuiFullscreen::IsMessageBoxDialogOpen());
|
||||
}
|
||||
@ -938,7 +946,6 @@ void FullscreenUI::Shutdown(bool clear_state)
|
||||
s_state.current_pause_submenu = PauseSubMenu::None;
|
||||
s_state.pause_menu_was_open = false;
|
||||
s_state.was_paused_on_quick_menu_open = false;
|
||||
s_state.about_window_open = false;
|
||||
|
||||
Achievements::ClearUIState();
|
||||
ClearInputBindingVariables();
|
||||
@ -1027,18 +1034,13 @@ void FullscreenUI::Render()
|
||||
break;
|
||||
}
|
||||
|
||||
if (s_state.save_state_selector_open)
|
||||
{
|
||||
if (s_state.save_state_selector_resuming)
|
||||
DrawResumeStateSelector();
|
||||
else
|
||||
DrawSaveStateSelector(s_state.save_state_selector_loading);
|
||||
}
|
||||
|
||||
if (s_state.about_window_open)
|
||||
if (IsFixedPopupDialogOpen(ABOUT_DIALOG_NAME))
|
||||
DrawAboutWindow();
|
||||
|
||||
if (s_state.input_binding_type != InputBindingInfo::Type::Unknown)
|
||||
else if (IsFixedPopupDialogOpen(RESUME_STATE_SELECTOR_DIALOG_NAME))
|
||||
DrawResumeStateSelector();
|
||||
else if (s_state.save_state_selector_open)
|
||||
DrawSaveStateSelector(s_state.save_state_selector_loading);
|
||||
else if (s_state.input_binding_type != InputBindingInfo::Type::Unknown)
|
||||
DrawInputBindingWindow();
|
||||
|
||||
ImGuiFullscreen::EndLayout();
|
||||
@ -1253,17 +1255,17 @@ void FullscreenUI::DoResume()
|
||||
return;
|
||||
}
|
||||
|
||||
SaveStateListEntry slentry;
|
||||
if (!InitializeSaveStateListEntryFromPath(&slentry, std::move(path), -1, false))
|
||||
return;
|
||||
|
||||
CloseSaveStateSelector();
|
||||
|
||||
SaveStateListEntry slentry;
|
||||
if (!InitializeSaveStateListEntryFromPath(&slentry, std::move(path), -1, false,
|
||||
&s_state.save_state_selector_game_path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_state.save_state_selector_slots.push_back(std::move(slentry));
|
||||
s_state.save_state_selector_game_path = {};
|
||||
s_state.save_state_selector_loading = true;
|
||||
s_state.save_state_selector_open = true;
|
||||
s_state.save_state_selector_resuming = true;
|
||||
QueueResetFocus(FocusResetType::PopupOpened);
|
||||
OpenFixedPopupDialog(RESUME_STATE_SELECTOR_DIALOG_NAME);
|
||||
}
|
||||
|
||||
void FullscreenUI::DoStartFile()
|
||||
@ -1969,7 +1971,7 @@ void FullscreenUI::DrawLandingWindow()
|
||||
if (!AreAnyDialogsOpen())
|
||||
{
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_GamepadBack, false) || ImGui::IsKeyPressed(ImGuiKey_F1, false))
|
||||
OpenAboutWindow();
|
||||
OpenFixedPopupDialog(ABOUT_DIALOG_NAME);
|
||||
else if (ImGui::IsKeyPressed(ImGuiKey_GamepadStart, false) || ImGui::IsKeyPressed(ImGuiKey_F3, false))
|
||||
DoResume();
|
||||
else if (ImGui::IsKeyPressed(ImGuiKey_NavGamepadMenu, false) || ImGui::IsKeyPressed(ImGuiKey_F11, false))
|
||||
@ -2323,6 +2325,9 @@ void FullscreenUI::ClearInputBindingVariables()
|
||||
s_state.input_binding_display_name = {};
|
||||
s_state.input_binding_new_bindings = {};
|
||||
s_state.input_binding_value_ranges = {};
|
||||
|
||||
if (IsFixedPopupDialogOpen(FSUI_ICONSTR(ICON_FA_GAMEPAD, "Set Input Binding")))
|
||||
CloseFixedPopupDialogImmediately();
|
||||
}
|
||||
|
||||
void FullscreenUI::BeginInputBinding(SettingsInterface* bsi, InputBindingInfo::Type type, std::string_view section,
|
||||
@ -2341,6 +2346,7 @@ void FullscreenUI::BeginInputBinding(SettingsInterface* bsi, InputBindingInfo::T
|
||||
s_state.input_binding_new_bindings = {};
|
||||
s_state.input_binding_value_ranges = {};
|
||||
s_state.input_binding_start_time = Timer::GetCurrentValue();
|
||||
OpenFixedPopupDialog(FSUI_ICONSTR(ICON_FA_GAMEPAD, "Set Input Binding"));
|
||||
|
||||
const bool game_settings = IsEditingGameSettings(bsi);
|
||||
|
||||
@ -2396,8 +2402,9 @@ void FullscreenUI::BeginInputBinding(SettingsInterface* bsi, InputBindingInfo::T
|
||||
bsi->SetStringValue(s_state.input_binding_section.c_str(), s_state.input_binding_key.c_str(),
|
||||
new_binding.c_str());
|
||||
SetSettingsChanged(bsi);
|
||||
ClearInputBindingVariables();
|
||||
QueueResetFocus(FocusResetType::PopupClosed);
|
||||
|
||||
GPUThread::RunOnThread(&CloseFixedPopupDialog);
|
||||
|
||||
return InputInterceptHook::CallbackResult::RemoveHookAndStopProcessingEvent;
|
||||
}
|
||||
|
||||
@ -2474,27 +2481,27 @@ void FullscreenUI::DrawInputBindingWindow()
|
||||
INPUT_BINDING_TIMEOUT_SECONDS -
|
||||
Timer::ConvertValueToSeconds(Timer::GetCurrentValue() - s_state.input_binding_start_time);
|
||||
if (time_remaining <= 0.0)
|
||||
{
|
||||
InputManager::RemoveHook();
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
|
||||
if (!BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 0.0f)))
|
||||
{
|
||||
InputManager::RemoveHook();
|
||||
ClearInputBindingVariables();
|
||||
QueueResetFocus(FocusResetType::PopupClosed);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* title = FSUI_ICONSTR(ICON_FA_GAMEPAD, "Set Input Binding");
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 0.0f));
|
||||
ImGui::OpenPopup(title);
|
||||
|
||||
if (BeginFixedPopupModal(title))
|
||||
{
|
||||
ImGui::TextWrapped("%s", SmallString::from_format(FSUI_FSTR("Setting {} binding {}."),
|
||||
s_state.input_binding_section, s_state.input_binding_display_name)
|
||||
ImGui::TextWrapped("%s", SmallString::from_format(FSUI_FSTR("Setting {} binding {}."), s_state.input_binding_section,
|
||||
s_state.input_binding_display_name)
|
||||
.c_str());
|
||||
ImGui::TextUnformatted(FSUI_CSTR("Push a controller button or axis now."));
|
||||
ImGui::NewLine();
|
||||
ImGui::TextUnformatted(SmallString::from_format(FSUI_FSTR("Timing out in {:.0f} seconds..."), time_remaining));
|
||||
EndFixedPopupModal();
|
||||
}
|
||||
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
|
||||
bool FullscreenUI::DrawToggleSetting(SettingsInterface* bsi, const char* title, const char* summary,
|
||||
@ -2661,18 +2668,18 @@ void FullscreenUI::DrawIntRangeSetting(SettingsInterface* bsi, const char* title
|
||||
value.has_value() ? SmallString::from_sprintf(format, value.value()) : SmallString(FSUI_VSTR("Use Global Setting"));
|
||||
|
||||
if (MenuButtonWithValue(title, summary, value_text.c_str(), enabled, height, font, summary_font))
|
||||
ImGui::OpenPopup(title);
|
||||
OpenFixedPopupDialog(title);
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 194.0f));
|
||||
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
|
||||
bool is_open = true;
|
||||
if (BeginFixedPopupModal(title, &is_open))
|
||||
if (!IsFixedPopupDialogOpen(title) ||
|
||||
!BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 194.0f)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
const float end = ImGui::GetCurrentWindow()->WorkRect.GetWidth();
|
||||
ImGui::SetNextItemWidth(end);
|
||||
ImGui::SetNextItemWidth(ImGui::GetCurrentWindow()->WorkRect.GetWidth());
|
||||
s32 dlg_value = static_cast<s32>(value.value_or(default_value));
|
||||
if (ImGui::SliderInt("##value", &dlg_value, min_value, max_value, format, ImGuiSliderFlags_NoInput))
|
||||
{
|
||||
@ -2688,12 +2695,11 @@ void FullscreenUI::DrawIntRangeSetting(SettingsInterface* bsi, const char* title
|
||||
if (MenuButtonWithoutSummary(FSUI_CSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, UIStyle.LargeFont,
|
||||
ImVec2(0.5f, 0.0f)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
}
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawFloatRangeSetting(SettingsInterface* bsi, const char* title, const char* summary,
|
||||
@ -2708,13 +2714,15 @@ void FullscreenUI::DrawFloatRangeSetting(SettingsInterface* bsi, const char* tit
|
||||
SmallString(FSUI_VSTR("Use Global Setting"));
|
||||
|
||||
if (MenuButtonWithValue(title, summary, value_text.c_str(), enabled, height, font, summary_font))
|
||||
ImGui::OpenPopup(title);
|
||||
OpenFixedPopupDialog(title);
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 194.0f));
|
||||
|
||||
bool is_open = true;
|
||||
if (BeginFixedPopupModal(title, &is_open))
|
||||
if (!IsFixedPopupDialogOpen(title) ||
|
||||
!BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 194.0f)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
const float end = ImGui::GetCurrentWindow()->WorkRect.GetWidth();
|
||||
@ -2737,12 +2745,11 @@ void FullscreenUI::DrawFloatRangeSetting(SettingsInterface* bsi, const char* tit
|
||||
if (MenuButtonWithoutSummary(FSUI_CSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, UIStyle.LargeFont,
|
||||
ImVec2(0.5f, 0.0f)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
}
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawFloatSpinBoxSetting(SettingsInterface* bsi, const char* title, const char* summary,
|
||||
@ -2760,15 +2767,17 @@ void FullscreenUI::DrawFloatSpinBoxSetting(SettingsInterface* bsi, const char* t
|
||||
|
||||
if (MenuButtonWithValue(title, summary, value_text.c_str(), enabled, height, font, summary_font))
|
||||
{
|
||||
ImGui::OpenPopup(title);
|
||||
OpenFixedPopupDialog(title);
|
||||
manual_input = false;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 194.0f));
|
||||
|
||||
bool is_open = true;
|
||||
if (BeginFixedPopupModal(title, &is_open))
|
||||
if (!IsFixedPopupDialogOpen(title) ||
|
||||
!BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 194.0f)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
float dlg_value = value.value_or(default_value) * multiplier;
|
||||
@ -2837,8 +2846,7 @@ void FullscreenUI::DrawFloatSpinBoxSetting(SettingsInterface* bsi, const char* t
|
||||
dlg_value_changed = true;
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(button_pos.y + (padding.y * 2.0f) +
|
||||
LayoutScale(LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY + 10.0f));
|
||||
ImGui::SetCursorPosY(button_pos.y + (padding.y * 2.0f) + LayoutScale(LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY + 10.0f));
|
||||
}
|
||||
|
||||
if (dlg_value_changed)
|
||||
@ -2855,12 +2863,11 @@ void FullscreenUI::DrawFloatSpinBoxSetting(SettingsInterface* bsi, const char* t
|
||||
if (MenuButtonWithoutSummary(FSUI_CSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, UIStyle.LargeFont,
|
||||
ImVec2(0.5f, 0.0f)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
}
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
|
||||
bool FullscreenUI::DrawIntRectSetting(SettingsInterface* bsi, const char* title, const char* summary,
|
||||
@ -2887,18 +2894,20 @@ bool FullscreenUI::DrawIntRectSetting(SettingsInterface* bsi, const char* title,
|
||||
TinyString(FSUI_VSTR("Default")));
|
||||
|
||||
if (MenuButtonWithValue(title, summary, value_text.c_str(), enabled, height, font, summary_font))
|
||||
ImGui::OpenPopup(title);
|
||||
OpenFixedPopupDialog(title);
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 370.0f));
|
||||
|
||||
bool is_open = true;
|
||||
bool changed = false;
|
||||
if (BeginFixedPopupModal(title, &is_open))
|
||||
if (!IsFixedPopupDialogOpen(title) ||
|
||||
!BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 370.0f)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
s32 dlg_left_value = static_cast<s32>(left_value.value_or(default_left));
|
||||
s32 dlg_top_value = static_cast<s32>(top_value.value_or(default_top));
|
||||
s32 dlg_right_value = static_cast<s32>(right_value.value_or(default_right));
|
||||
s32 dlg_bottom_value = static_cast<s32>(bottom_value.value_or(default_bottom));
|
||||
bool changed = false;
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
@ -2964,12 +2973,11 @@ bool FullscreenUI::DrawIntRectSetting(SettingsInterface* bsi, const char* title,
|
||||
if (MenuButtonWithoutSummary(FSUI_CSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, UIStyle.LargeFont,
|
||||
ImVec2(0.5f, 0.0f)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
}
|
||||
EndFixedPopupDialog();
|
||||
|
||||
return changed;
|
||||
}
|
||||
@ -2992,15 +3000,17 @@ void FullscreenUI::DrawIntSpinBoxSetting(SettingsInterface* bsi, const char* tit
|
||||
|
||||
if (MenuButtonWithValue(title, summary, value_text, enabled, height, font, summary_font))
|
||||
{
|
||||
ImGui::OpenPopup(title);
|
||||
OpenFixedPopupDialog(title);
|
||||
manual_input = false;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 194.0f));
|
||||
|
||||
bool is_open = true;
|
||||
if (BeginFixedPopupModal(title, &is_open))
|
||||
if (!IsFixedPopupDialogOpen(title) ||
|
||||
!BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 194.0f)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
s32 dlg_value = static_cast<s32>(value.value_or(default_value));
|
||||
@ -3063,8 +3073,7 @@ void FullscreenUI::DrawIntSpinBoxSetting(SettingsInterface* bsi, const char* tit
|
||||
dlg_value_changed = true;
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(button_pos.y + (padding.y * 2.0f) +
|
||||
LayoutScale(LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY + 10.0f));
|
||||
ImGui::SetCursorPosY(button_pos.y + (padding.y * 2.0f) + LayoutScale(LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY + 10.0f));
|
||||
}
|
||||
|
||||
if (dlg_value_changed)
|
||||
@ -3081,12 +3090,11 @@ void FullscreenUI::DrawIntSpinBoxSetting(SettingsInterface* bsi, const char* tit
|
||||
if (MenuButtonWithoutSummary(FSUI_CSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, UIStyle.LargeFont,
|
||||
ImVec2(0.5f, 0.0f)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
}
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
|
||||
[[maybe_unused]] void
|
||||
@ -4737,7 +4745,7 @@ void FullscreenUI::DrawControllerSettingsPage()
|
||||
"Determines the frequency at which the macro will toggle the buttons on and off (aka auto fire)."),
|
||||
freq_summary, true))
|
||||
{
|
||||
ImGui::OpenPopup(freq_label.c_str());
|
||||
OpenFixedPopupDialog(freq_label);
|
||||
}
|
||||
|
||||
DrawFloatSpinBoxSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROW_DOWN, "Pressure"),
|
||||
@ -4750,13 +4758,15 @@ void FullscreenUI::DrawControllerSettingsPage()
|
||||
section, TinyString::from_format("Macro{}Deadzone", macro_index + 1).c_str(), 0.0f, 0.00f,
|
||||
1.0f, 0.01f, 100.0f, "%.0f%%");
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 180.0f));
|
||||
|
||||
bool is_open = true;
|
||||
if (BeginFixedPopupModal(freq_label, &is_open))
|
||||
if (IsFixedPopupDialogOpen(freq_label) &&
|
||||
BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 194.0f)))
|
||||
{
|
||||
ImGui::SetNextItemWidth(LayoutScale(450.0f));
|
||||
if (ImGui::SliderInt("##value", &frequency, 0, 60, FSUI_CSTR("Toggle every %d frames"),
|
||||
BeginMenuButtons();
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetCurrentWindow()->WorkRect.GetWidth());
|
||||
if (ImGui::SliderInt("##value", &frequency, 0, 60,
|
||||
(frequency == 0) ? FSUI_CSTR("Disabled") : FSUI_CSTR("Toggle every %d frames"),
|
||||
ImGuiSliderFlags_NoInput))
|
||||
{
|
||||
if (frequency == 0)
|
||||
@ -4765,12 +4775,16 @@ void FullscreenUI::DrawControllerSettingsPage()
|
||||
bsi->SetIntValue(section.c_str(), freq_key.c_str(), frequency);
|
||||
}
|
||||
|
||||
BeginMenuButtons();
|
||||
if (MenuButton(FSUI_CSTR("OK"), nullptr, true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY))
|
||||
ImGui::CloseCurrentPopup();
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
|
||||
if (MenuButtonWithoutSummary(FSUI_CSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, UIStyle.LargeFont,
|
||||
ImVec2(0.5f, 0.0f)))
|
||||
{
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
}
|
||||
|
||||
@ -5573,34 +5587,16 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
|
||||
str.format(FSUI_FSTR("Value: {} | Default: {} | Minimum: {} | Maximum: {}"), opt.value[0].float_value,
|
||||
opt.default_value[0].float_value, opt.min_value[0].float_value, opt.max_value[0].float_value);
|
||||
if (MenuButton(tstr, str))
|
||||
ImGui::OpenPopup(tstr);
|
||||
OpenFixedPopupDialog(tstr);
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 194.0f));
|
||||
|
||||
bool is_open = true;
|
||||
if (BeginFixedPopupModal(tstr, &is_open))
|
||||
if (IsFixedPopupDialogOpen(tstr) &&
|
||||
BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 194.0f)))
|
||||
{
|
||||
BeginMenuButtons();
|
||||
|
||||
const float end = ImGui::GetCurrentWindow()->WorkRect.GetWidth();
|
||||
|
||||
#if 0
|
||||
for (u32 i = 0; i < opt.vector_size; i++)
|
||||
{
|
||||
static constexpr const char* components[] = { "X", "Y", "Z", "W" };
|
||||
if (opt.vector_size == 1)
|
||||
tstr.Assign("##value");
|
||||
else
|
||||
tstr.Fmt("{}##value{}", components[i], i);
|
||||
|
||||
ImGui::SetNextItemWidth(end);
|
||||
if (ImGui::SliderFloat(tstr, &opt.value[i].float_value, opt.min_value[i].float_value,
|
||||
opt.max_value[i].float_value, "%f", ImGuiSliderFlags_NoInput))
|
||||
{
|
||||
SavePostProcessingChain();
|
||||
}
|
||||
}
|
||||
#else
|
||||
ImGui::SetNextItemWidth(end);
|
||||
|
||||
bool changed = false;
|
||||
@ -5641,17 +5637,17 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
|
||||
SetSettingsChanged(bsi);
|
||||
reload_pending = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
|
||||
if (MenuButtonWithoutSummary(FSUI_CSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, UIStyle.LargeFont,
|
||||
ImVec2(0.5f, 0.0f)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -5662,34 +5658,15 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
|
||||
str.format(FSUI_FSTR("Value: {} | Default: {} | Minimum: {} | Maximum: {}"), opt.value[0].int_value,
|
||||
opt.default_value[0].int_value, opt.min_value[0].int_value, opt.max_value[0].int_value);
|
||||
if (MenuButton(tstr, str))
|
||||
ImGui::OpenPopup(tstr);
|
||||
OpenFixedPopupDialog(tstr);
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 194.0f));
|
||||
|
||||
bool is_open = true;
|
||||
if (BeginFixedPopupModal(tstr, &is_open))
|
||||
if (IsFixedPopupDialogOpen(tstr) &&
|
||||
BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 194.0f)))
|
||||
{
|
||||
BeginMenuButtons();
|
||||
|
||||
const float end = ImGui::GetCurrentWindow()->WorkRect.GetWidth();
|
||||
|
||||
#if 0
|
||||
for (u32 i = 0; i < opt.vector_size; i++)
|
||||
{
|
||||
static constexpr const char* components[] = { "X", "Y", "Z", "W" };
|
||||
if (opt.vector_size == 1)
|
||||
tstr.Assign("##value");
|
||||
else
|
||||
tstr.Fmt("{}##value{}", components[i], i);
|
||||
|
||||
ImGui::SetNextItemWidth(end);
|
||||
if (ImGui::SliderInt(tstr, &opt.value[i].int_value, opt.min_value[i].int_value,
|
||||
opt.max_value[i].int_value, "%d", ImGuiSliderFlags_NoInput))
|
||||
{
|
||||
SavePostProcessingChain();
|
||||
}
|
||||
}
|
||||
#else
|
||||
bool changed = false;
|
||||
ImGui::SetNextItemWidth(end);
|
||||
switch (opt.vector_size)
|
||||
@ -5729,17 +5706,16 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
|
||||
SetSettingsChanged(bsi);
|
||||
reload_pending = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
|
||||
if (MenuButtonWithoutSummary(FSUI_CSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, UIStyle.LargeFont,
|
||||
ImVec2(0.5f, 0.0f)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -6022,13 +5998,12 @@ void FullscreenUI::DrawAchievementsSettingsPage()
|
||||
{
|
||||
MenuButtonWithoutSummary(FSUI_ICONSTR(ICON_FA_USER, "Not Logged In"), false);
|
||||
|
||||
if (MenuButton(FSUI_ICONSTR(ICON_FA_KEY, "Login"), FSUI_CSTR("Logs in to RetroAchievements.")))
|
||||
{
|
||||
s_state.achievements_login_window_open = true;
|
||||
QueueResetFocus(FocusResetType::PopupOpened);
|
||||
}
|
||||
static constexpr std::string_view popup_title = "##achievements_login";
|
||||
|
||||
if (s_state.achievements_login_window_open)
|
||||
if (MenuButton(FSUI_ICONSTR(ICON_FA_KEY, "Login"), FSUI_CSTR("Logs in to RetroAchievements.")))
|
||||
OpenFixedPopupDialog(popup_title);
|
||||
|
||||
if (IsFixedPopupDialogOpen(popup_title))
|
||||
DrawAchievementsLoginWindow();
|
||||
}
|
||||
|
||||
@ -6065,26 +6040,29 @@ void FullscreenUI::DrawAchievementsLoginWindow()
|
||||
|
||||
static char username[256] = {};
|
||||
static char password[256] = {};
|
||||
static std::unique_ptr<std::string> login_error;
|
||||
|
||||
static constexpr auto actually_close_popup = []() {
|
||||
if (!BeginFixedPopupDialog(LayoutScale(LAYOUT_LARGE_POPUP_PADDING), LayoutScale(LAYOUT_LARGE_POPUP_ROUNDING),
|
||||
LayoutScale(600.0f, 0.0f)))
|
||||
{
|
||||
std::memset(username, 0, sizeof(username));
|
||||
std::memset(password, 0, sizeof(password));
|
||||
s_state.achievements_login_window_open = false;
|
||||
QueueResetFocus(FocusResetType::PopupClosed);
|
||||
};
|
||||
login_error.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(600.0f, 0.0f));
|
||||
|
||||
const char* popup_title = FSUI_ICONSTR(ICON_FA_KEY, "RetroAchievements Login");
|
||||
bool popup_closed = false;
|
||||
ImGui::OpenPopup(popup_title);
|
||||
if (BeginFixedPopupModal(popup_title, nullptr))
|
||||
{
|
||||
BeginMenuButtons();
|
||||
|
||||
if (!login_error)
|
||||
{
|
||||
ImGui::TextWrapped(
|
||||
FSUI_CSTR("Please enter your user name and password for retroachievements.org below. Your password will "
|
||||
"not be saved in DuckStation, an access token will be generated and used instead."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::TextWrapped("%s", login_error->c_str());
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
@ -6124,40 +6102,23 @@ void FullscreenUI::DrawAchievementsLoginWindow()
|
||||
|
||||
if (result)
|
||||
{
|
||||
actually_close_popup();
|
||||
CloseFixedPopupDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
// keep popup open on failure
|
||||
// because of the whole popup stack thing, we need to hide the dialog while this popup is visible
|
||||
s_state.achievements_login_window_open = false;
|
||||
ImGuiFullscreen::OpenInfoMessageDialog(
|
||||
FSUI_STR("Login Error"),
|
||||
login_error = std::make_unique<std::string>(
|
||||
fmt::format(FSUI_FSTR("Login Failed.\nError: {}\nPlease check your username and password, and try again."),
|
||||
error.GetDescription()),
|
||||
[]() {
|
||||
s_state.achievements_login_window_open = true;
|
||||
QueueResetFocus(FocusResetType::PopupOpened);
|
||||
},
|
||||
FSUI_ICONSTR(ICON_FA_TIMES, "Close"));
|
||||
error.GetDescription()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (MenuButtonWithoutSummary(FSUI_ICONSTR(ICON_FA_TIMES, "Cancel"), !is_logging_in))
|
||||
popup_closed = true;
|
||||
|
||||
popup_closed = popup_closed || (!is_logging_in && WantsToCloseMenu());
|
||||
if (popup_closed)
|
||||
ImGui::CloseCurrentPopup();
|
||||
CloseFixedPopupDialog();
|
||||
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
}
|
||||
|
||||
if (popup_closed)
|
||||
actually_close_popup();
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawAdvancedSettingsPage()
|
||||
@ -6324,12 +6285,11 @@ void FullscreenUI::DrawPatchesOrCheatsSettingsPage(bool cheats)
|
||||
constexpr s32 step_value = 1;
|
||||
|
||||
if (MenuButtonWithValue(title.c_str(), ci.description.c_str(), visible_value.c_str()))
|
||||
ImGui::OpenPopup(title);
|
||||
OpenFixedPopupDialog(title);
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(500.0f, 194.0f));
|
||||
|
||||
bool is_open = true;
|
||||
if (BeginFixedPopupModal(title, &is_open))
|
||||
if (IsFixedPopupDialogOpen(title) &&
|
||||
BeginFixedPopupDialog(LayoutScale(LAYOUT_SMALL_POPUP_PADDING), LayoutScale(LAYOUT_SMALL_POPUP_PADDING),
|
||||
LayoutScale(500.0f, 194.0f)))
|
||||
{
|
||||
BeginMenuButtons();
|
||||
|
||||
@ -6396,11 +6356,11 @@ void FullscreenUI::DrawPatchesOrCheatsSettingsPage(bool cheats)
|
||||
if (MenuButtonWithoutSummary(FSUI_CSTR("OK"), true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, UIStyle.LargeFont,
|
||||
ImVec2(0.5f, 0.0f)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
CloseFixedPopupDialog();
|
||||
}
|
||||
EndMenuButtons();
|
||||
|
||||
EndFixedPopupModal();
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -6776,7 +6736,7 @@ bool FullscreenUI::InitializeSaveStateListEntryFromSerial(SaveStateListEntry* li
|
||||
{
|
||||
const std::string path =
|
||||
(global ? System::GetGlobalSaveStateFileName(slot) : System::GetGameSaveStateFileName(serial, slot));
|
||||
if (!InitializeSaveStateListEntryFromPath(li, path.c_str(), slot, global))
|
||||
if (!InitializeSaveStateListEntryFromPath(li, path.c_str(), slot, global, nullptr))
|
||||
{
|
||||
InitializePlaceholderSaveStateListEntry(li, slot, global);
|
||||
return false;
|
||||
@ -6785,7 +6745,8 @@ bool FullscreenUI::InitializeSaveStateListEntryFromSerial(SaveStateListEntry* li
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FullscreenUI::InitializeSaveStateListEntryFromPath(SaveStateListEntry* li, std::string path, s32 slot, bool global)
|
||||
bool FullscreenUI::InitializeSaveStateListEntryFromPath(SaveStateListEntry* li, std::string path, s32 slot, bool global,
|
||||
std::string* media_path)
|
||||
{
|
||||
std::optional<ExtendedSaveStateInfo> ssi(System::GetExtendedSaveStateInfo(path.c_str()));
|
||||
if (!ssi.has_value())
|
||||
@ -6807,6 +6768,8 @@ bool FullscreenUI::InitializeSaveStateListEntryFromPath(SaveStateListEntry* li,
|
||||
li->global = global;
|
||||
if (ssi->screenshot.IsValid())
|
||||
li->preview_texture = g_gpu_device->FetchAndUploadTextureImage(ssi->screenshot);
|
||||
if (media_path)
|
||||
*media_path = std::move(ssi->media_path);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -6865,7 +6828,6 @@ void FullscreenUI::OpenSaveStateSelector(const std::string& serial, const std::s
|
||||
std::optional<ExtendedSaveStateInfo> undo_state = System::GetUndoSaveStateInfo();
|
||||
GPUThread::RunOnThread([serial = std::move(serial), undo_state = std::move(undo_state), is_loading]() mutable {
|
||||
s_state.save_state_selector_loading = is_loading;
|
||||
s_state.save_state_selector_resuming = false;
|
||||
s_state.save_state_selector_game_path = {};
|
||||
if (PopulateSaveStateListEntries(serial, std::move(undo_state)) > 0)
|
||||
{
|
||||
@ -6883,7 +6845,6 @@ void FullscreenUI::OpenSaveStateSelector(const std::string& serial, const std::s
|
||||
else
|
||||
{
|
||||
s_state.save_state_selector_loading = is_loading;
|
||||
s_state.save_state_selector_resuming = false;
|
||||
if (PopulateSaveStateListEntries(serial, std::nullopt) > 0)
|
||||
{
|
||||
s_state.save_state_selector_game_path = path;
|
||||
@ -6905,8 +6866,10 @@ void FullscreenUI::CloseSaveStateSelector()
|
||||
ClearSaveStateEntryList();
|
||||
s_state.save_state_selector_open = false;
|
||||
s_state.save_state_selector_loading = false;
|
||||
s_state.save_state_selector_resuming = false;
|
||||
s_state.save_state_selector_game_path = {};
|
||||
|
||||
if (IsFixedPopupDialogOpen(RESUME_STATE_SELECTOR_DIALOG_NAME))
|
||||
CloseFixedPopupDialogImmediately();
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawSaveStateSelector(bool is_loading)
|
||||
@ -7240,27 +7203,18 @@ bool FullscreenUI::OpenLoadStateSelectorForGameResume(const GameList::Entry* ent
|
||||
CloseSaveStateSelector();
|
||||
s_state.save_state_selector_slots.push_back(std::move(slentry));
|
||||
s_state.save_state_selector_game_path = entry->path;
|
||||
s_state.save_state_selector_loading = true;
|
||||
s_state.save_state_selector_open = true;
|
||||
s_state.save_state_selector_resuming = true;
|
||||
QueueResetFocus(FocusResetType::PopupOpened);
|
||||
OpenFixedPopupDialog(RESUME_STATE_SELECTOR_DIALOG_NAME);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawResumeStateSelector()
|
||||
{
|
||||
ImGui::SetNextWindowSize(LayoutScale(820.0f, 625.0f));
|
||||
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
ImGui::OpenPopup(FSUI_CSTR("Load Resume State"));
|
||||
|
||||
ImGui::PushFont(UIStyle.LargeFont);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(40.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(30.0f, 30.0f));
|
||||
|
||||
bool is_open = true;
|
||||
if (ImGui::BeginPopupModal(FSUI_CSTR("Load Resume State"), &is_open,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize))
|
||||
if (!BeginFixedPopupDialog(LayoutScale(30.0f), LayoutScale(40.0f), LayoutScale(820.0f, 625.0f)))
|
||||
{
|
||||
CloseSaveStateSelector();
|
||||
return;
|
||||
}
|
||||
|
||||
SaveStateListEntry& entry = s_state.save_state_selector_slots.front();
|
||||
SmallString time;
|
||||
TimeToPrintableString(&time, entry.timestamp);
|
||||
@ -7277,7 +7231,8 @@ void FullscreenUI::DrawResumeStateSelector()
|
||||
const ImRect image_bb(pos, pos + ImVec2(image_width, image_height));
|
||||
ImGui::GetWindowDrawList()->AddImage(
|
||||
static_cast<ImTextureID>(entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture().get()),
|
||||
image_bb.Min, image_bb.Max);
|
||||
image_bb.Min, image_bb.Max, ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f),
|
||||
ImGui::GetColorU32(IM_COL32(255, 255, 255, 255)));
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + image_height + LayoutScale(40.0f));
|
||||
|
||||
@ -7286,22 +7241,26 @@ void FullscreenUI::DrawResumeStateSelector()
|
||||
|
||||
if (MenuButtonWithoutSummary(FSUI_ICONSTR(ICON_FA_PLAY, "Load State")))
|
||||
{
|
||||
DoStartPath(s_state.save_state_selector_game_path, std::move(entry.path));
|
||||
is_open = false;
|
||||
std::string game_path = std::move(s_state.save_state_selector_game_path);
|
||||
std::string state_path = std::move(entry.path);
|
||||
CloseSaveStateSelector();
|
||||
DoStartPath(std::move(game_path), std::move(state_path));
|
||||
}
|
||||
|
||||
if (MenuButtonWithoutSummary(FSUI_ICONSTR(ICON_FA_LIGHTBULB, "Clean Boot")))
|
||||
{
|
||||
DoStartPath(s_state.save_state_selector_game_path);
|
||||
is_open = false;
|
||||
std::string game_path = std::move(s_state.save_state_selector_game_path);
|
||||
CloseSaveStateSelector();
|
||||
DoStartPath(std::move(game_path));
|
||||
}
|
||||
|
||||
if (MenuButtonWithoutSummary(FSUI_ICONSTR(ICON_FA_FOLDER_MINUS, "Delete State")))
|
||||
{
|
||||
if (FileSystem::DeleteFile(entry.path.c_str()))
|
||||
{
|
||||
DoStartPath(s_state.save_state_selector_game_path);
|
||||
is_open = false;
|
||||
std::string game_path = std::move(s_state.save_state_selector_game_path);
|
||||
CloseSaveStateSelector();
|
||||
DoStartPath(std::move(game_path));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -7309,32 +7268,14 @@ void FullscreenUI::DrawResumeStateSelector()
|
||||
}
|
||||
}
|
||||
|
||||
if (MenuButtonWithoutSummary(FSUI_ICONSTR(ICON_FA_WINDOW_CLOSE, "Cancel")) || WantsToCloseMenu())
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
is_open = false;
|
||||
}
|
||||
if (MenuButtonWithoutSummary(FSUI_ICONSTR(ICON_FA_WINDOW_CLOSE, "Cancel")))
|
||||
CloseFixedPopupDialog();
|
||||
|
||||
EndMenuButtons();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopFont();
|
||||
|
||||
if (!is_open)
|
||||
{
|
||||
ClearSaveStateEntryList();
|
||||
QueueResetFocus(FocusResetType::PopupClosed);
|
||||
s_state.save_state_selector_open = false;
|
||||
s_state.save_state_selector_loading = false;
|
||||
s_state.save_state_selector_resuming = false;
|
||||
s_state.save_state_selector_game_path = {};
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStandardSelectionFooterText(false);
|
||||
}
|
||||
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
|
||||
void FullscreenUI::DoLoadState(std::string path)
|
||||
@ -8409,11 +8350,6 @@ GPUTexture* FullscreenUI::GetCoverForCurrentGame()
|
||||
// Overlays
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void FullscreenUI::OpenAboutWindow()
|
||||
{
|
||||
s_state.about_window_open = true;
|
||||
}
|
||||
|
||||
void FullscreenUI::ExitFullscreenAndOpenURL(std::string_view url)
|
||||
{
|
||||
Host::RunOnCPUThread([url = std::string(url)]() {
|
||||
@ -8434,32 +8370,29 @@ void FullscreenUI::CopyTextToClipboard(std::string title, std::string_view text)
|
||||
|
||||
void FullscreenUI::DrawAboutWindow()
|
||||
{
|
||||
ImGui::SetNextWindowSize(LayoutScale(1020.0f, 590.0f));
|
||||
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
ImGui::OpenPopup(FSUI_CSTR("About DuckStation"));
|
||||
|
||||
ImGui::PushFont(UIStyle.LargeFont);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(40.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(30.0f, 30.0f));
|
||||
|
||||
if (ImGui::BeginPopupModal(FSUI_CSTR("About DuckStation"), &s_state.about_window_open,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize))
|
||||
if (!BeginFixedPopupDialog(LayoutScale(LAYOUT_LARGE_POPUP_PADDING), LayoutScale(LAYOUT_LARGE_POPUP_ROUNDING),
|
||||
LayoutScale(1020.0f, 590.0f)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ImVec2 image_size = LayoutScale(64.0f, 64.0f);
|
||||
const float indent = image_size.x + LayoutScale(8.0f);
|
||||
ImGui::GetWindowDrawList()->AddImage(s_state.app_icon_texture.get(), ImGui::GetCursorScreenPos(),
|
||||
ImGui::GetCursorScreenPos() + image_size);
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent);
|
||||
ImGui::TextUnformatted("DuckStation");
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, DarkerColor(UIStyle.BackgroundTextColor));
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent);
|
||||
ImGui::TextUnformatted(g_scm_tag_str);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::TextWrapped("%s", FSUI_CSTR("DuckStation is a free simulator/emulator of the Sony PlayStation(TM) "
|
||||
"console, focusing on playability, speed, and long-term maintainability."));
|
||||
ImGui::NewLine();
|
||||
ImGui::TextWrapped(
|
||||
"%s", FSUI_CSTR("Duck icon by icons8 (https://icons8.com/icon/74847/platforms.undefined.short-title)"));
|
||||
ImGui::TextWrapped("%s",
|
||||
FSUI_CSTR("Duck icon by icons8 (https://icons8.com/icon/74847/platforms.undefined.short-title)"));
|
||||
ImGui::NewLine();
|
||||
ImGui::TextWrapped(
|
||||
"%s", FSUI_CSTR("\"PlayStation\" and \"PSX\" are registered trademarks of Sony Interactive Entertainment Europe "
|
||||
@ -8476,22 +8409,13 @@ void FullscreenUI::DrawAboutWindow()
|
||||
ExitFullscreenAndOpenURL("https://github.com/stenzek/duckstation/blob/master/CONTRIBUTORS.md");
|
||||
|
||||
if (MenuButtonWithoutSummary(FSUI_ICONSTR(ICON_FA_WINDOW_CLOSE, "Close")) || WantsToCloseMenu())
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
s_state.about_window_open = false;
|
||||
}
|
||||
CloseFixedPopupDialog();
|
||||
else
|
||||
{
|
||||
SetStandardSelectionFooterText(true);
|
||||
}
|
||||
|
||||
EndMenuButtons();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopFont();
|
||||
EndFixedPopupDialog();
|
||||
}
|
||||
|
||||
void FullscreenUI::OpenAchievementsWindow()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -44,6 +44,9 @@ static constexpr float LAYOUT_HORIZONTAL_MENU_PADDING = 30.0f;
|
||||
static constexpr float LAYOUT_HORIZONTAL_MENU_ITEM_WIDTH = 250.0f;
|
||||
static constexpr float LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE = 150.0f;
|
||||
static constexpr float LAYOUT_SHADOW_OFFSET = 1.0f;
|
||||
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;
|
||||
|
||||
struct ALIGN_TO_CACHE_LINE UIStyles
|
||||
{
|
||||
@ -185,8 +188,16 @@ void UploadAsyncTextures();
|
||||
|
||||
void BeginLayout();
|
||||
void EndLayout();
|
||||
bool BeginFixedPopupModal(const char* name, bool* p_open = nullptr);
|
||||
void EndFixedPopupModal();
|
||||
|
||||
bool IsAnyFixedPopupDialogOpen();
|
||||
bool IsFixedPopupDialogOpen(std::string_view name);
|
||||
void OpenFixedPopupDialog(std::string_view name);
|
||||
void CloseFixedPopupDialog();
|
||||
void CloseFixedPopupDialogImmediately();
|
||||
bool BeginFixedPopupDialog(float scaled_window_padding = LayoutScale(20.0f),
|
||||
float scaled_window_rounding = LayoutScale(20.0f),
|
||||
const ImVec2& scaled_window_size = ImVec2(0.0f, 0.0f));
|
||||
void EndFixedPopupDialog();
|
||||
|
||||
void RenderOverlays();
|
||||
|
||||
@ -357,7 +368,7 @@ void CloseChoiceDialog();
|
||||
|
||||
using InputStringDialogCallback = std::function<void(std::string text)>;
|
||||
bool IsInputDialogOpen();
|
||||
void OpenInputStringDialog(std::string title, std::string message, std::string caption, std::string ok_button_text,
|
||||
void OpenInputStringDialog(std::string_view title, std::string message, std::string caption, std::string ok_button_text,
|
||||
InputStringDialogCallback callback);
|
||||
void CloseInputDialog();
|
||||
|
||||
@ -365,12 +376,12 @@ using ConfirmMessageDialogCallback = std::function<void(bool)>;
|
||||
using InfoMessageDialogCallback = std::function<void()>;
|
||||
using MessageDialogCallback = std::function<void(s32)>;
|
||||
bool IsMessageBoxDialogOpen();
|
||||
void OpenConfirmMessageDialog(std::string title, std::string message, ConfirmMessageDialogCallback callback,
|
||||
void OpenConfirmMessageDialog(std::string_view title, std::string message, ConfirmMessageDialogCallback callback,
|
||||
std::string yes_button_text = ICON_FA_CHECK " Yes",
|
||||
std::string no_button_text = ICON_FA_TIMES " No");
|
||||
void OpenInfoMessageDialog(std::string title, std::string message, InfoMessageDialogCallback callback = {},
|
||||
void OpenInfoMessageDialog(std::string_view title, std::string message, InfoMessageDialogCallback callback = {},
|
||||
std::string button_text = ICON_FA_WINDOW_CLOSE " Close");
|
||||
void OpenMessageDialog(std::string title, std::string message, MessageDialogCallback callback,
|
||||
void OpenMessageDialog(std::string_view title, std::string message, MessageDialogCallback callback,
|
||||
std::string first_button_text, std::string second_button_text, std::string third_button_text);
|
||||
void CloseMessageDialog();
|
||||
|
||||
@ -405,6 +416,46 @@ void ClearToast();
|
||||
void GetChoiceDialogHelpText(SmallStringBase& dest);
|
||||
void GetFileSelectorHelpText(SmallStringBase& dest);
|
||||
void GetInputDialogHelpText(SmallStringBase& dest);
|
||||
|
||||
// Wrapper for an animated popup dialog.
|
||||
class PopupDialog
|
||||
{
|
||||
public:
|
||||
PopupDialog();
|
||||
~PopupDialog();
|
||||
|
||||
ALWAYS_INLINE const std::string& GetTitle() const { return m_title; }
|
||||
ALWAYS_INLINE bool IsOpen() const { return (m_state != State::Inactive); }
|
||||
|
||||
void StartClose();
|
||||
void CloseImmediately();
|
||||
void ClearState();
|
||||
|
||||
protected:
|
||||
enum class State
|
||||
{
|
||||
Inactive,
|
||||
ClosingTrigger,
|
||||
Open,
|
||||
OpeningTrigger,
|
||||
Opening,
|
||||
Closing,
|
||||
};
|
||||
|
||||
static constexpr float OPEN_TIME = 0.2f;
|
||||
static constexpr float CLOSE_TIME = 0.1f;
|
||||
|
||||
void SetTitleAndOpen(std::string title);
|
||||
|
||||
bool BeginRender(float scaled_window_padding = LayoutScale(20.0f), float scaled_window_rounding = LayoutScale(20.0f),
|
||||
const ImVec2& scaled_window_size = ImVec2(0.0f, 0.0f));
|
||||
void EndRender();
|
||||
|
||||
std::string m_title;
|
||||
float m_animation_time_remaining = 0.0f;
|
||||
State m_state = State::Inactive;
|
||||
};
|
||||
|
||||
} // namespace ImGuiFullscreen
|
||||
|
||||
// Host UI triggers from Big Picture mode.
|
||||
|
Loading…
x
Reference in New Issue
Block a user