88 lines
3.0 KiB
C++
88 lines
3.0 KiB
C++
#include "tools/cabana/ui/dialogs/messagebox.h"
|
|
|
|
#include <deque>
|
|
|
|
#include "imgui.h"
|
|
#include "imgui_internal.h"
|
|
#include "tools/cabana/ui/util.h"
|
|
|
|
namespace MessageBox {
|
|
|
|
namespace {
|
|
|
|
struct Box {
|
|
std::string title;
|
|
std::string text;
|
|
std::string detailed_text;
|
|
bool has_cancel = false;
|
|
std::function<void(bool)> on_result;
|
|
};
|
|
|
|
std::deque<Box> g_queue;
|
|
bool g_show_details = false;
|
|
PopupOwner g_owner;
|
|
|
|
void push(Box box) { g_queue.push_back(std::move(box)); }
|
|
|
|
std::function<void(bool)> wrap(std::function<void()> on_close) {
|
|
if (!on_close) return nullptr;
|
|
return [on_close = std::move(on_close)](bool) { on_close(); };
|
|
}
|
|
|
|
}
|
|
|
|
void information(const std::string &title, const std::string &text, std::function<void()> on_close) {
|
|
push({.title = title, .text = text, .on_result = wrap(std::move(on_close))});
|
|
}
|
|
|
|
void warning(const std::string &title, const std::string &text, const std::string &detailed_text,
|
|
std::function<void()> on_close) {
|
|
push({.title = title, .text = text, .detailed_text = detailed_text, .on_result = wrap(std::move(on_close))});
|
|
}
|
|
|
|
void question(const std::string &title, const std::string &text, std::function<void(bool)> on_result) {
|
|
push({.title = title, .text = text, .has_cancel = true, .on_result = std::move(on_result)});
|
|
}
|
|
|
|
void draw() {
|
|
if (g_queue.empty()) return;
|
|
Box &box = g_queue.front();
|
|
const std::string popup_id = box.title + "###MessageBox";
|
|
const bool first = g_owner.popup_id == 0;
|
|
if (!g_owner.begin(popup_id.c_str())) return;
|
|
|
|
const ImGuiStyle &style = ImGui::GetStyle();
|
|
const float min_width = ImGui::CalcTextSize(box.title.c_str()).x + style.FramePadding.x * 2 + style.WindowPadding.x * 2;
|
|
ImGui::SetNextWindowSizeConstraints(ImVec2(min_width, 0.0f), ImVec2(FLT_MAX, FLT_MAX));
|
|
setNextDialogWindow(ImVec2(0.0f, 0.0f));
|
|
if (!ImGui::BeginPopupModal(popup_id.c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) return;
|
|
if (first) g_show_details = false;
|
|
bool result = false, done = false;
|
|
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 480.0f);
|
|
ImGui::TextUnformatted(box.text.c_str());
|
|
ImGui::PopTextWrapPos();
|
|
if (g_show_details) {
|
|
ImGui::InputTextMultiline("##details", box.detailed_text.data(), box.detailed_text.size() + 1,
|
|
ImVec2(480.0f, 160.0f), ImGuiInputTextFlags_ReadOnly);
|
|
}
|
|
ImGui::Separator();
|
|
if (!box.detailed_text.empty()) {
|
|
|
|
if (ImGui::Button(g_show_details ? "Hide Details..." : "Show Details...")) g_show_details = !g_show_details;
|
|
ImGui::SameLine();
|
|
}
|
|
dialogButtons("OK", &result, &done, true, box.has_cancel ? "Cancel" : nullptr);
|
|
if (ImGui::IsKeyPressed(ImGuiKey_Enter, false) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter, false)) result = true;
|
|
if (result) done = true;
|
|
if (done) ImGui::CloseCurrentPopup();
|
|
ImGui::EndPopup();
|
|
if (done) {
|
|
g_owner.reset();
|
|
Box finished = std::move(g_queue.front());
|
|
g_queue.pop_front();
|
|
if (finished.on_result) finished.on_result(result);
|
|
}
|
|
}
|
|
|
|
}
|