From d56918e71dc69b4f36872f01b5738ec3171a9b7f Mon Sep 17 00:00:00 2001 From: Patrick Wuttke Date: Tue, 23 Sep 2025 11:14:33 +0200 Subject: [PATCH] Added some utility coroutines for showing message boxes. --- public/raid/imraid.hpp | 88 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/public/raid/imraid.hpp b/public/raid/imraid.hpp index a5d32e1..2082517 100644 --- a/public/raid/imraid.hpp +++ b/public/raid/imraid.hpp @@ -6,12 +6,14 @@ #include #include +#include #include #include #include #include #include +#include #include namespace ImRaid @@ -231,6 +233,92 @@ inline DataTableColumn MakeColumn(const char* header, const char* fmt, .comparator = [member](const TObject& left, const TObject& right) { return left.*member < right.*member; } }; } + +template +mijin::Task<> c_MessageBox(const char* titleId, TFunc&& renderFunc) +{ + ImGui::OpenPopup(titleId); + + bool open = true; + while (ImGui::BeginPopupModal(titleId, &open, ImGuiWindowFlags_NoResize)) + { + std::invoke(std::forward(renderFunc)); + ImGui::EndPopup(); + co_await mijin::c_suspend(); + } +} + +template +mijin::Task c_MessageBox(const char* titleId, std::span buttons, std::format_string format, TFormatArgs&&... formatArgs) +{ + const std::string message = std::format(format, std::forward(formatArgs)...); + int buttonIdx = -1; + + const ImGuiStyle& style = ImGui::GetStyle(); + float buttonsWidth = 0.f; + for (const char* button : buttons) { + buttonsWidth += ImGui::CalcTextSize(button).x; + } + buttonsWidth += static_cast(buttons.size()) * 2.f * style.FramePadding.x;; + buttonsWidth += static_cast(buttons.size() - 1) * style.ItemSpacing.x; + + co_await c_MessageBox(titleId, [&]() + { + ImGui::TextUnformatted(message.c_str()); + + const float offset = 0.5f * (ImGui::GetWindowWidth() - buttonsWidth); + ImGui::SetCursorPosX(offset); + for (int idx = 0; idx < static_cast(buttons.size()); ++idx) + { + if (idx != 0) { + ImGui::SameLine(); + } + if (ImGui::Button(buttons[idx])) + { + buttonIdx = idx; + ImGui::CloseCurrentPopup(); + } + } + }); + co_return buttonIdx; +} + +struct YesNo +{ + enum Value + { + YES, + NO + }; + Value value = Value::NO; + + constexpr YesNo() noexcept = default; + constexpr YesNo(const YesNo&) noexcept = default; + constexpr YesNo(Value value_) noexcept : value(value_) {} + + constexpr YesNo& operator=(const YesNo&) noexcept = default; + + constexpr auto operator<=>(const YesNo&) const noexcept = default; + + constexpr operator bool() const noexcept { return value == YES; } + constexpr bool operator!() const noexcept { return value == NO; } +}; + +template +mijin::Task c_MessageBoxYesNo(const char* titleId, std::format_string format, TFormatArgs&&... formatArgs) +{ + static std::array BUTTONS = {"Yes", "No"}; + const int idx = co_await c_MessageBox(titleId, BUTTONS, format, std::forward(formatArgs)...); + switch (idx) + { + case 0: + co_return YesNo::YES; + case 1: + co_return YesNo::NO; + default: + co_return DefaultResult; + } +} } // namespace ImRaid #endif // !defined(RAID_PUBLIC_RAID_IMRAID_HPP_INCLUDED)