system/msgdialog: callback available to be used by host

This commit is contained in:
Vinicius Rangel 2024-10-18 18:35:38 -03:00
parent 92b9903467
commit 015550384c
No known key found for this signature in database
GPG Key ID: A5B154D904B761D9
2 changed files with 45 additions and 14 deletions

View File

@ -238,11 +238,21 @@ void MsgDialogUi::Finish(ButtonId buttonId, Result r) {
} }
if (status) { if (status) {
*status = Status::FINISHED; *status = Status::FINISHED;
if (callback.has_value()) {
callback.value()(DialogResult{
.result = r,
.buttonId = buttonId,
});
}
} }
state = nullptr; state = nullptr;
status = nullptr; status = nullptr;
result = nullptr; result = nullptr;
RemoveLayer(this); RemoveLayer(this);
if (self_destruct) {
self_destruct = false;
delete this;
}
} }
void MsgDialogUi::Draw() { void MsgDialogUi::Draw() {
@ -282,19 +292,24 @@ void MsgDialogUi::Draw() {
first_render = false; first_render = false;
} }
DialogResult Libraries::MsgDialog::ShowMsgDialog(MsgDialogState p_state, bool block) { void Libraries::MsgDialog::ShowMsgDialog(
static DialogResult result{}; MsgDialogState p_state, bool block, std::optional<std::function<void(DialogResult)>> callback) {
static Status status; auto status = new Status{Status::RUNNING};
static MsgDialogUi dialog; auto state = new MsgDialogState{std::move(p_state)};
static MsgDialogState state; auto dialog = new MsgDialogUi(state, status, nullptr);
dialog = MsgDialogUi{}; bool running = true;
status = Status::RUNNING; dialog->SetSelfDestruct();
state = std::move(p_state); dialog->SetCallback([&, status, state, callback = std::move(callback)](auto result) {
dialog = MsgDialogUi(&state, &status, &result); running = false;
delete status;
delete state;
if (callback.has_value()) {
callback.value()(result);
}
});
if (block) { if (block) {
while (status == Status::RUNNING) { while (running) {
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
} }
return result;
} }

View File

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <optional>
#include <string> #include <string>
#include <variant> #include <variant>
@ -11,6 +12,8 @@
#include "core/libraries/system/commondialog.h" #include "core/libraries/system/commondialog.h"
#include "imgui/imgui_layer.h" #include "imgui/imgui_layer.h"
#include <functional>
namespace Libraries::MsgDialog { namespace Libraries::MsgDialog {
using OrbisUserServiceUserId = s32; using OrbisUserServiceUserId = s32;
@ -157,6 +160,10 @@ class MsgDialogUi final : public ImGui::Layer {
CommonDialog::Status* status{}; CommonDialog::Status* status{};
DialogResult* result{}; DialogResult* result{};
// HOST ONLY
bool self_destruct{false};
std::optional<std::function<void(DialogResult)>> callback;
void DrawUser(); void DrawUser();
void DrawProgressBar(); void DrawProgressBar();
void DrawSystemMessage(); void DrawSystemMessage();
@ -169,13 +176,22 @@ public:
MsgDialogUi(MsgDialogUi&& other) noexcept; MsgDialogUi(MsgDialogUi&& other) noexcept;
MsgDialogUi& operator=(MsgDialogUi other); MsgDialogUi& operator=(MsgDialogUi other);
void SetSelfDestruct() {
self_destruct = true;
}
void SetCallback(std::function<void(DialogResult)> callback) {
this->callback = std::move(callback);
}
void Finish(ButtonId buttonId, CommonDialog::Result r = CommonDialog::Result::OK); void Finish(ButtonId buttonId, CommonDialog::Result r = CommonDialog::Result::OK);
void Draw() override; void Draw() override;
}; };
// Utility function to show a message dialog // Utility function to show a message dialog from host code
// !!! This function can block !!! // callback is called from the present thread
DialogResult ShowMsgDialog(MsgDialogState state, bool block = true); void ShowMsgDialog(MsgDialogState state, bool block = false,
std::optional<std::function<void(DialogResult)>> callback = std::nullopt);
}; // namespace Libraries::MsgDialog }; // namespace Libraries::MsgDialog