impr: Make unsaved changes popup behave more like in other applications
This commit is contained in:
parent
7ec245925a
commit
fd61e757f0
@ -3,7 +3,7 @@
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
void openProject();
|
||||
void saveProject();
|
||||
void saveProjectAs();
|
||||
bool saveProject();
|
||||
bool saveProjectAs();
|
||||
|
||||
}
|
||||
|
@ -11,10 +11,10 @@ namespace hex::plugin::builtin {
|
||||
|
||||
class PopupUnsavedChanges : public Popup<PopupUnsavedChanges> {
|
||||
public:
|
||||
PopupUnsavedChanges(std::string message, std::function<void()> yesFunction, std::function<void()> noFunction)
|
||||
PopupUnsavedChanges(std::string message, std::function<void()> yesFunction, std::function<void()> noFunction, std::function<void()> cancelFunction)
|
||||
: hex::Popup<PopupUnsavedChanges>("hex.ui.common.question", false),
|
||||
m_message(std::move(message)),
|
||||
m_yesFunction(std::move(yesFunction)), m_noFunction(std::move(noFunction)) { }
|
||||
m_yesFunction(std::move(yesFunction)), m_noFunction(std::move(noFunction)), m_cancelFunction(std::move(cancelFunction)) { }
|
||||
|
||||
void drawContent() override {
|
||||
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
|
||||
@ -33,17 +33,23 @@ namespace hex::plugin::builtin {
|
||||
ImGui::Separator();
|
||||
|
||||
auto width = ImGui::GetWindowWidth();
|
||||
ImGui::SetCursorPosX(width / 9);
|
||||
if (ImGui::Button("hex.ui.common.yes"_lang, ImVec2(width / 3, 0))) {
|
||||
ImGui::SetCursorPosX((width / 10) * 0.5);
|
||||
if (ImGui::Button("hex.ui.common.yes"_lang, ImVec2(width / 4, 0))) {
|
||||
m_yesFunction();
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(width / 9 * 5);
|
||||
if (ImGui::Button("hex.ui.common.no"_lang, ImVec2(width / 3, 0)) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
ImGui::SetCursorPosX((width / 10) * 3.75);
|
||||
if (ImGui::Button("hex.ui.common.no"_lang, ImVec2(width / 4, 0)) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
m_noFunction();
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX((width / 10) * 7);
|
||||
if (ImGui::Button("hex.ui.common.cancel"_lang, ImVec2(width / 4, 0)) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
m_cancelFunction();
|
||||
this->close();
|
||||
}
|
||||
|
||||
ImGui::SetWindowPos((ImHexApi::System::getMainWindowSize() - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
}
|
||||
@ -62,7 +68,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
std::function<void()> m_yesFunction, m_noFunction;
|
||||
std::function<void()> m_yesFunction, m_noFunction, m_cancelFunction;
|
||||
};
|
||||
|
||||
}
|
@ -360,7 +360,7 @@
|
||||
"hex.builtin.oobe.tutorial_question": "Da dies das erste mal ist das du ImHex verwendest, möchtest du das Tutorial starten?",
|
||||
"hex.builtin.popup.blocking_task.desc": "Ein Task ist immer noch im Hintergrund am laufen.",
|
||||
"hex.builtin.popup.blocking_task.title": "Laufender Task",
|
||||
"hex.builtin.popup.close_provider.desc": "Es wurden ungespeicherte Änderungen an einem oder mehreren Provider vorgenommen.\nBist du sicher, dass du diese schliessen willst?",
|
||||
"hex.builtin.popup.close_provider.desc": "Einige Änderungen wurden noch nicht in einem Projekt gespeichert\nMöchtest du diese vor dem schliessen sichern?",
|
||||
"hex.builtin.popup.close_provider.title": "Provider schliessen?",
|
||||
"hex.builtin.popup.create_workspace.desc": "Gib einen Namen für den neuen Arbeitsbereich ein",
|
||||
"hex.builtin.popup.create_workspace.title": "Arbeitsbereich erstellen",
|
||||
|
@ -354,7 +354,7 @@
|
||||
"hex.builtin.nodes.visualizer.image_rgba.header": "RGBA8 Image Visualizer",
|
||||
"hex.builtin.nodes.visualizer.layered_dist": "Layered Distribution",
|
||||
"hex.builtin.nodes.visualizer.layered_dist.header": "Layered Distribution",
|
||||
"hex.builtin.popup.close_provider.desc": "There are unsaved changes made to one or more Providers\nthat haven't been saved to a Project yet.\n\nAre you sure you want to close them?",
|
||||
"hex.builtin.popup.close_provider.desc": "Some changes haven't been saved to a Project yet.\n\nDo you want to save them before closing?",
|
||||
"hex.builtin.popup.close_provider.title": "Close Provider?",
|
||||
"hex.builtin.popup.docs_question.title": "Documentation query",
|
||||
"hex.builtin.popup.docs_question.no_answer": "The documentation didn't have an answer for this question",
|
||||
|
@ -359,7 +359,7 @@
|
||||
"hex.builtin.oobe.tutorial_question": "",
|
||||
"hex.builtin.popup.blocking_task.desc": "현재 작업을 실행 중입니다.",
|
||||
"hex.builtin.popup.blocking_task.title": "작업 실행 중",
|
||||
"hex.builtin.popup.close_provider.desc": "이 공급자에 대해 아직 프로젝트에\n저장되지 않은 변경 사항이 있습니다.\n\n정말 종료하시겠습니까?",
|
||||
"hex.builtin.popup.close_provider.desc": "",
|
||||
"hex.builtin.popup.close_provider.title": "공급자를 종료하시겠습니까?",
|
||||
"hex.builtin.popup.create_workspace.desc": "",
|
||||
"hex.builtin.popup.create_workspace.title": "",
|
||||
|
@ -354,7 +354,7 @@
|
||||
"hex.builtin.nodes.visualizer.image_rgba.header": "RGBA8 图像可视化",
|
||||
"hex.builtin.nodes.visualizer.layered_dist": "分层布局",
|
||||
"hex.builtin.nodes.visualizer.layered_dist.header": "分层布局",
|
||||
"hex.builtin.popup.close_provider.desc": "对一个或多个提供者进行了未保存的更改\n尚未保存到项目中。\n\n并且您确定要关闭它们吗?",
|
||||
"hex.builtin.popup.close_provider.desc": "",
|
||||
"hex.builtin.popup.close_provider.title": "关闭提供者?",
|
||||
"hex.builtin.popup.docs_question.title": "查找文档",
|
||||
"hex.builtin.popup.docs_question.no_answer": "文档中没有这个问题的答案",
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <content/global_actions.hpp>
|
||||
|
||||
#include <content/providers/file_provider.hpp>
|
||||
|
||||
@ -80,17 +81,30 @@ namespace hex::plugin::builtin {
|
||||
if (provider->isDirty()) {
|
||||
*shouldClose = false;
|
||||
PopupUnsavedChanges::open("hex.builtin.popup.close_provider.desc"_lang,
|
||||
[]{
|
||||
for (const auto &provider : ImHexApi::Provider::impl::getClosingProviders())
|
||||
ImHexApi::Provider::remove(provider, true);
|
||||
[]{
|
||||
const bool projectSaved = ProjectFile::hasPath() ? saveProject() : saveProjectAs();
|
||||
if (projectSaved) {
|
||||
for (const auto &provider : ImHexApi::Provider::impl::getClosingProviders())
|
||||
ImHexApi::Provider::remove(provider, true);
|
||||
|
||||
if (imhexClosing)
|
||||
ImHexApi::System::closeImHex(true);
|
||||
},
|
||||
[] {
|
||||
ImHexApi::Provider::impl::resetClosingProvider();
|
||||
imhexClosing = false;
|
||||
}
|
||||
if (imhexClosing)
|
||||
ImHexApi::System::closeImHex(true);
|
||||
} else {
|
||||
ImHexApi::Provider::impl::resetClosingProvider();
|
||||
imhexClosing = false;
|
||||
}
|
||||
},
|
||||
[] {
|
||||
for (const auto &provider : ImHexApi::Provider::impl::getClosingProviders())
|
||||
ImHexApi::Provider::remove(provider, true);
|
||||
|
||||
if (imhexClosing)
|
||||
ImHexApi::System::closeImHex(true);
|
||||
},
|
||||
[] {
|
||||
ImHexApi::Provider::impl::resetClosingProvider();
|
||||
imhexClosing = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
|
||||
#include <content/global_actions.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/api/project_file_manager.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
@ -18,18 +19,25 @@ namespace hex::plugin::builtin {
|
||||
});
|
||||
}
|
||||
|
||||
void saveProject() {
|
||||
if (ImHexApi::Provider::isValid() && ProjectFile::hasPath()) {
|
||||
bool saveProject() {
|
||||
if (!ImHexApi::Provider::isValid())
|
||||
return false;
|
||||
|
||||
if (ProjectFile::hasPath()) {
|
||||
if (!ProjectFile::store()) {
|
||||
ui::ToastError::open("hex.builtin.popup.error.project.save"_lang);
|
||||
return false;
|
||||
} else {
|
||||
log::debug("Project saved");
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return saveProjectAs();
|
||||
}
|
||||
}
|
||||
|
||||
void saveProjectAs() {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, { {"Project File", "hexproj"} },
|
||||
bool saveProjectAs() {
|
||||
return fs::openFileBrowser(fs::DialogMode::Save, { {"Project File", "hexproj"} },
|
||||
[](std::fs::path path) {
|
||||
if (path.extension() != ".hexproj") {
|
||||
path.replace_extension(".hexproj");
|
||||
|
@ -54,4 +54,52 @@ namespace hex::ui {
|
||||
std::function<void()> m_yesFunction, m_noFunction;
|
||||
};
|
||||
|
||||
class PopupCancelableQuestion : public Popup<PopupCancelableQuestion> {
|
||||
public:
|
||||
PopupCancelableQuestion(std::string message, std::function<void()> yesFunction, std::function<void()> noFunction)
|
||||
: hex::Popup<PopupCancelableQuestion>("hex.ui.common.question", false),
|
||||
m_message(std::move(message)),
|
||||
m_yesFunction(std::move(yesFunction)), m_noFunction(std::move(noFunction)) { }
|
||||
|
||||
void drawContent() override {
|
||||
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
|
||||
auto width = ImGui::GetWindowWidth();
|
||||
ImGui::SetCursorPosX(width / 9);
|
||||
if (ImGui::Button("hex.ui.common.yes"_lang, ImVec2(width / 3, 0))) {
|
||||
m_yesFunction();
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("hex.ui.common.no"_lang, ImVec2(width / 3, 0))) {
|
||||
m_noFunction();
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("hex.ui.common.cancel"_lang, ImVec2(width / 3, 0))) {
|
||||
this->close();
|
||||
}
|
||||
|
||||
ImGui::SetWindowPos((ImHexApi::System::getMainWindowSize() - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
}
|
||||
|
||||
[[nodiscard]] ImGuiWindowFlags getFlags() const override {
|
||||
return ImGuiWindowFlags_AlwaysAutoResize;
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getMinSize() const override {
|
||||
return scaled({ 400, 100 });
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getMaxSize() const override {
|
||||
return scaled({ 600, 300 });
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
std::function<void()> m_yesFunction, m_noFunction;
|
||||
};
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user