diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp index 73b798ef6..260a9f221 100644 --- a/src/duckstation-qt/qthost.cpp +++ b/src/duckstation-qt/qthost.cpp @@ -1976,47 +1976,66 @@ bool Host::ConfirmMessage(std::string_view title, std::string_view message) QString::fromUtf8(message.data(), message.size())); } -void Host::ConfirmMessageAsync(std::string_view title, std::string_view message, ConfirmMessageAsyncCallback callback) +void Host::ConfirmMessageAsync(std::string_view title, std::string_view message, ConfirmMessageAsyncCallback callback, + std::string_view yes_text, std::string_view no_text) { INFO_LOG("ConfirmMessageAsync({}, {})", title, message); // This is a racey read, but whether FSUI is started should be visible on all threads. std::atomic_thread_fence(std::memory_order_acquire); + // Default button titles. + if (yes_text.empty()) + yes_text = TRANSLATE_SV("QtHost", "Yes"); + if (no_text.empty()) + no_text = TRANSLATE_SV("QtHost", "No"); + // Use FSUI to display the confirmation if it is active. if (FullscreenUI::IsInitialized()) { // This.. should not be a thing. if (!g_emu_thread->isCurrentThread()) { - Host::RunOnCPUThread( - [title = std::string(title), message = std::string(message), callback = std::move(callback)]() mutable { - ConfirmMessageAsync(title, message, std::move(callback)); - }); + Host::RunOnCPUThread([title = std::string(title), message = std::string(message), callback = std::move(callback), + yes_text = std::string(yes_text), no_text = std::string(no_text)]() mutable { + ConfirmMessageAsync(title, message, std::move(callback)); + }); return; } - GPUThread::RunOnThread( - [title = std::string(title), message = std::string(message), callback = std::move(callback)]() mutable { - if (!FullscreenUI::Initialize()) - { - callback(false); - return; - } + GPUThread::RunOnThread([title = std::string(title), message = std::string(message), callback = std::move(callback), + yes_text = std::string(yes_text), no_text = std::string(no_text)]() mutable { + if (!FullscreenUI::Initialize()) + { + callback(false); + return; + } - ImGuiFullscreen::OpenConfirmMessageDialog(std::move(title), std::move(message), std::move(callback), - fmt::format(ICON_FA_CHECK " {}", TRANSLATE_SV("QtHost", "Yes")), - fmt::format(ICON_FA_TIMES " {}", TRANSLATE_SV("QtHost", "No"))); - }); + ImGuiFullscreen::OpenConfirmMessageDialog(std::move(title), std::move(message), std::move(callback), + fmt::format(ICON_FA_CHECK " {}", yes_text), + fmt::format(ICON_FA_TIMES " {}", no_text)); + }); } else { // Otherwise, use the desktop UI. QtHost::RunOnUIThread([title = QtUtils::StringViewToQString(title), message = QtUtils::StringViewToQString(message), - callback = std::move(callback)]() mutable { + callback = std::move(callback), yes_text = QtUtils::StringViewToQString(yes_text), + no_text = QtUtils::StringViewToQString(no_text)]() mutable { auto lock = g_main_window->pauseAndLockSystem(); - const bool result = (QMessageBox::question(lock.getDialogParent(), title, message) != QMessageBox::No); + bool result; + { + QMessageBox msgbox(lock.getDialogParent()); + msgbox.setIcon(QMessageBox::Question); + msgbox.setWindowTitle(title); + msgbox.setText(message); + + QPushButton* const yes_button = msgbox.addButton(yes_text, QMessageBox::AcceptRole); + msgbox.addButton(no_text, QMessageBox::RejectRole); + msgbox.exec(); + result = (msgbox.clickedButton() == yes_button); + } callback(result); }); diff --git a/src/duckstation-regtest/regtest_host.cpp b/src/duckstation-regtest/regtest_host.cpp index ebdf74157..6b811f62c 100644 --- a/src/duckstation-regtest/regtest_host.cpp +++ b/src/duckstation-regtest/regtest_host.cpp @@ -162,7 +162,8 @@ bool Host::ConfirmMessage(std::string_view title, std::string_view message) return true; } -void Host::ConfirmMessageAsync(std::string_view title, std::string_view message, ConfirmMessageAsyncCallback callback) +void Host::ConfirmMessageAsync(std::string_view title, std::string_view message, ConfirmMessageAsyncCallback callback, + std::string_view yes_text, std::string_view no_text) { if (!title.empty() && !message.empty()) ERROR_LOG("ConfirmMessage: {}: {}", title, message); diff --git a/src/util/host.h b/src/util/host.h index d0258bfba..0b1fa348d 100644 --- a/src/util/host.h +++ b/src/util/host.h @@ -48,7 +48,8 @@ bool ConfirmMessage(std::string_view title, std::string_view message); /// Displays an asynchronous confirmation on the UI thread, but does not block the caller. /// The callback may be executed on a different thread. Use RunOnCPUThread() in the callback to ensure safety. using ConfirmMessageAsyncCallback = std::function; -void ConfirmMessageAsync(std::string_view title, std::string_view message, ConfirmMessageAsyncCallback callback); +void ConfirmMessageAsync(std::string_view title, std::string_view message, ConfirmMessageAsyncCallback callback, + std::string_view yes_text = std::string_view(), std::string_view no_text = std::string_view()); /// Returns the user agent to use for HTTP requests. std::string GetHTTPUserAgent();