From c54842830f4fd919a8efc8c799f04eab578099fd Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 2 Feb 2021 01:40:37 +1000 Subject: [PATCH] FullscreenUI: Support modal error/confirmation --- .../nogui_host_interface.cpp | 60 ++++++++++++ src/duckstation-nogui/nogui_host_interface.h | 4 + src/duckstation-nogui/sdl_host_interface.cpp | 51 ---------- src/duckstation-nogui/sdl_host_interface.h | 4 - src/frontend-common/fullscreen_ui.cpp | 94 +++++++++++++++++++ src/frontend-common/fullscreen_ui.h | 4 + 6 files changed, 162 insertions(+), 55 deletions(-) diff --git a/src/duckstation-nogui/nogui_host_interface.cpp b/src/duckstation-nogui/nogui_host_interface.cpp index ec16dacd2..1eef98412 100644 --- a/src/duckstation-nogui/nogui_host_interface.cpp +++ b/src/duckstation-nogui/nogui_host_interface.cpp @@ -392,6 +392,66 @@ void NoGUIHostInterface::Run() } } +void NoGUIHostInterface::ReportMessage(const char* message) +{ + Log_InfoPrint(message); + AddOSDMessage(message, 10.0f); +} + +void NoGUIHostInterface::ReportError(const char* message) +{ + Log_ErrorPrint(message); + + if (!m_display) + return; + + ImGui::EndFrame(); + + bool done = false; + while (!done) + { + RunCallbacks(); + PollAndUpdate(); + if (m_fullscreen_ui_enabled) + FullscreenUI::SetImGuiNavInputs(); + + ImGui::NewFrame(); + done = FullscreenUI::DrawErrorWindow(message); + ImGui::EndFrame(); + m_display->Render(); + } + + ImGui::NewFrame(); +} + +bool NoGUIHostInterface::ConfirmMessage(const char* message) +{ + Log_InfoPrintf("Confirm: %s", message); + + if (!m_display) + return true; + + ImGui::EndFrame(); + + bool done = false; + bool result = true; + while (!done) + { + RunCallbacks(); + PollAndUpdate(); + if (m_fullscreen_ui_enabled) + FullscreenUI::SetImGuiNavInputs(); + + ImGui::NewFrame(); + done = FullscreenUI::DrawConfirmWindow(message, &result); + ImGui::EndFrame(); + m_display->Render(); + } + + ImGui::NewFrame(); + return result; +} + void NoGUIHostInterface::RunLater(std::function callback) { std::unique_lock lock(m_queued_callbacks_lock); diff --git a/src/duckstation-nogui/nogui_host_interface.h b/src/duckstation-nogui/nogui_host_interface.h index 949779344..373f0dbbd 100644 --- a/src/duckstation-nogui/nogui_host_interface.h +++ b/src/duckstation-nogui/nogui_host_interface.h @@ -25,6 +25,10 @@ public: virtual void Shutdown() override; virtual void Run(); + void ReportMessage(const char* message) override; + void ReportError(const char* message) override; + bool ConfirmMessage(const char* message) override; + std::string GetStringSettingValue(const char* section, const char* key, const char* default_value = "") override; bool GetBoolSettingValue(const char* section, const char* key, bool default_value = false) override; int GetIntSettingValue(const char* section, const char* key, int default_value = 0) override; diff --git a/src/duckstation-nogui/sdl_host_interface.cpp b/src/duckstation-nogui/sdl_host_interface.cpp index 7859f28ea..0b19b662b 100644 --- a/src/duckstation-nogui/sdl_host_interface.cpp +++ b/src/duckstation-nogui/sdl_host_interface.cpp @@ -253,57 +253,6 @@ std::optional SDLHostInterface::GetHostKeyCode return static_cast(*code); } -void SDLHostInterface::ReportError(const char* message) -{ - const bool was_fullscreen = IsFullscreen(); - if (was_fullscreen) - SetFullscreen(false); - - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "DuckStation", message, m_window); - - if (was_fullscreen) - SetFullscreen(true); -} - -void SDLHostInterface::ReportMessage(const char* message) -{ - AddOSDMessage(message, 2.0f); -} - -bool SDLHostInterface::ConfirmMessage(const char* message) -{ - const bool was_fullscreen = IsFullscreen(); - if (was_fullscreen) - SetFullscreen(false); - - SDL_MessageBoxData mbd = {}; - mbd.flags = SDL_MESSAGEBOX_INFORMATION; - mbd.window = m_window; - mbd.title = "DuckStation"; - mbd.message = message; - mbd.numbuttons = 2; - - // Why the heck these are reversed I have no idea... - SDL_MessageBoxButtonData buttons[2] = {}; - buttons[1].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; - buttons[1].buttonid = 0; - buttons[1].text = "Yes"; - buttons[0].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; - buttons[0].buttonid = 1; - buttons[0].text = "No"; - mbd.buttons = buttons; - mbd.numbuttons = countof(buttons); - - int button_id = 0; - SDL_ShowMessageBox(&mbd, &button_id); - const bool result = (button_id == 0); - - if (was_fullscreen) - SetFullscreen(true); - - return result; -} - void SDLHostInterface::PollAndUpdate() { // Process SDL events before the controller interface can steal them. diff --git a/src/duckstation-nogui/sdl_host_interface.h b/src/duckstation-nogui/sdl_host_interface.h index 91f4b9934..3a9b44d77 100644 --- a/src/duckstation-nogui/sdl_host_interface.h +++ b/src/duckstation-nogui/sdl_host_interface.h @@ -12,10 +12,6 @@ public: const char* GetFrontendName() const override; - void ReportError(const char* message) override; - void ReportMessage(const char* message) override; - bool ConfirmMessage(const char* message) override; - bool Initialize() override; void Shutdown() override; diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp index 120b7e61f..8e8b1d82a 100644 --- a/src/frontend-common/fullscreen_ui.cpp +++ b/src/frontend-common/fullscreen_ui.cpp @@ -39,6 +39,8 @@ using ImGuiFullscreen::LAYOUT_LARGE_FONT_SIZE; using ImGuiFullscreen::LAYOUT_MEDIUM_FONT_SIZE; using ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT; using ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY; +using ImGuiFullscreen::LAYOUT_MENU_BUTTON_X_PADDING; +using ImGuiFullscreen::LAYOUT_MENU_BUTTON_Y_PADDING; using ImGuiFullscreen::LAYOUT_SCREEN_HEIGHT; using ImGuiFullscreen::LAYOUT_SCREEN_WIDTH; @@ -2762,6 +2764,98 @@ void DrawAboutWindow() ImGui::PopFont(); } +bool DrawErrorWindow(const char* message) +{ + bool is_open = true; + + ImGuiFullscreen::BeginLayout(); + + ImGui::SetNextWindowSize(LayoutScale(500.0f, 0.0f)); + ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f)); + ImGui::OpenPopup("ReportError"); + + ImGui::PushFont(g_large_font); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(10.0f, 10.0f)); + + if (ImGui::BeginPopupModal("ReportError", &is_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize)) + { + ImGui::SetCursorPos(LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING, LAYOUT_MENU_BUTTON_Y_PADDING)); + ImGui::TextWrapped(message); + ImGui::GetCurrentWindow()->DC.CursorPos.y += LayoutScale(5.0f); + + BeginMenuButtons(); + + if (ActiveButton(ICON_FA_WINDOW_CLOSE " Close", false)) + { + ImGui::CloseCurrentPopup(); + is_open = false; + } + EndMenuButtons(); + + ImGui::EndPopup(); + } + + ImGui::PopStyleVar(2); + ImGui::PopFont(); + + ImGuiFullscreen::EndLayout(); + return !is_open; +} + +bool DrawConfirmWindow(const char* message, bool* result) +{ + bool is_open = true; + + ImGuiFullscreen::BeginLayout(); + + ImGui::SetNextWindowSize(LayoutScale(500.0f, 0.0f)); + ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f)); + ImGui::OpenPopup("ConfirmMessage"); + + ImGui::PushFont(g_large_font); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(10.0f, 10.0f)); + + if (ImGui::BeginPopupModal("ConfirmMessage", &is_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize)) + { + ImGui::SetCursorPos(LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING, LAYOUT_MENU_BUTTON_Y_PADDING)); + ImGui::TextWrapped(message); + ImGui::GetCurrentWindow()->DC.CursorPos.y += LayoutScale(5.0f); + + BeginMenuButtons(); + + bool done = false; + + if (ActiveButton(ICON_FA_CHECK " Yes", false)) + { + *result = true; + done = true; + } + + if (ActiveButton(ICON_FA_TIMES " No", false)) + { + *result = false; + done = true; + } + if (done) + { + ImGui::CloseCurrentPopup(); + is_open = false; + } + + EndMenuButtons(); + + ImGui::EndPopup(); + } + + ImGui::PopStyleVar(2); + ImGui::PopFont(); + + ImGuiFullscreen::EndLayout(); + return !is_open; +} + ////////////////////////////////////////////////////////////////////////// // Debug Menu ////////////////////////////////////////////////////////////////////////// diff --git a/src/frontend-common/fullscreen_ui.h b/src/frontend-common/fullscreen_ui.h index 738a05773..b2b6e2668 100644 --- a/src/frontend-common/fullscreen_ui.h +++ b/src/frontend-common/fullscreen_ui.h @@ -47,6 +47,10 @@ void CloseQuickMenu(); void Shutdown(); void Render(); +// Returns true if the message has been dismissed. +bool DrawErrorWindow(const char* message); +bool DrawConfirmWindow(const char* message, bool* result); + void EnsureGameListLoaded(); Settings& GetSettingsCopy();