FullscreenUI: Support modal error/confirmation

This commit is contained in:
Connor McLaughlin 2021-02-02 01:40:37 +10:00
parent 626b2ecec1
commit c54842830f
6 changed files with 162 additions and 55 deletions

View file

@ -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<void()> callback) void NoGUIHostInterface::RunLater(std::function<void()> callback)
{ {
std::unique_lock<std::mutex> lock(m_queued_callbacks_lock); std::unique_lock<std::mutex> lock(m_queued_callbacks_lock);

View file

@ -25,6 +25,10 @@ public:
virtual void Shutdown() override; virtual void Shutdown() override;
virtual void Run(); 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; 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; 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; int GetIntSettingValue(const char* section, const char* key, int default_value = 0) override;

View file

@ -253,57 +253,6 @@ std::optional<CommonHostInterface::HostKeyCode> SDLHostInterface::GetHostKeyCode
return static_cast<HostKeyCode>(*code); return static_cast<HostKeyCode>(*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() void SDLHostInterface::PollAndUpdate()
{ {
// Process SDL events before the controller interface can steal them. // Process SDL events before the controller interface can steal them.

View file

@ -12,10 +12,6 @@ public:
const char* GetFrontendName() const override; 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; bool Initialize() override;
void Shutdown() override; void Shutdown() override;

View file

@ -39,6 +39,8 @@ using ImGuiFullscreen::LAYOUT_LARGE_FONT_SIZE;
using ImGuiFullscreen::LAYOUT_MEDIUM_FONT_SIZE; using ImGuiFullscreen::LAYOUT_MEDIUM_FONT_SIZE;
using ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT; using ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT;
using ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY; 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_HEIGHT;
using ImGuiFullscreen::LAYOUT_SCREEN_WIDTH; using ImGuiFullscreen::LAYOUT_SCREEN_WIDTH;
@ -2762,6 +2764,98 @@ void DrawAboutWindow()
ImGui::PopFont(); 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 // Debug Menu
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View file

@ -47,6 +47,10 @@ void CloseQuickMenu();
void Shutdown(); void Shutdown();
void Render(); void Render();
// Returns true if the message has been dismissed.
bool DrawErrorWindow(const char* message);
bool DrawConfirmWindow(const char* message, bool* result);
void EnsureGameListLoaded(); void EnsureGameListLoaded();
Settings& GetSettingsCopy(); Settings& GetSettingsCopy();