diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp index d094b37e6..b60aa487b 100644 --- a/src/frontend-common/fullscreen_ui.cpp +++ b/src/frontend-common/fullscreen_ui.cpp @@ -60,6 +60,7 @@ using ImGuiFullscreen::EndFullscreenColumnWindow; using ImGuiFullscreen::EndFullscreenWindow; using ImGuiFullscreen::EndMenuButtons; using ImGuiFullscreen::EnumChoiceButton; +using ImGuiFullscreen::FloatingButton; using ImGuiFullscreen::LayoutScale; using ImGuiFullscreen::MenuButton; using ImGuiFullscreen::MenuButtonFrame; @@ -731,21 +732,20 @@ void DrawLandingWindow() s_host_interface->RequestExit(); { - bool about_visible, about_hovered, about_pressed; - ImRect about_rect; - ImGui::SetCursorPosY(ImGui::GetWindowHeight() - LayoutScale(50.0f)); - about_pressed = MenuButtonFrame("About", true, ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, - &about_visible, &about_hovered, &about_rect.Min, &about_rect.Max); - - if (about_visible) + ImVec2 fullscreen_pos; + if (FloatingButton(ICON_FA_WINDOW_CLOSE, 0.0f, 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, true, g_large_font, + &fullscreen_pos)) { - ImGui::PushFont(g_large_font); - ImGui::RenderTextClipped(about_rect.Min, about_rect.Max, ICON_FA_QUESTION_CIRCLE, nullptr, nullptr, - ImVec2(1.0f, 0.0f), &about_rect); - ImGui::PopFont(); + s_host_interface->RequestExit(); } - if (about_pressed) + if (FloatingButton(ICON_FA_EXPAND, fullscreen_pos.x, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f, true, g_large_font, + &fullscreen_pos)) + { + s_host_interface->RunLater([]() { s_host_interface->SetFullscreen(!s_host_interface->IsFullscreen()); }); + } + + if (FloatingButton(ICON_FA_QUESTION_CIRCLE, fullscreen_pos.x, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f)) OpenAboutWindow(); } @@ -2879,11 +2879,19 @@ void DrawAboutWindow() BeginMenuButtons(); if (ActiveButton(ICON_FA_GLOBE " GitHub Repository", false)) - s_host_interface->ReportError("Go to https://github.com/stenzek/duckstation/"); + { + s_host_interface->RunLater( + []() { s_host_interface->ReportError("Go to https://github.com/stenzek/duckstation/"); }); + } if (ActiveButton(ICON_FA_BUG " Issue Tracker", false)) - s_host_interface->ReportError("Go to https://github.com/stenzek/duckstation/issues"); + { + s_host_interface->RunLater( + []() { s_host_interface->ReportError("Go to https://github.com/stenzek/duckstation/issues"); }); + } if (ActiveButton(ICON_FA_COMMENT " Discord Server", false)) - s_host_interface->ReportError("Go to https://discord.gg/Buktv3t"); + { + s_host_interface->RunLater([]() { s_host_interface->ReportError("Go to https://discord.gg/Buktv3t"); }); + } if (ActiveButton(ICON_FA_WINDOW_CLOSE " Close", false)) { diff --git a/src/frontend-common/imgui_fullscreen.cpp b/src/frontend-common/imgui_fullscreen.cpp index 55ed715fb..7077df2bc 100644 --- a/src/frontend-common/imgui_fullscreen.cpp +++ b/src/frontend-common/imgui_fullscreen.cpp @@ -579,6 +579,91 @@ bool MenuImageButton(const char* title, const char* summary, ImTextureID user_te return pressed; } +bool FloatingButton(const char* text, float x, float y, float width, float height, float anchor_x, float anchor_y, + bool enabled, ImFont* font, ImVec2* out_position) +{ + const ImVec2 text_size(font->CalcTextSizeA(font->FontSize, std::numeric_limits::max(), 0.0f, text)); + const ImVec2& padding(ImGui::GetStyle().FramePadding); + if (width < 0.0f) + width = (padding.x * 2.0f) + text_size.x; + if (height < 0.0f) + height = (padding.y * 2.0f) + text_size.y; + + const ImVec2 window_size(ImGui::GetWindowSize()); + if (anchor_x == -1.0f) + x -= width; + else if (anchor_x == -0.5f) + x -= (width * 0.5f); + else if (anchor_x == 0.5f) + x = (window_size.x * 0.5f) - (width * 0.5f) - x; + else if (anchor_x == 1.0f) + x = window_size.x - width - x; + if (anchor_y == -1.0f) + y -= height; + else if (anchor_y == -0.5f) + y -= (height * 0.5f); + else if (anchor_y == 0.5f) + y = (window_size.y * 0.5f) - (height * 0.5f) - y; + else if (anchor_y == 1.0f) + y = window_size.y - height - y; + + if (out_position) + *out_position = ImVec2(x, y); + + ImGuiWindow* window = ImGui::GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImVec2 base(ImGui::GetWindowPos() + ImVec2(x, y)); + ImRect bb(base, base + ImVec2(width, height)); + + const ImGuiID id = window->GetID(text); + if (enabled) + { + if (!ImGui::ItemAdd(bb, id)) + return false; + } + else + { + if (ImGui::IsClippedEx(bb, id, false)) + return false; + } + + bool hovered; + bool held; + bool pressed; + if (enabled) + { + pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0); + if (hovered) + { + const ImU32 col = ImGui::GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered, 1.0f); + ImGui::RenderFrame(bb.Min, bb.Max, col, true, 0.0f); + } + } + else + { + hovered = false; + pressed = false; + held = false; + } + + bb.Min += padding; + bb.Max -= padding; + + if (!enabled) + ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled)); + + ImGui::PushFont(font); + ImGui::RenderTextClipped(bb.Min, bb.Max, text, nullptr, nullptr, ImVec2(0.0f, 0.0f), &bb); + ImGui::PopFont(); + + if (!enabled) + ImGui::PopStyleColor(); + + return pressed; +} + bool ToggleButton(const char* title, const char* summary, bool* v, bool enabled, float height, ImFont* font, ImFont* summary_font) { diff --git a/src/frontend-common/imgui_fullscreen.h b/src/frontend-common/imgui_fullscreen.h index 27f22de53..8a6665ca5 100644 --- a/src/frontend-common/imgui_fullscreen.h +++ b/src/frontend-common/imgui_fullscreen.h @@ -188,6 +188,9 @@ bool MenuImageButton(const char* title, const char* summary, ImTextureID user_te bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT, const ImVec2& uv0 = ImVec2(0.0f, 0.0f), const ImVec2& uv1 = ImVec2(1.0f, 1.0f), ImFont* font = g_large_font, ImFont* summary_font = g_medium_font); +bool FloatingButton(const char* text, float x, float y, float width = -1.0f, + float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, float anchor_x = 0.0f, float anchor_y = 0.0f, + bool enabled = true, ImFont* font = g_large_font, ImVec2* out_position = nullptr); bool ToggleButton(const char* title, const char* summary, bool* v, bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT, ImFont* font = g_large_font, ImFont* summary_font = g_medium_font);