diff --git a/lib/libimhex/include/hex/api/event.hpp b/lib/libimhex/include/hex/api/event.hpp index 2b6ca613e..4ae8ff524 100644 --- a/lib/libimhex/include/hex/api/event.hpp +++ b/lib/libimhex/include/hex/api/event.hpp @@ -183,10 +183,7 @@ namespace hex { EVENT_DEF(RequestCreateProvider, std::string, bool, hex::prv::Provider **); EVENT_DEF(RequestInitThemeHandlers); - EVENT_DEF(RequestShowInfoPopup, std::string); - EVENT_DEF(RequestShowErrorPopup, std::string); - EVENT_DEF(RequestShowFatalErrorPopup, std::string); - EVENT_DEF(RequestShowYesNoQuestionPopup, std::string, std::function, std::function); - EVENT_DEF(RequestShowFileChooserPopup, std::vector, std::vector, std::function, bool); - + EVENT_DEF(RequestOpenInfoPopup, const std::string); + EVENT_DEF(RequestOpenErrorPopup, const std::string); + EVENT_DEF(RequestOpenFatalPopup, const std::string); } \ No newline at end of file diff --git a/lib/libimhex/include/hex/api/task.hpp b/lib/libimhex/include/hex/api/task.hpp index 7ed05a6e0..1d31d3015 100644 --- a/lib/libimhex/include/hex/api/task.hpp +++ b/lib/libimhex/include/hex/api/task.hpp @@ -108,6 +108,8 @@ namespace hex { [[nodiscard]] bool wasInterrupted() const; [[nodiscard]] bool shouldInterrupt() const; + [[nodiscard]] u32 getProgress() const; + void interrupt(); private: std::weak_ptr m_task; diff --git a/lib/libimhex/include/hex/ui/popup.hpp b/lib/libimhex/include/hex/ui/popup.hpp index 01bf8898a..c066f07ac 100644 --- a/lib/libimhex/include/hex/ui/popup.hpp +++ b/lib/libimhex/include/hex/ui/popup.hpp @@ -7,55 +7,88 @@ #include #include +#include +#include + +#include namespace hex { - class PopupBase { - public: - explicit PopupBase(std::string unlocalizedName, bool closeButton = true) - : m_unlocalizedName(std::move(unlocalizedName)), m_closeButton(closeButton) { } + namespace impl { - virtual ~PopupBase() = default; + class PopupBase { + public: + explicit PopupBase(std::string unlocalizedName, bool closeButton, bool modal) + : m_unlocalizedName(std::move(unlocalizedName)), m_closeButton(closeButton), m_modal(modal) { } - virtual void drawContent() = 0; - [[nodiscard]] virtual ImGuiPopupFlags getFlags() const { return ImGuiPopupFlags_None; } + virtual ~PopupBase() = default; + virtual void drawContent() = 0; + [[nodiscard]] virtual ImGuiWindowFlags getFlags() const { return ImGuiWindowFlags_None; } - [[nodiscard]] static std::vector> &getOpenPopups() { - return s_openPopups; - } + [[nodiscard]] virtual ImVec2 getMinSize() const { + return { 0, 0 }; + } - [[nodiscard]] const std::string &getUnlocalizedName() const { - return this->m_unlocalizedName; - } + [[nodiscard]] virtual ImVec2 getMaxSize() const { + return { FLT_MAX, FLT_MAX }; + } - [[nodiscard]] bool hasCloseButton() const { - return this->m_closeButton; - } + [[nodiscard]] static std::vector> &getOpenPopups() { + return s_openPopups; + } - protected: - static void close() { - ImGui::CloseCurrentPopup(); - s_openPopups.pop_back(); - } + [[nodiscard]] const std::string &getUnlocalizedName() const { + return this->m_unlocalizedName; + } - static std::vector> s_openPopups; - private: + [[nodiscard]] bool hasCloseButton() const { + return this->m_closeButton; + } + + [[nodiscard]] bool isModal() const { + return this->m_modal; + } + + static void close() { + if (s_openPopups.empty()) + return; + + TaskManager::doLater([]{ + std::lock_guard lock(s_mutex); + + ImGui::CloseCurrentPopup(); + s_openPopups.pop_back(); + }); + } + + static std::mutex& getMutex() { + return s_mutex; + } + + protected: + static std::vector> s_openPopups; + static std::mutex s_mutex; + + private: + + std::string m_unlocalizedName; + bool m_closeButton, m_modal; + }; + + } - std::string m_unlocalizedName; - bool m_closeButton; - }; template - class Popup : public PopupBase { + class Popup : public impl::PopupBase { protected: - explicit Popup(std::string unlocalizedName, bool closeButton = true) : PopupBase(std::move(unlocalizedName), closeButton) { } + explicit Popup(std::string unlocalizedName, bool closeButton = true, bool modal = true) : PopupBase(std::move(unlocalizedName), closeButton, modal) { } public: - virtual ~Popup() = default; - template static void open(Args && ... args) { + std::lock_guard lock(s_mutex); + auto popup = std::make_unique(std::forward(args)...); s_openPopups.emplace_back(std::move(popup)); diff --git a/lib/libimhex/include/hex/ui/view.hpp b/lib/libimhex/include/hex/ui/view.hpp index be76b1f56..09f367d00 100644 --- a/lib/libimhex/include/hex/ui/view.hpp +++ b/lib/libimhex/include/hex/ui/view.hpp @@ -34,13 +34,6 @@ namespace hex { [[nodiscard]] virtual bool isAvailable() const; [[nodiscard]] virtual bool shouldProcess() const { return this->isAvailable() && this->getWindowOpenState(); } - static void showInfoPopup(const std::string &message); - static void showErrorPopup(const std::string &message); - static void showFatalPopup(const std::string &message); - static void showYesNoQuestionPopup(const std::string &message, const std::function &yesCallback, const std::function &noCallback); - - static void showFileChooserPopup(const std::vector &paths, const std::vector &validExtensions, bool multiple, const std::function &callback); - [[nodiscard]] virtual bool hasViewMenuItemEntry() const; [[nodiscard]] virtual ImVec2 getMinSize() const; [[nodiscard]] virtual ImVec2 getMaxSize() const; diff --git a/lib/libimhex/source/api/task.cpp b/lib/libimhex/source/api/task.cpp index 83bdec0ff..53735e3f4 100644 --- a/lib/libimhex/source/api/task.cpp +++ b/lib/libimhex/source/api/task.cpp @@ -165,6 +165,14 @@ namespace hex { task->interrupt(); } + u32 TaskHolder::getProgress() const { + if (this->m_task.expired()) + return 0; + + auto task = this->m_task.lock(); + return (u32)((task->getValue() * 100) / task->getMaxValue()); + } + void TaskManager::init() { for (u32 i = 0; i < std::thread::hardware_concurrency(); i++) diff --git a/lib/libimhex/source/ui/popup.cpp b/lib/libimhex/source/ui/popup.cpp index bc2a76515..a15fab316 100644 --- a/lib/libimhex/source/ui/popup.cpp +++ b/lib/libimhex/source/ui/popup.cpp @@ -1,7 +1,8 @@ #include -namespace hex { +namespace hex::impl { std::vector> PopupBase::s_openPopups; + std::mutex PopupBase::s_mutex; } \ No newline at end of file diff --git a/lib/libimhex/source/ui/view.cpp b/lib/libimhex/source/ui/view.cpp index 991cb5d05..a17d1a570 100644 --- a/lib/libimhex/source/ui/view.cpp +++ b/lib/libimhex/source/ui/view.cpp @@ -17,33 +17,6 @@ namespace hex { return ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isAvailable(); } - void View::showInfoPopup(const std::string &message) { - EventManager::post(message); - } - - void View::showErrorPopup(const std::string &message) { - EventManager::post(message); - } - - void View::showFatalPopup(const std::string &message) { - EventManager::post(message); - } - - void View::showYesNoQuestionPopup(const std::string &message, const std::function &yesCallback, const std::function &noCallback) { - EventManager::post(message, yesCallback, noCallback); - - } - - void View::showFileChooserPopup(const std::vector &paths, const std::vector &validExtensions, bool multiple, const std::function &callback) { - if (paths.empty()) { - fs::openFileBrowser(fs::DialogMode::Open, validExtensions, [callback](const auto &path) { - callback(path); - }, {}, multiple); - } else { - EventManager::post(paths, validExtensions, callback, multiple); - } - } - bool View::hasViewMenuItemEntry() const { return true; } diff --git a/main/source/window/window.cpp b/main/source/window/window.cpp index c8055e1d6..f7aca554f 100644 --- a/main/source/window/window.cpp +++ b/main/source/window/window.cpp @@ -525,7 +525,8 @@ namespace hex { // Draw popup stack { - if (auto &popups = PopupBase::getOpenPopups(); !popups.empty()) { + std::scoped_lock lock(impl::PopupBase::getMutex()); + if (auto &popups = impl::PopupBase::getOpenPopups(); !popups.empty()) { auto &currPopup = popups.back(); const auto &name = LangEntry(currPopup->getUnlocalizedName()); @@ -533,10 +534,24 @@ namespace hex { ImGui::OpenPopup(name); bool open = true; - if (ImGui::BeginPopupModal(name, currPopup->hasCloseButton() ? &open : nullptr, currPopup->getFlags())) { - currPopup->drawContent(); + ImGui::SetNextWindowSizeConstraints(currPopup->getMinSize(), currPopup->getMaxSize()); - ImGui::EndPopup(); + auto closeButton = currPopup->hasCloseButton() ? &open : nullptr; + auto flags = currPopup->getFlags(); + + ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F)); + if (currPopup->isModal()) { + if (ImGui::BeginPopupModal(name, closeButton, flags)) { + currPopup->drawContent(); + + ImGui::EndPopup(); + } + } else { + if (ImGui::BeginPopup(name, flags)) { + currPopup->drawContent(); + + ImGui::EndPopup(); + } } if (!open) diff --git a/plugins/builtin/include/content/popups/popup_file_chooser.hpp b/plugins/builtin/include/content/popups/popup_file_chooser.hpp new file mode 100644 index 000000000..768bb1853 --- /dev/null +++ b/plugins/builtin/include/content/popups/popup_file_chooser.hpp @@ -0,0 +1,80 @@ +#include + +#include + +#include +#include + +namespace hex::plugin::builtin { + + class PopupFileChooser : public Popup { + public: + PopupFileChooser(const std::vector &files, const std::vector &validExtensions, bool multiple, const std::function &callback) + : hex::Popup("hex.builtin.common.choose_file", false), + m_indices({ }), m_files(files), + m_openCallback(callback), + m_validExtensions(validExtensions), m_multiple(multiple) { } + + void drawContent() override { + bool doubleClicked = false; + + if (ImGui::BeginListBox("##files", scaled(ImVec2(500, 400)))) { + u32 index = 0; + for (auto &path : this->m_files) { + ImGui::PushID(index); + + bool selected = this->m_indices.contains(index); + if (ImGui::Selectable(wolv::util::toUTF8String(path.filename()).c_str(), selected, ImGuiSelectableFlags_DontClosePopups)) { + if (!this->m_multiple) { + this->m_indices.clear(); + this->m_indices.insert(index); + } else { + if (selected) { + this->m_indices.erase(index); + } else { + this->m_indices.insert(index); + } + } + } + + if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) + doubleClicked = true; + + ImGui::InfoTooltip(wolv::util::toUTF8String(path).c_str()); + + ImGui::PopID(); + index++; + } + + ImGui::EndListBox(); + } + + if (ImGui::Button("hex.builtin.common.open"_lang) || doubleClicked) { + for (const auto &index : this->m_indices) + this->m_openCallback(this->m_files[index]); + ImGui::CloseCurrentPopup(); + } + + ImGui::SameLine(); + + if (ImGui::Button("hex.builtin.common.browse"_lang)) { + fs::openFileBrowser(fs::DialogMode::Open, this->m_validExtensions, [this](const auto &path) { + this->m_openCallback(path); + ImGui::CloseCurrentPopup(); + }, {}, this->m_multiple); + } + } + + [[nodiscard]] ImGuiWindowFlags getFlags() const override { + return ImGuiWindowFlags_AlwaysAutoResize; + } + + private: + std::set m_indices; + std::vector m_files; + std::function m_openCallback; + std::vector m_validExtensions; + bool m_multiple = false; + }; + +} \ No newline at end of file diff --git a/plugins/builtin/include/content/popups/popup_notification.hpp b/plugins/builtin/include/content/popups/popup_notification.hpp new file mode 100644 index 000000000..4c9f95868 --- /dev/null +++ b/plugins/builtin/include/content/popups/popup_notification.hpp @@ -0,0 +1,74 @@ +#include + +#include + +#include +#include + +namespace hex::plugin::builtin { + + namespace impl { + + template + class PopupNotification : public Popup { + public: + PopupNotification(std::string unlocalizedName, std::string message, std::function function) + : hex::Popup(std::move(unlocalizedName), false), + m_message(std::move(message)), m_function(std::move(function)) { } + + void drawContent() override { + ImGui::TextFormattedWrapped("{}", this->m_message.c_str()); + ImGui::NewLine(); + ImGui::Separator(); + if (ImGui::Button("hex.builtin.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) + this->m_function(); + + 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 m_function; + }; + + } + + class PopupInfo : public impl::PopupNotification { + public: + explicit PopupInfo(std::string message) + : PopupNotification("hex.builtin.common.info", std::move(message), []() { + Popup::close(); + }) { } + }; + + class PopupError : public impl::PopupNotification { + public: + explicit PopupError(std::string message) + : PopupNotification("hex.builtin.common.error", std::move(message), []() { + Popup::close(); + }) { } + }; + + class PopupFatal : public impl::PopupNotification { + public: + explicit PopupFatal(std::string message) + : PopupNotification("hex.builtin.common.fatal", std::move(message), []() { + ImHexApi::System::closeImHex(); + Popup::close(); + }) { } + }; + + +} \ No newline at end of file diff --git a/plugins/builtin/include/content/popups/popup_question.hpp b/plugins/builtin/include/content/popups/popup_question.hpp new file mode 100644 index 000000000..479d31a1f --- /dev/null +++ b/plugins/builtin/include/content/popups/popup_question.hpp @@ -0,0 +1,51 @@ +#include + +#include + +#include +#include + +namespace hex::plugin::builtin { + + class PopupQuestion : public Popup { + public: + PopupQuestion(std::string message, std::function yesFunction, std::function noFunction) + : hex::Popup("hex.builtin.common.question", false), + m_message(std::move(message)), + m_yesFunction(std::move(yesFunction)), m_noFunction(std::move(noFunction)) { } + + void drawContent() override { + ImGui::TextFormattedWrapped("{}", this->m_message.c_str()); + ImGui::NewLine(); + ImGui::Separator(); + + auto width = ImGui::GetWindowWidth(); + ImGui::SetCursorPosX(width / 9); + if (ImGui::Button("hex.builtin.common.yes"_lang, ImVec2(width / 3, 0))) + this->m_yesFunction(); + ImGui::SameLine(); + ImGui::SetCursorPosX(width / 9 * 5); + if (ImGui::Button("hex.builtin.common.no"_lang, ImVec2(width / 3, 0))) + this->m_noFunction(); + + 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 m_yesFunction, m_noFunction; + }; + +} \ No newline at end of file diff --git a/plugins/builtin/include/content/popups/popup_tasks_waiting.hpp b/plugins/builtin/include/content/popups/popup_tasks_waiting.hpp new file mode 100644 index 000000000..7c7a9e006 --- /dev/null +++ b/plugins/builtin/include/content/popups/popup_tasks_waiting.hpp @@ -0,0 +1,37 @@ +#include + +#include + +#include +#include + +namespace hex::plugin::builtin { + + class PopupTasksWaiting : public Popup { + public: + PopupTasksWaiting() + : hex::Popup("hex.builtin.popup.waiting_for_tasks.title", false) { } + + void drawContent() override { + ImGui::TextUnformatted("hex.builtin.popup.waiting_for_tasks.desc"_lang); + ImGui::Separator(); + + ImGui::SetCursorPosX((ImGui::GetWindowWidth() - ImGui::CalcTextSize("[-]").x) / 2); + ImGui::TextSpinner(""); + ImGui::NewLine(); + ImGui::SetCursorPosX((ImGui::GetWindowWidth() - 150_scaled) / 2); + if (ImGui::ButtonEx("hex.builtin.common.cancel"_lang, ImVec2(150, 0)) || ImGui::IsKeyDown(ImGuiKey_Escape)) + ImGui::CloseCurrentPopup(); + + if (TaskManager::getRunningTaskCount() == 0 && TaskManager::getRunningBackgroundTaskCount() == 0) { + ImGui::CloseCurrentPopup(); + ImHexApi::System::closeImHex(); + } + } + + [[nodiscard]] ImGuiWindowFlags getFlags() const override { + return ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove; + } + }; + +} \ No newline at end of file diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index c896b30ea..77abbc2f9 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -1,14 +1,18 @@ #pragma once #include +#include +#include + #include #include -#include #include +#include + #include #include -#include + #include #include @@ -38,6 +42,54 @@ namespace hex::plugin::builtin { Deny }; + class PopupAcceptPattern : public Popup { + public: + PopupAcceptPattern(ViewPatternEditor *view) : Popup("hex.builtin.view.pattern_editor.accept_pattern"), m_view(view) {} + + void drawContent() override { + ImGui::TextFormattedWrapped("{}", static_cast("hex.builtin.view.pattern_editor.accept_pattern.desc"_lang)); + + std::vector entries; + entries.resize(this->m_view->m_possiblePatternFiles.size()); + + for (u32 i = 0; i < entries.size(); i++) { + entries[i] = wolv::util::toUTF8String(this->m_view->m_possiblePatternFiles[i].filename()); + } + + if (ImGui::BeginListBox("##patterns_accept", ImVec2(-FLT_MIN, 0))) { + u32 index = 0; + for (auto &path : this->m_view->m_possiblePatternFiles) { + if (ImGui::Selectable(wolv::util::toUTF8String(path.filename()).c_str(), index == this->m_view->m_selectedPatternFile)) + this->m_view->m_selectedPatternFile = index; + index++; + } + + ImGui::EndListBox(); + } + + ImGui::NewLine(); + ImGui::TextUnformatted("hex.builtin.view.pattern_editor.accept_pattern.question"_lang); + + auto provider = ImHexApi::Provider::get(); + + confirmButtons( + "hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, [this, provider] { + this->m_view->loadPatternFile(this->m_view->m_possiblePatternFiles[this->m_view->m_selectedPatternFile], provider); + Popup::close(); + }, + [] { + Popup::close(); + } + ); + + if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape))) + Popup::close(); + } + + private: + ViewPatternEditor *m_view; + }; + private: using PlData = ProviderExtraData::Data::PatternLanguage; diff --git a/plugins/builtin/romfs/lang/base.json b/plugins/builtin/romfs/lang/base.json index 11f3d578c..9d7d1878d 100644 --- a/plugins/builtin/romfs/lang/base.json +++ b/plugins/builtin/romfs/lang/base.json @@ -764,8 +764,8 @@ "hex.builtin.view.store.row.name", "hex.builtin.view.store.tab.constants", "hex.builtin.view.store.tab.encodings", - "hex.builtin.view.store.tab.libraries", - "hex.builtin.view.store.tab.magics", + "hex.builtin.view.store.tab.includes", + "hex.builtin.view.store.tab.magic", "hex.builtin.view.store.tab.patterns", "hex.builtin.view.store.tab.yara", "hex.builtin.view.store.update", diff --git a/plugins/builtin/romfs/lang/de_DE.json b/plugins/builtin/romfs/lang/de_DE.json index e02ded1b5..0c64adb39 100644 --- a/plugins/builtin/romfs/lang/de_DE.json +++ b/plugins/builtin/romfs/lang/de_DE.json @@ -806,8 +806,8 @@ "hex.builtin.view.store.row.name": "Name", "hex.builtin.view.store.tab.constants": "Konstanten", "hex.builtin.view.store.tab.encodings": "Encodings", - "hex.builtin.view.store.tab.libraries": "Libraries", - "hex.builtin.view.store.tab.magics": "Magic Files", + "hex.builtin.view.store.tab.includes": "Libraries", + "hex.builtin.view.store.tab.magic": "Magic Files", "hex.builtin.view.store.tab.nodes": "", "hex.builtin.view.store.tab.patterns": "Patterns", "hex.builtin.view.store.tab.themes": "", diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 013803194..bc3e4dcbb 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -814,8 +814,8 @@ "hex.builtin.view.store.row.name": "Name", "hex.builtin.view.store.tab.constants": "Constants", "hex.builtin.view.store.tab.encodings": "Encodings", - "hex.builtin.view.store.tab.libraries": "Libraries", - "hex.builtin.view.store.tab.magics": "Magic Files", + "hex.builtin.view.store.tab.includes": "Libraries", + "hex.builtin.view.store.tab.magic": "Magic Files", "hex.builtin.view.store.tab.nodes": "Nodes", "hex.builtin.view.store.tab.patterns": "Patterns", "hex.builtin.view.store.tab.themes": "Themes", diff --git a/plugins/builtin/romfs/lang/it_IT.json b/plugins/builtin/romfs/lang/it_IT.json index 457ca71b8..cd8b28805 100644 --- a/plugins/builtin/romfs/lang/it_IT.json +++ b/plugins/builtin/romfs/lang/it_IT.json @@ -806,8 +806,8 @@ "hex.builtin.view.store.row.name": "Nome", "hex.builtin.view.store.tab.constants": "Costanti", "hex.builtin.view.store.tab.encodings": "Encodings", - "hex.builtin.view.store.tab.libraries": "Librerie", - "hex.builtin.view.store.tab.magics": "File Magici", + "hex.builtin.view.store.tab.includes": "Librerie", + "hex.builtin.view.store.tab.magic": "File Magici", "hex.builtin.view.store.tab.nodes": "", "hex.builtin.view.store.tab.patterns": "Modelli", "hex.builtin.view.store.tab.themes": "", diff --git a/plugins/builtin/romfs/lang/ja_JP.json b/plugins/builtin/romfs/lang/ja_JP.json index 35da2f878..dad42c582 100644 --- a/plugins/builtin/romfs/lang/ja_JP.json +++ b/plugins/builtin/romfs/lang/ja_JP.json @@ -806,8 +806,8 @@ "hex.builtin.view.store.row.name": "名前", "hex.builtin.view.store.tab.constants": "定数", "hex.builtin.view.store.tab.encodings": "エンコード", - "hex.builtin.view.store.tab.libraries": "ライブラリ", - "hex.builtin.view.store.tab.magics": "Magicファイル", + "hex.builtin.view.store.tab.includes": "ライブラリ", + "hex.builtin.view.store.tab.magic": "Magicファイル", "hex.builtin.view.store.tab.nodes": "", "hex.builtin.view.store.tab.patterns": "パターン", "hex.builtin.view.store.tab.themes": "", diff --git a/plugins/builtin/romfs/lang/ko_KR.json b/plugins/builtin/romfs/lang/ko_KR.json index c05b72c6e..023b9cdd2 100644 --- a/plugins/builtin/romfs/lang/ko_KR.json +++ b/plugins/builtin/romfs/lang/ko_KR.json @@ -806,8 +806,8 @@ "hex.builtin.view.store.row.name": "이름", "hex.builtin.view.store.tab.constants": "상수", "hex.builtin.view.store.tab.encodings": "인코딩", - "hex.builtin.view.store.tab.libraries": "라이브러리", - "hex.builtin.view.store.tab.magics": "Magic 파일", + "hex.builtin.view.store.tab.includes": "라이브러리", + "hex.builtin.view.store.tab.magic": "Magic 파일", "hex.builtin.view.store.tab.nodes": "", "hex.builtin.view.store.tab.patterns": "패턴", "hex.builtin.view.store.tab.themes": "", diff --git a/plugins/builtin/romfs/lang/pt_BR.json b/plugins/builtin/romfs/lang/pt_BR.json index 9c7356077..7608c26d5 100644 --- a/plugins/builtin/romfs/lang/pt_BR.json +++ b/plugins/builtin/romfs/lang/pt_BR.json @@ -806,8 +806,8 @@ "hex.builtin.view.store.row.name": "Nome", "hex.builtin.view.store.tab.constants": "Constantes", "hex.builtin.view.store.tab.encodings": "Codificações", - "hex.builtin.view.store.tab.libraries": "Bibliotecas", - "hex.builtin.view.store.tab.magics": "Arquivos Mágicos", + "hex.builtin.view.store.tab.includes": "Bibliotecas", + "hex.builtin.view.store.tab.magic": "Arquivos Mágicos", "hex.builtin.view.store.tab.nodes": "", "hex.builtin.view.store.tab.patterns": "Padrões", "hex.builtin.view.store.tab.themes": "", diff --git a/plugins/builtin/romfs/lang/zh_CN.json b/plugins/builtin/romfs/lang/zh_CN.json index ab1567115..6d5e00506 100644 --- a/plugins/builtin/romfs/lang/zh_CN.json +++ b/plugins/builtin/romfs/lang/zh_CN.json @@ -770,8 +770,8 @@ "hex.builtin.view.store.row.name": "名称", "hex.builtin.view.store.tab.constants": "常量", "hex.builtin.view.store.tab.encodings": "编码", - "hex.builtin.view.store.tab.libraries": "库", - "hex.builtin.view.store.tab.magics": "LibMagic 数据库", + "hex.builtin.view.store.tab.includes": "库", + "hex.builtin.view.store.tab.magic": "LibMagic 数据库", "hex.builtin.view.store.tab.patterns": "模式", "hex.builtin.view.store.tab.yara": "Yara 规则", "hex.builtin.view.store.update": "更新", diff --git a/plugins/builtin/romfs/lang/zh_TW.json b/plugins/builtin/romfs/lang/zh_TW.json index 8b7286797..4a9441b4d 100644 --- a/plugins/builtin/romfs/lang/zh_TW.json +++ b/plugins/builtin/romfs/lang/zh_TW.json @@ -806,8 +806,8 @@ "hex.builtin.view.store.row.name": "名稱", "hex.builtin.view.store.tab.constants": "常數", "hex.builtin.view.store.tab.encodings": "編碼", - "hex.builtin.view.store.tab.libraries": "程式庫", - "hex.builtin.view.store.tab.magics": "Magic Files", + "hex.builtin.view.store.tab.includes": "程式庫", + "hex.builtin.view.store.tab.magic": "Magic Files", "hex.builtin.view.store.tab.nodes": "", "hex.builtin.view.store.tab.patterns": "模式", "hex.builtin.view.store.tab.themes": "", diff --git a/plugins/builtin/source/content/events.cpp b/plugins/builtin/source/content/events.cpp index efe068bad..857151477 100644 --- a/plugins/builtin/source/content/events.cpp +++ b/plugins/builtin/source/content/events.cpp @@ -14,6 +14,10 @@ #include +#include +#include +#include + namespace hex::plugin::builtin { static void openFile(const std::fs::path &path) { @@ -30,13 +34,21 @@ namespace hex::plugin::builtin { EventManager::subscribe([](GLFWwindow *window) { if (ImHexApi::Provider::isDirty()) { glfwSetWindowShouldClose(window, GLFW_FALSE); - TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.popup.exit_application.title"_lang); }); + PopupQuestion::open("hex.builtin.popup.exit_application.desc"_lang, + []{ + ImHexApi::Provider::resetDirty(); + ImHexApi::System::closeImHex(); + }, + []{ + PopupQuestion::close(); + } + ); } else if (TaskManager::getRunningTaskCount() > 0 || TaskManager::getRunningBackgroundTaskCount() > 0) { glfwSetWindowShouldClose(window, GLFW_FALSE); TaskManager::doLater([] { for (auto &task : TaskManager::getRunningTasks()) task->interrupt(); - ImGui::OpenPopup("hex.builtin.popup.waiting_for_tasks.title"_lang); + PopupTasksWaiting::open(); }); } }); @@ -44,7 +56,15 @@ namespace hex::plugin::builtin { EventManager::subscribe([](hex::prv::Provider *provider, bool *shouldClose) { if (provider->isDirty()) { *shouldClose = false; - TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.popup.close_provider.title"_lang); }); + PopupQuestion::open("hex.builtin.popup.close_provider.desc", + []{ + ImHexApi::Provider::remove(ImHexApi::Provider::impl::getClosingProvider(), true); + PopupQuestion::close(); + }, + []{ + PopupQuestion::close(); + } + ); } }); @@ -75,7 +95,7 @@ namespace hex::plugin::builtin { fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"} }, [](const auto &path) { if (!ProjectFile::load(path)) { - View::showErrorPopup("hex.builtin.popup.error.project.load"_lang); + PopupError::open("hex.builtin.popup.error.project.load"_lang); } }); } @@ -95,7 +115,7 @@ namespace hex::plugin::builtin { return; } if (!provider->open()) { - View::showErrorPopup("hex.builtin.popup.error.open"_lang); + PopupError::open("hex.builtin.popup.error.open"_lang); TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); }); return; } @@ -106,7 +126,7 @@ namespace hex::plugin::builtin { EventManager::post(View::toWindowName("hex.builtin.view.provider_settings.load_popup")); else { if (!provider->open() || !provider->isAvailable()) { - View::showErrorPopup("hex.builtin.popup.error.open"_lang); + PopupError::open("hex.builtin.popup.error.open"_lang); TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); }); return; } @@ -123,11 +143,23 @@ namespace hex::plugin::builtin { ImHexApi::HexEditor::impl::setCurrentSelection(region); }); + EventManager::subscribe([](const std::string &message) { + PopupInfo::open(message); + }); + + EventManager::subscribe([](const std::string &message) { + PopupError::open(message); + }); + + EventManager::subscribe([](const std::string &message) { + PopupFatal::open(message); + }); + fs::setFileBrowserErrorCallback([](const std::string& errMsg){ #if defined(NFD_PORTAL) - View::showErrorPopup(hex::format("hex.builtin.popup.error.file_dialog.portal"_lang, errMsg)); + PopupError::open(hex::format("hex.builtin.popup.error.file_dialog.portal"_lang, errMsg)); #else - View::showErrorPopup(hex::format("hex.builtin.popup.error.file_dialog.common"_lang, errMsg)); + PopupError::open(hex::format("hex.builtin.popup.error.file_dialog.common"_lang, errMsg)); #endif }); diff --git a/plugins/builtin/source/content/global_actions.cpp b/plugins/builtin/source/content/global_actions.cpp index 8af1b0b00..2d03a1559 100644 --- a/plugins/builtin/source/content/global_actions.cpp +++ b/plugins/builtin/source/content/global_actions.cpp @@ -3,6 +3,7 @@ #include #include +#include namespace hex::plugin::builtin { @@ -10,7 +11,7 @@ namespace hex::plugin::builtin { fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"} }, [](const auto &path) { if (!ProjectFile::load(path)) { - View::showErrorPopup("hex.builtin.popup.error.project.load"_lang); + PopupError::open("hex.builtin.popup.error.project.load"_lang); } }); } @@ -18,7 +19,7 @@ namespace hex::plugin::builtin { void saveProject() { if (ImHexApi::Provider::isValid() && ProjectFile::hasPath()) { if (!ProjectFile::store()) { - View::showErrorPopup("hex.builtin.popup.error.project.save"_lang); + PopupError::open("hex.builtin.popup.error.project.save"_lang); } else { log::debug("Project saved"); } @@ -33,7 +34,7 @@ namespace hex::plugin::builtin { } if (!ProjectFile::store(path)) { - View::showErrorPopup("hex.builtin.popup.error.project.save"_lang); + PopupError::open("hex.builtin.popup.error.project.save"_lang); } }); } diff --git a/plugins/builtin/source/content/main_menu_items.cpp b/plugins/builtin/source/content/main_menu_items.cpp index 74da4fa11..5b997a410 100644 --- a/plugins/builtin/source/content/main_menu_items.cpp +++ b/plugins/builtin/source/content/main_menu_items.cpp @@ -11,6 +11,7 @@ #include #include "content/global_actions.hpp" +#include #include @@ -38,19 +39,19 @@ namespace hex::plugin::builtin { TaskManager::doLater([error]{ switch (error) { case IPSError::InvalidPatchHeader: - View::showErrorPopup("hex.builtin.menu.file.export.ips.popup.invalid_patch_header_error"_lang); + PopupError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_header_error"_lang); break; case IPSError::AddressOutOfRange: - View::showErrorPopup("hex.builtin.menu.file.export.ips.popup.address_out_of_range_error"_lang); + PopupError::open("hex.builtin.menu.file.export.ips.popup.address_out_of_range_error"_lang); break; case IPSError::PatchTooLarge: - View::showErrorPopup("hex.builtin.menu.file.export.ips.popup.patch_too_large_error"_lang); + PopupError::open("hex.builtin.menu.file.export.ips.popup.patch_too_large_error"_lang); break; case IPSError::InvalidPatchFormat: - View::showErrorPopup("hex.builtin.menu.file.export.ips.popup.invalid_patch_format_error"_lang); + PopupError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_format_error"_lang); break; case IPSError::MissingEOF: - View::showErrorPopup("hex.builtin.menu.file.export.ips.popup.missing_eof_error"_lang); + PopupError::open("hex.builtin.menu.file.export.ips.popup.missing_eof_error"_lang); break; } }); @@ -65,7 +66,7 @@ namespace hex::plugin::builtin { fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) { wolv::io::File inputFile(path, wolv::io::File::Mode::Read); if (!inputFile.isValid()) { - View::showErrorPopup("hex.builtin.menu.file.import.base64.popup.open_error"_lang); + PopupError::open("hex.builtin.menu.file.import.base64.popup.open_error"_lang); return; } @@ -75,19 +76,19 @@ namespace hex::plugin::builtin { auto data = crypt::decode64(base64); if (data.empty()) - View::showErrorPopup("hex.builtin.menu.file.import.base64.popup.import_error"_lang); + PopupError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang); else { fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const std::fs::path &path) { wolv::io::File outputFile(path, wolv::io::File::Mode::Create); if (!outputFile.isValid()) - View::showErrorPopup("hex.builtin.menu.file.import.base64.popup.import_error"_lang); + PopupError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang); outputFile.writeVector(data); }); } } else { - View::showErrorPopup("hex.builtin.popup.file_open_error"_lang); + PopupError::open("hex.builtin.popup.file_open_error"_lang); } }); } @@ -151,7 +152,7 @@ namespace hex::plugin::builtin { auto patchData = wolv::io::File(path, wolv::io::File::Mode::Read).readVector(); if (patchData.size() != provider->getActualSize()) { - View::showErrorPopup("hex.builtin.menu.file.import.modified_file.popup.invalid_size"_lang); + PopupError::open("hex.builtin.menu.file.import.modified_file.popup.invalid_size"_lang); return; } @@ -191,7 +192,7 @@ namespace hex::plugin::builtin { wolv::io::File outputFile(path, wolv::io::File::Mode::Create); if (!outputFile.isValid()) { TaskManager::doLater([] { - View::showErrorPopup("hex.builtin.menu.file.export.base64.popup.export_error"_lang); + PopupError::open("hex.builtin.menu.file.export.base64.popup.export_error"_lang); }); return; } @@ -227,7 +228,7 @@ namespace hex::plugin::builtin { fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) { auto file = wolv::io::File(path, wolv::io::File::Mode::Create); if (!file.isValid()) { - View::showErrorPopup("hex.builtin.menu.file.export.ips.popup.export_error"_lang); + PopupError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang); return; } @@ -260,7 +261,7 @@ namespace hex::plugin::builtin { fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) { auto file = wolv::io::File(path, wolv::io::File::Mode::Create); if (!file.isValid()) { - View::showErrorPopup("hex.builtin.menu.file.export.ips.popup.export_error"_lang); + PopupError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang); return; } diff --git a/plugins/builtin/source/content/tools_entries.cpp b/plugins/builtin/source/content/tools_entries.cpp index ff0347661..e81f3f0c6 100644 --- a/plugins/builtin/source/content/tools_entries.cpp +++ b/plugins/builtin/source/content/tools_entries.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #define IMGUI_DEFINE_MATH_OPERATORS @@ -646,11 +647,11 @@ namespace hex::plugin::builtin { json["data"]["file"]["metadata"]["size"]["readable"] }); } catch (...) { - View::showErrorPopup("hex.builtin.tools.file_uploader.invalid_response"_lang); + PopupError::open("hex.builtin.tools.file_uploader.invalid_response"_lang); } } else if (response.getStatusCode() == 0) { // Canceled by user, no action needed - } else View::showErrorPopup(hex::format("hex.builtin.tools.file_uploader.error"_lang, response.getStatusCode())); + } else PopupError::open(hex::format("hex.builtin.tools.file_uploader.error"_lang, response.getStatusCode())); uploadProcess = {}; currFile.clear(); @@ -772,7 +773,7 @@ namespace hex::plugin::builtin { wolv::io::File file(selectedFile, wolv::io::File::Mode::Write); if (!file.isValid()) { - View::showErrorPopup("hex.builtin.tools.file_tools.shredder.error.open"_lang); + PopupError::open("hex.builtin.tools.file_tools.shredder.error.open"_lang); return; } @@ -846,7 +847,7 @@ namespace hex::plugin::builtin { file.remove(); - View::showInfoPopup("hex.builtin.tools.file_tools.shredder.success"_lang); + PopupInfo::open("hex.builtin.tools.file_tools.shredder.success"_lang); }); } } @@ -937,12 +938,12 @@ namespace hex::plugin::builtin { wolv::io::File file(selectedFile, wolv::io::File::Mode::Read); if (!file.isValid()) { - View::showErrorPopup("hex.builtin.tools.file_tools.splitter.picker.error.open"_lang); + PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.open"_lang); return; } if (file.getSize() < splitSize) { - View::showErrorPopup("hex.builtin.tools.file_tools.splitter.picker.error.size"_lang); + PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.size"_lang); return; } @@ -958,7 +959,7 @@ namespace hex::plugin::builtin { wolv::io::File partFile(path, wolv::io::File::Mode::Create); if (!partFile.isValid()) { - View::showErrorPopup(hex::format("hex.builtin.tools.file_tools.splitter.picker.error.create"_lang, index)); + PopupError::open(hex::format("hex.builtin.tools.file_tools.splitter.picker.error.create"_lang, index)); return; } @@ -971,7 +972,7 @@ namespace hex::plugin::builtin { index++; } - View::showInfoPopup("hex.builtin.tools.file_tools.splitter.picker.success"_lang); + PopupInfo::open("hex.builtin.tools.file_tools.splitter.picker.success"_lang); }); } } @@ -1071,7 +1072,7 @@ namespace hex::plugin::builtin { wolv::io::File output(outputPath, wolv::io::File::Mode::Create); if (!output.isValid()) { - View::showErrorPopup("hex.builtin.tools.file_tools.combiner.error.open_output"_lang); + PopupError::open("hex.builtin.tools.file_tools.combiner.error.open_output"_lang); return; } @@ -1084,7 +1085,7 @@ namespace hex::plugin::builtin { wolv::io::File input(file, wolv::io::File::Mode::Read); if (!input.isValid()) { - View::showErrorPopup(hex::format("hex.builtin.tools.file_tools.combiner.open_input"_lang, wolv::util::toUTF8String(file))); + PopupError::open(hex::format("hex.builtin.tools.file_tools.combiner.open_input"_lang, wolv::util::toUTF8String(file))); return; } @@ -1100,7 +1101,7 @@ namespace hex::plugin::builtin { selectedIndex = 0; outputPath.clear(); - View::showInfoPopup("hex.builtin.tools.file_tools.combiner.success"_lang); + PopupInfo::open("hex.builtin.tools.file_tools.combiner.success"_lang); }); } } diff --git a/plugins/builtin/source/content/ui_items.cpp b/plugins/builtin/source/content/ui_items.cpp index f0112be6c..bfce656de 100644 --- a/plugins/builtin/source/content/ui_items.cpp +++ b/plugins/builtin/source/content/ui_items.cpp @@ -12,193 +12,16 @@ #include #include +#include +#include + namespace hex::plugin::builtin { - static std::string s_popupMessage; - static std::function s_yesCallback, s_noCallback; - static std::set s_selectableFileIndices; - static std::vector s_selectableFiles; - static std::function s_selectableFileOpenCallback; - static std::vector s_selectableFilesValidExtensions; - static bool s_selectableFileMultiple; - static void drawGlobalPopups() { - // "Are you sure you want to exit?" Popup - if (ImGui::BeginPopupModal("hex.builtin.popup.exit_application.title"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::NewLine(); - ImGui::TextUnformatted("hex.builtin.popup.exit_application.desc"_lang); - ImGui::NewLine(); - - View::confirmButtons("hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, - [] { - ImHexApi::Provider::resetDirty(); - ImHexApi::System::closeImHex(); - }, - [] { ImGui::CloseCurrentPopup(); } - ); - - if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape))) - ImGui::CloseCurrentPopup(); - - ImGui::EndPopup(); - } - - // "Are you sure you want to close provider?" Popup - if (ImGui::BeginPopupModal("hex.builtin.popup.close_provider.title"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::NewLine(); - ImGui::TextUnformatted("hex.builtin.popup.close_provider.desc"_lang); - ImGui::NewLine(); - - View::confirmButtons("hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, - [] { ImHexApi::Provider::remove(ImHexApi::Provider::impl::getClosingProvider(), true); ImGui::CloseCurrentPopup(); }, - [] { ImGui::CloseCurrentPopup(); } - ); - - if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape))) - ImGui::CloseCurrentPopup(); - - ImGui::EndPopup(); - } - - if (ImGui::BeginPopupModal("hex.builtin.popup.waiting_for_tasks.title"_lang, nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) { - ImGui::TextUnformatted("hex.builtin.popup.waiting_for_tasks.desc"_lang); - ImGui::Separator(); - - ImGui::SetCursorPosX((ImGui::GetWindowWidth() - ImGui::CalcTextSize("[-]").x) / 2); - ImGui::TextSpinner(""); - ImGui::NewLine(); - ImGui::SetCursorPosX((ImGui::GetWindowWidth() - 150_scaled) / 2); - if (ImGui::ButtonEx("hex.builtin.common.cancel"_lang, ImVec2(150, 0)) || ImGui::IsKeyDown(ImGuiKey_Escape)) - ImGui::CloseCurrentPopup(); - - if (TaskManager::getRunningTaskCount() == 0 && TaskManager::getRunningBackgroundTaskCount() == 0) { - ImGui::CloseCurrentPopup(); - ImHexApi::System::closeImHex(); - } - - ImGui::EndPopup(); - } - - auto windowSize = ImHexApi::System::getMainWindowSize(); - - // Info popup - ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300))); - if (ImGui::BeginPopupModal("hex.builtin.common.info"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str()); - ImGui::NewLine(); - ImGui::Separator(); - if (ImGui::Button("hex.builtin.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) - ImGui::CloseCurrentPopup(); - - ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing); - ImGui::EndPopup(); - } - - // Error popup - ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300))); - if (ImGui::BeginPopupModal("hex.builtin.common.error"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str()); - ImGui::NewLine(); - ImGui::Separator(); - if (ImGui::Button("hex.builtin.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) - ImGui::CloseCurrentPopup(); - - ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing); - ImGui::EndPopup(); - } - - // Fatal error popup - ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300))); - if (ImGui::BeginPopupModal("hex.builtin.common.fatal"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str()); - ImGui::NewLine(); - ImGui::Separator(); - if (ImGui::Button("hex.builtin.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) { - ImHexApi::System::closeImHex(); - ImGui::CloseCurrentPopup(); - } - - ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing); - ImGui::EndPopup(); - } - - // Yes/No question popup - ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300))); - if (ImGui::BeginPopupModal("hex.builtin.common.question"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str()); - ImGui::NewLine(); - ImGui::Separator(); - - View::confirmButtons( - "hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, [] { - s_yesCallback(); - ImGui::CloseCurrentPopup(); }, [] { - s_noCallback(); - ImGui::CloseCurrentPopup(); }); - - ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing); - ImGui::EndPopup(); - } - - // File chooser popup - bool opened = true; - ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F)); - if (ImGui::BeginPopupModal("hex.builtin.common.choose_file"_lang, &opened, ImGuiWindowFlags_AlwaysAutoResize)) { - bool doubleClicked = false; - - if (ImGui::BeginListBox("##files", scaled(ImVec2(500, 400)))) { - u32 index = 0; - for (auto &path : s_selectableFiles) { - ImGui::PushID(index); - - bool selected = s_selectableFileIndices.contains(index); - if (ImGui::Selectable(wolv::util::toUTF8String(path.filename()).c_str(), selected, ImGuiSelectableFlags_DontClosePopups)) { - if (!s_selectableFileMultiple) { - s_selectableFileIndices.clear(); - s_selectableFileIndices.insert(index); - } else { - if (selected) { - s_selectableFileIndices.erase(index); - } else { - s_selectableFileIndices.insert(index); - } - } - } - - if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) - doubleClicked = true; - - ImGui::InfoTooltip(wolv::util::toUTF8String(path).c_str()); - - ImGui::PopID(); - index++; - } - - ImGui::EndListBox(); - } - - if (ImGui::Button("hex.builtin.common.open"_lang) || doubleClicked) { - for (auto &index : s_selectableFileIndices) - s_selectableFileOpenCallback(s_selectableFiles[index]); - ImGui::CloseCurrentPopup(); - } - - ImGui::SameLine(); - - if (ImGui::Button("hex.builtin.common.browse"_lang)) { - fs::openFileBrowser(fs::DialogMode::Open, s_selectableFilesValidExtensions, [](const auto &path) { - s_selectableFileOpenCallback(path); - ImGui::CloseCurrentPopup(); - }, {}, s_selectableFileMultiple); - } - - ImGui::EndPopup(); - } - // Task exception popup for (const auto &task : TaskManager::getRunningTasks()) { if (task->hadException()) { - EventManager::post(hex::format("hex.builtin.popup.error.task_exception"_lang, LangEntry(task->getUnlocalizedName()), task->getExceptionMessage())); + PopupError::open(hex::format("hex.builtin.popup.error.task_exception"_lang, LangEntry(task->getUnlocalizedName()), task->getExceptionMessage())); task->clearException(); break; } @@ -207,49 +30,6 @@ namespace hex::plugin::builtin { void addGlobalUIItems() { EventManager::subscribe(drawGlobalPopups); - - EventManager::subscribe([](const std::string &message) { - s_popupMessage = message; - - TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.info"_lang); }); - }); - - EventManager::subscribe([](const std::string &message) { - s_popupMessage = message; - - TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.error"_lang); }); - }); - - EventManager::subscribe([](const std::string &message) { - s_popupMessage = message; - - TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.fatal"_lang); }); - }); - - EventManager::subscribe([](const std::string &message, const std::function &yesCallback, const std::function &noCallback) { - s_popupMessage = message; - - s_yesCallback = yesCallback; - s_noCallback = noCallback; - - TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.question"_lang); }); - }); - - EventManager::subscribe([](const std::vector &paths, const std::vector &validExtensions, const std::function &callback, bool multiple) { - s_selectableFileIndices = { }; - s_selectableFiles = paths; - std::sort(s_selectableFiles.begin(), s_selectableFiles.end(), - [](const auto &a, const auto &b) { - return a.filename() < b.filename(); - } - ); - - s_selectableFilesValidExtensions = validExtensions; - s_selectableFileOpenCallback = callback; - s_selectableFileMultiple = multiple; - - TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.choose_file"_lang); }); - }); } void addFooterItems() { diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index 2c2eec225..f3e87986a 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -1013,7 +1014,7 @@ namespace hex::plugin::builtin { } } - View::showFileChooserPopup(paths, { {"Thingy Table File", "tbl"} }, false, + PopupFileChooser::open(paths, std::vector{ {"Thingy Table File", "tbl"} }, false, [this](const auto &path) { TaskManager::createTask("Loading encoding file", 0, [this, path](auto&) { auto encoding = EncodingFile(EncodingFile::Type::Thingy, path); diff --git a/plugins/builtin/source/content/views/view_information.cpp b/plugins/builtin/source/content/views/view_information.cpp index 852111277..d80887479 100644 --- a/plugins/builtin/source/content/views/view_information.cpp +++ b/plugins/builtin/source/content/views/view_information.cpp @@ -15,6 +15,8 @@ #include +#include + namespace hex::plugin::builtin { using namespace hex::literals; @@ -47,7 +49,7 @@ namespace hex::plugin::builtin { ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) { for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Magic)) { if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) { - View::showInfoPopup("hex.builtin.view.information.magic_db_added"_lang); + PopupInfo::open("hex.builtin.view.information.magic_db_added"_lang); return true; } } diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 3b034c445..ec5b5f2af 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -15,6 +15,8 @@ #include #include +#include +#include #include #include @@ -83,7 +85,6 @@ namespace hex::plugin::builtin { return langDef; } - ViewPatternEditor::ViewPatternEditor() : View("hex.builtin.view.pattern_editor.name") { this->m_parserRuntime = std::make_unique(); ContentRegistry::PatternLanguage::configureRuntime(*this->m_parserRuntime, nullptr); @@ -196,25 +197,18 @@ namespace hex::plugin::builtin { if (this->m_dangerousFunctionCalled && !ImGui::IsPopupOpen(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str())) { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str()); - this->m_dangerousFunctionCalled = false; - } - if (ImGui::BeginPopupModal(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::NewLine(); - ImGui::TextUnformatted("hex.builtin.view.pattern_editor.dangerous_function.desc"_lang); - ImGui::NewLine(); - - View::confirmButtons( - "hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, + PopupQuestion::open("hex.builtin.view.pattern_editor.dangerous_function.desc"_lang, [this] { this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Allow; ImGui::CloseCurrentPopup(); }, [this] { this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Deny; ImGui::CloseCurrentPopup(); - }); + } + ); - ImGui::EndPopup(); + this->m_dangerousFunctionCalled = false; } View::discardNavigationRequests(); @@ -501,42 +495,6 @@ namespace hex::plugin::builtin { void ViewPatternEditor::drawAlwaysVisible() { auto provider = ImHexApi::Provider::get(); - ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F)); - if (ImGui::BeginPopupModal("hex.builtin.view.pattern_editor.accept_pattern"_lang, &this->m_acceptPatternWindowOpen, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::TextFormattedWrapped("{}", static_cast("hex.builtin.view.pattern_editor.accept_pattern.desc"_lang)); - - std::vector entries; - entries.resize(this->m_possiblePatternFiles.size()); - - for (u32 i = 0; i < entries.size(); i++) { - entries[i] = wolv::util::toUTF8String(this->m_possiblePatternFiles[i].filename()); - } - - if (ImGui::BeginListBox("##patterns_accept", ImVec2(-FLT_MIN, 0))) { - u32 index = 0; - for (auto &path : this->m_possiblePatternFiles) { - if (ImGui::Selectable(wolv::util::toUTF8String(path.filename()).c_str(), index == this->m_selectedPatternFile)) - this->m_selectedPatternFile = index; - index++; - } - - ImGui::EndListBox(); - } - - ImGui::NewLine(); - ImGui::TextUnformatted("hex.builtin.view.pattern_editor.accept_pattern.question"_lang); - - confirmButtons( - "hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, [this, provider] { - this->loadPatternFile(this->m_possiblePatternFiles[this->m_selectedPatternFile], provider); - ImGui::CloseCurrentPopup(); }, [] { ImGui::CloseCurrentPopup(); }); - - if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape))) - ImGui::CloseCurrentPopup(); - - ImGui::EndPopup(); - } - auto open = this->m_sectionWindowDrawer.contains(provider); if (open) { ImGui::SetNextWindowSize(scaled(ImVec2(600, 700)), ImGuiCond_Appearing); @@ -828,7 +786,7 @@ namespace hex::plugin::builtin { if (!this->m_possiblePatternFiles.empty()) { this->m_selectedPatternFile = 0; - EventManager::post("hex.builtin.view.pattern_editor.accept_pattern"_lang); + PopupAcceptPattern::open(this); this->m_acceptPatternWindowOpen = true; } }); @@ -903,7 +861,7 @@ namespace hex::plugin::builtin { } } - View::showFileChooserPopup(paths, { { "Pattern File", "hexpat" } }, false, + PopupFileChooser::open(paths, std::vector{ { "Pattern File", "hexpat" } }, false, [this, provider](const std::fs::path &path) { this->loadPatternFile(path, provider); }); diff --git a/plugins/builtin/source/content/views/view_provider_settings.cpp b/plugins/builtin/source/content/views/view_provider_settings.cpp index 2053aac6f..afa09c313 100644 --- a/plugins/builtin/source/content/views/view_provider_settings.cpp +++ b/plugins/builtin/source/content/views/view_provider_settings.cpp @@ -1,5 +1,7 @@ #include "content/views/view_provider_settings.hpp" +#include + namespace hex::plugin::builtin { ViewProviderSettings::ViewProviderSettings() : hex::View("hex.builtin.view.provider_settings.name") { @@ -43,9 +45,9 @@ namespace hex::plugin::builtin { else { auto errorMessage = provider->getErrorMessage(); if (errorMessage.empty()) { - View::showErrorPopup("hex.builtin.view.provider_settings.load_error"_lang); + PopupError::open("hex.builtin.view.provider_settings.load_error"_lang); } else { - View::showErrorPopup(hex::format("hex.builtin.view.provider_settings.load_error_details"_lang, errorMessage)); + PopupError::open(hex::format("hex.builtin.view.provider_settings.load_error_details"_lang, errorMessage)); } TaskManager::doLater([=] { ImHexApi::Provider::remove(provider); }); } diff --git a/plugins/builtin/source/content/views/view_settings.cpp b/plugins/builtin/source/content/views/view_settings.cpp index 9d81c1693..9a4cd5c48 100644 --- a/plugins/builtin/source/content/views/view_settings.cpp +++ b/plugins/builtin/source/content/views/view_settings.cpp @@ -1,11 +1,12 @@ #include "content/views/view_settings.hpp" #include - #include #include +#include + namespace hex::plugin::builtin { ViewSettings::ViewSettings() : View("hex.builtin.view.settings.name") { @@ -87,7 +88,7 @@ namespace hex::plugin::builtin { this->getWindowOpenState() = false; if (!this->getWindowOpenState() && this->m_restartRequested) { - View::showYesNoQuestionPopup("hex.builtin.view.settings.restart_question"_lang, ImHexApi::System::restartImHex, [] {}); + PopupQuestion::open("hex.builtin.view.settings.restart_question"_lang, ImHexApi::System::restartImHex, [] {}); } } diff --git a/plugins/builtin/source/content/views/view_yara.cpp b/plugins/builtin/source/content/views/view_yara.cpp index cdc1a034b..126dee5ea 100644 --- a/plugins/builtin/source/content/views/view_yara.cpp +++ b/plugins/builtin/source/content/views/view_yara.cpp @@ -8,6 +8,9 @@ #include "content/helpers/provider_extra_data.hpp" +#include +#include + // 's RE type has a zero-sized array, which is not allowed in ISO C++. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" @@ -32,7 +35,7 @@ namespace hex::plugin::builtin { ContentRegistry::FileHandler::add({ ".yar", ".yara" }, [](const auto &path) { for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Yara)) { if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) { - View::showInfoPopup("hex.builtin.view.yara.rule_added"_lang); + PopupInfo::open("hex.builtin.view.yara.rule_added"_lang); return true; } } @@ -132,7 +135,7 @@ namespace hex::plugin::builtin { } } - View::showFileChooserPopup(paths, { { "Yara File", "yara" }, { "Yara File", "yar" } }, true, + PopupFileChooser::open(paths, std::vector{ { "Yara File", "yara" }, { "Yara File", "yar" } }, true, [&](const auto &path) { rules.push_back({ path.filename(), path }); }); diff --git a/plugins/builtin/source/content/welcome_screen.cpp b/plugins/builtin/source/content/welcome_screen.cpp index a3010863e..37c1c9e7b 100644 --- a/plugins/builtin/source/content/welcome_screen.cpp +++ b/plugins/builtin/source/content/welcome_screen.cpp @@ -23,6 +23,9 @@ #include +#include +#include + #include #include #include @@ -59,6 +62,59 @@ namespace hex::plugin::builtin { }; + class PopupRestoreBackup : public Popup { + public: + PopupRestoreBackup() : Popup("hex.builtin.popup.safety_backup.title") { } + + void drawContent() override { + ImGui::TextUnformatted("hex.builtin.welcome.safety_backup.desc"_lang); + ImGui::NewLine(); + + auto width = ImGui::GetWindowWidth(); + ImGui::SetCursorPosX(width / 9); + if (ImGui::Button("hex.builtin.welcome.safety_backup.restore"_lang, ImVec2(width / 3, 0))) { + ProjectFile::load(s_safetyBackupPath); + ProjectFile::clearPath(); + + for (const auto &provider : ImHexApi::Provider::getProviders()) + provider->markDirty(); + + wolv::io::fs::remove(s_safetyBackupPath); + + Popup::close(); + } + ImGui::SameLine(); + ImGui::SetCursorPosX(width / 9 * 5); + if (ImGui::Button("hex.builtin.welcome.safety_backup.delete"_lang, ImVec2(width / 3, 0))) { + wolv::io::fs::remove(s_safetyBackupPath); + + Popup::close(); + } + } + }; + + class PopupTipOfTheDay : public Popup { + public: + PopupTipOfTheDay() : Popup("hex.builtin.popup.tip_of_the_day.title", true, false) { } + + void drawContent() override { + ImGui::Header("hex.builtin.welcome.tip_of_the_day"_lang, true); + + ImGui::TextFormattedWrapped("{}", s_tipOfTheDay.c_str()); + ImGui::NewLine(); + + static bool dontShowAgain = false; + if (ImGui::Checkbox("hex.builtin.common.dont_show_again"_lang, &dontShowAgain)) { + ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", !dontShowAgain); + } + + ImGui::SameLine((ImGui::GetMainViewport()->Size / 3 - ImGui::CalcTextSize("hex.builtin.common.close"_lang) - ImGui::GetStyle().FramePadding).x); + + if (ImGui::Button("hex.builtin.common.close"_lang)) + Popup::close(); + } + }; + static std::atomic s_recentProvidersUpdating = false; static std::list s_recentProviders; @@ -124,7 +180,7 @@ namespace hex::plugin::builtin { provider->loadSettings(recentProvider.data); if (!provider->open() || !provider->isAvailable()) { - View::showErrorPopup("hex.builtin.popup.error.open"_lang); + PopupError::open("hex.builtin.popup.error.open"_lang); TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); }); return; } @@ -160,60 +216,6 @@ namespace hex::plugin::builtin { }); } - static void drawPopups() { - ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F)); - ImGui::SetNextWindowSize(ImGui::GetMainViewport()->Size / 3, ImGuiCond_Appearing); - if (ImGui::BeginPopup("hex.builtin.welcome.tip_of_the_day"_lang)) { - ImGui::Header("hex.builtin.welcome.tip_of_the_day"_lang, true); - - ImGui::TextFormattedWrapped("{}", s_tipOfTheDay.c_str()); - ImGui::NewLine(); - - static bool dontShowAgain = false; - if (ImGui::Checkbox("hex.builtin.common.dont_show_again"_lang, &dontShowAgain)) { - ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", !dontShowAgain); - } - - ImGui::SameLine((ImGui::GetMainViewport()->Size / 3 - ImGui::CalcTextSize("hex.builtin.common.close"_lang) - ImGui::GetStyle().FramePadding).x); - - if (ImGui::Button("hex.builtin.common.close"_lang)) - ImGui::CloseCurrentPopup(); - - ImGui::EndPopup(); - } - - - // Popup for if there is a safety backup present because ImHex crashed - ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F)); - if (ImGui::BeginPopupModal("hex.builtin.welcome.safety_backup.title"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) { - ImGui::TextUnformatted("hex.builtin.welcome.safety_backup.desc"_lang); - ImGui::NewLine(); - - auto width = ImGui::GetWindowWidth(); - ImGui::SetCursorPosX(width / 9); - if (ImGui::Button("hex.builtin.welcome.safety_backup.restore"_lang, ImVec2(width / 3, 0))) { - ProjectFile::load(s_safetyBackupPath); - ProjectFile::clearPath(); - - for (const auto &provider : ImHexApi::Provider::getProviders()) - provider->markDirty(); - - wolv::io::fs::remove(s_safetyBackupPath); - - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - ImGui::SetCursorPosX(width / 9 * 5); - if (ImGui::Button("hex.builtin.welcome.safety_backup.delete"_lang, ImVec2(width / 3, 0))) { - wolv::io::fs::remove(s_safetyBackupPath); - - ImGui::CloseCurrentPopup(); - } - - ImGui::EndPopup(); - } - } - static void drawWelcomeScreenContent() { const auto availableSpace = ImGui::GetContentRegionAvail(); @@ -406,8 +408,6 @@ namespace hex::plugin::builtin { } } ImGui::End(); - - drawPopups(); } static void drawNoViewsBackground() { @@ -515,8 +515,8 @@ namespace hex::plugin::builtin { // documentation of the value above the setting definition int showCheckForUpdates = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.check_for_updates", 2); if (showCheckForUpdates == 2) { - ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.check_for_updates", 0); - View::showYesNoQuestionPopup("hex.builtin.welcome.check_for_updates_text"_lang, + ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.check_for_updates", 0); + PopupQuestion::open("hex.builtin.welcome.check_for_updates_text"_lang, [] { // yes ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.check_for_updates", 1); ImGui::CloseCurrentPopup(); @@ -526,7 +526,7 @@ namespace hex::plugin::builtin { } }); - // clear project context if we go back to the welcome screen + // Clear project context if we go back to the welcome screen EventManager::subscribe([](hex::prv::Provider *oldProvider, hex::prv::Provider *newProvider) { hex::unused(oldProvider); if (newProvider == nullptr) { @@ -559,14 +559,16 @@ namespace hex::plugin::builtin { } }); + // Check for crash backup constexpr static auto CrashBackupFileName = "crash_backup.hexproj"; for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) { if (auto filePath = std::fs::path(path) / CrashBackupFileName; wolv::io::fs::exists(filePath)) { s_safetyBackupPath = filePath; - TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.safety_backup.title"_lang); }); + PopupRestoreBackup::open(); } } + // Tip of the day auto tipsData = romfs::get("tips.json"); if(s_safetyBackupPath.empty() && tipsData.valid()){ auto tipsCategories = nlohmann::json::parse(tipsData.string()); @@ -581,7 +583,7 @@ namespace hex::plugin::builtin { bool showTipOfTheDay = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", 1); if (showTipOfTheDay) - TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.tip_of_the_day"_lang); }); + PopupTipOfTheDay::open(); } } diff --git a/plugins/windows/source/content/providers/process_memory_provider.cpp b/plugins/windows/source/content/providers/process_memory_provider.cpp index 7a48d1c44..97942082d 100644 --- a/plugins/windows/source/content/providers/process_memory_provider.cpp +++ b/plugins/windows/source/content/providers/process_memory_provider.cpp @@ -215,7 +215,7 @@ namespace hex::plugin::windows { if (loadLibraryW != nullptr) { if (auto threadHandle = CreateRemoteThread(this->m_processHandle, nullptr, 0, loadLibraryW, pathAddress, 0, nullptr); threadHandle != nullptr) { WaitForSingleObject(threadHandle, INFINITE); - hex::View::showInfoPopup(hex::format("hex.windows.provider.process_memory.utils.inject_dll.success"_lang, path.filename().string())); + EventManager::post(hex::format("hex.windows.provider.process_memory.utils.inject_dll.success"_lang, path.filename().string())); this->reloadProcessModules(); CloseHandle(threadHandle); return; @@ -224,7 +224,7 @@ namespace hex::plugin::windows { } } - hex::View::showErrorPopup(hex::format("hex.windows.provider.process_memory.utils.inject_dll.failure"_lang, path.filename().string())); + EventManager::post(hex::format("hex.windows.provider.process_memory.utils.inject_dll.failure"_lang, path.filename().string())); }); } } diff --git a/plugins/windows/source/views/view_tty_console.cpp b/plugins/windows/source/views/view_tty_console.cpp index 00fe587b3..154f871dc 100644 --- a/plugins/windows/source/views/view_tty_console.cpp +++ b/plugins/windows/source/views/view_tty_console.cpp @@ -87,7 +87,7 @@ namespace hex::plugin::windows { if (this->m_portHandle == INVALID_HANDLE_VALUE) { if (ImGui::Button("hex.windows.view.tty_console.connect"_lang)) if (!this->connect()) - View::showErrorPopup("hex.windows.view.tty_console.connect_error"_lang); + EventManager::post("hex.windows.view.tty_console.connect_error"_lang); } else { if (ImGui::Button("hex.windows.view.tty_console.disconnect"_lang)) this->disconnect(); @@ -190,7 +190,7 @@ namespace hex::plugin::windows { bool ViewTTYConsole::connect() { if (this->m_comPorts.empty() || static_cast(this->m_selectedPort) >= this->m_comPorts.size()) { - View::showErrorPopup("hex.windows.view.tty_console.no_available_port"_lang); + EventManager::post("hex.windows.view.tty_console.no_available_port"_lang); return true; // If false, connect_error error popup will override this error popup } this->m_portHandle = ::CreateFile((R"(\\.\)" + this->m_comPorts[this->m_selectedPort].first).c_str(),