impr: Update all of ImHex to the new popup system
This commit is contained in:
parent
9c9ac23818
commit
80edaea392
@ -183,10 +183,7 @@ namespace hex {
|
|||||||
EVENT_DEF(RequestCreateProvider, std::string, bool, hex::prv::Provider **);
|
EVENT_DEF(RequestCreateProvider, std::string, bool, hex::prv::Provider **);
|
||||||
EVENT_DEF(RequestInitThemeHandlers);
|
EVENT_DEF(RequestInitThemeHandlers);
|
||||||
|
|
||||||
EVENT_DEF(RequestShowInfoPopup, std::string);
|
EVENT_DEF(RequestOpenInfoPopup, const std::string);
|
||||||
EVENT_DEF(RequestShowErrorPopup, std::string);
|
EVENT_DEF(RequestOpenErrorPopup, const std::string);
|
||||||
EVENT_DEF(RequestShowFatalErrorPopup, std::string);
|
EVENT_DEF(RequestOpenFatalPopup, const std::string);
|
||||||
EVENT_DEF(RequestShowYesNoQuestionPopup, std::string, std::function<void()>, std::function<void()>);
|
|
||||||
EVENT_DEF(RequestShowFileChooserPopup, std::vector<std::fs::path>, std::vector<nfdfilteritem_t>, std::function<void(std::fs::path)>, bool);
|
|
||||||
|
|
||||||
}
|
}
|
@ -108,6 +108,8 @@ namespace hex {
|
|||||||
[[nodiscard]] bool wasInterrupted() const;
|
[[nodiscard]] bool wasInterrupted() const;
|
||||||
[[nodiscard]] bool shouldInterrupt() const;
|
[[nodiscard]] bool shouldInterrupt() const;
|
||||||
|
|
||||||
|
[[nodiscard]] u32 getProgress() const;
|
||||||
|
|
||||||
void interrupt();
|
void interrupt();
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<Task> m_task;
|
std::weak_ptr<Task> m_task;
|
||||||
|
@ -7,55 +7,88 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
#include <hex/ui/imgui_imhex_extensions.h>
|
||||||
|
#include <hex/helpers/utils.hpp>
|
||||||
|
|
||||||
|
#include <hex/api/task.hpp>
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
class PopupBase {
|
namespace impl {
|
||||||
public:
|
|
||||||
explicit PopupBase(std::string unlocalizedName, bool closeButton = true)
|
|
||||||
: m_unlocalizedName(std::move(unlocalizedName)), m_closeButton(closeButton) { }
|
|
||||||
|
|
||||||
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;
|
virtual ~PopupBase() = default;
|
||||||
[[nodiscard]] virtual ImGuiPopupFlags getFlags() const { return ImGuiPopupFlags_None; }
|
|
||||||
|
|
||||||
|
virtual void drawContent() = 0;
|
||||||
|
[[nodiscard]] virtual ImGuiWindowFlags getFlags() const { return ImGuiWindowFlags_None; }
|
||||||
|
|
||||||
[[nodiscard]] static std::vector<std::unique_ptr<PopupBase>> &getOpenPopups() {
|
[[nodiscard]] virtual ImVec2 getMinSize() const {
|
||||||
return s_openPopups;
|
return { 0, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getUnlocalizedName() const {
|
[[nodiscard]] virtual ImVec2 getMaxSize() const {
|
||||||
return this->m_unlocalizedName;
|
return { FLT_MAX, FLT_MAX };
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool hasCloseButton() const {
|
[[nodiscard]] static std::vector<std::unique_ptr<PopupBase>> &getOpenPopups() {
|
||||||
return this->m_closeButton;
|
return s_openPopups;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
[[nodiscard]] const std::string &getUnlocalizedName() const {
|
||||||
static void close() {
|
return this->m_unlocalizedName;
|
||||||
ImGui::CloseCurrentPopup();
|
}
|
||||||
s_openPopups.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::unique_ptr<PopupBase>> s_openPopups;
|
[[nodiscard]] bool hasCloseButton() const {
|
||||||
private:
|
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<std::unique_ptr<PopupBase>> 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<typename T>
|
template<typename T>
|
||||||
class Popup : public PopupBase {
|
class Popup : public impl::PopupBase {
|
||||||
protected:
|
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:
|
public:
|
||||||
virtual ~Popup() = default;
|
|
||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
static void open(Args && ... args) {
|
static void open(Args && ... args) {
|
||||||
|
std::lock_guard lock(s_mutex);
|
||||||
|
|
||||||
auto popup = std::make_unique<T>(std::forward<Args>(args)...);
|
auto popup = std::make_unique<T>(std::forward<Args>(args)...);
|
||||||
|
|
||||||
s_openPopups.emplace_back(std::move(popup));
|
s_openPopups.emplace_back(std::move(popup));
|
||||||
|
@ -34,13 +34,6 @@ namespace hex {
|
|||||||
[[nodiscard]] virtual bool isAvailable() const;
|
[[nodiscard]] virtual bool isAvailable() const;
|
||||||
[[nodiscard]] virtual bool shouldProcess() const { return this->isAvailable() && this->getWindowOpenState(); }
|
[[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<void()> &yesCallback, const std::function<void()> &noCallback);
|
|
||||||
|
|
||||||
static void showFileChooserPopup(const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, bool multiple, const std::function<void(std::fs::path)> &callback);
|
|
||||||
|
|
||||||
[[nodiscard]] virtual bool hasViewMenuItemEntry() const;
|
[[nodiscard]] virtual bool hasViewMenuItemEntry() const;
|
||||||
[[nodiscard]] virtual ImVec2 getMinSize() const;
|
[[nodiscard]] virtual ImVec2 getMinSize() const;
|
||||||
[[nodiscard]] virtual ImVec2 getMaxSize() const;
|
[[nodiscard]] virtual ImVec2 getMaxSize() const;
|
||||||
|
@ -165,6 +165,14 @@ namespace hex {
|
|||||||
task->interrupt();
|
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() {
|
void TaskManager::init() {
|
||||||
for (u32 i = 0; i < std::thread::hardware_concurrency(); i++)
|
for (u32 i = 0; i < std::thread::hardware_concurrency(); i++)
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#include <hex/ui/popup.hpp>
|
#include <hex/ui/popup.hpp>
|
||||||
|
|
||||||
namespace hex {
|
namespace hex::impl {
|
||||||
|
|
||||||
std::vector<std::unique_ptr<PopupBase>> PopupBase::s_openPopups;
|
std::vector<std::unique_ptr<PopupBase>> PopupBase::s_openPopups;
|
||||||
|
std::mutex PopupBase::s_mutex;
|
||||||
|
|
||||||
}
|
}
|
@ -17,33 +17,6 @@ namespace hex {
|
|||||||
return ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isAvailable();
|
return ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::showInfoPopup(const std::string &message) {
|
|
||||||
EventManager::post<RequestShowInfoPopup>(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void View::showErrorPopup(const std::string &message) {
|
|
||||||
EventManager::post<RequestShowErrorPopup>(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void View::showFatalPopup(const std::string &message) {
|
|
||||||
EventManager::post<RequestShowFatalErrorPopup>(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void View::showYesNoQuestionPopup(const std::string &message, const std::function<void()> &yesCallback, const std::function<void()> &noCallback) {
|
|
||||||
EventManager::post<RequestShowYesNoQuestionPopup>(message, yesCallback, noCallback);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void View::showFileChooserPopup(const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, bool multiple, const std::function<void(std::fs::path)> &callback) {
|
|
||||||
if (paths.empty()) {
|
|
||||||
fs::openFileBrowser(fs::DialogMode::Open, validExtensions, [callback](const auto &path) {
|
|
||||||
callback(path);
|
|
||||||
}, {}, multiple);
|
|
||||||
} else {
|
|
||||||
EventManager::post<RequestShowFileChooserPopup>(paths, validExtensions, callback, multiple);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool View::hasViewMenuItemEntry() const {
|
bool View::hasViewMenuItemEntry() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,8 @@ namespace hex {
|
|||||||
|
|
||||||
// Draw popup stack
|
// 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();
|
auto &currPopup = popups.back();
|
||||||
const auto &name = LangEntry(currPopup->getUnlocalizedName());
|
const auto &name = LangEntry(currPopup->getUnlocalizedName());
|
||||||
|
|
||||||
@ -533,10 +534,24 @@ namespace hex {
|
|||||||
ImGui::OpenPopup(name);
|
ImGui::OpenPopup(name);
|
||||||
|
|
||||||
bool open = true;
|
bool open = true;
|
||||||
if (ImGui::BeginPopupModal(name, currPopup->hasCloseButton() ? &open : nullptr, currPopup->getFlags())) {
|
ImGui::SetNextWindowSizeConstraints(currPopup->getMinSize(), currPopup->getMaxSize());
|
||||||
currPopup->drawContent();
|
|
||||||
|
|
||||||
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)
|
if (!open)
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
#include <hex/ui/popup.hpp>
|
||||||
|
|
||||||
|
#include <hex/api/localization.hpp>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
|
class PopupFileChooser : public Popup<PopupFileChooser> {
|
||||||
|
public:
|
||||||
|
PopupFileChooser(const std::vector<std::fs::path> &files, const std::vector<nfdfilteritem_t> &validExtensions, bool multiple, const std::function<void(std::fs::path)> &callback)
|
||||||
|
: hex::Popup<PopupFileChooser>("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<u32> m_indices;
|
||||||
|
std::vector<std::fs::path> m_files;
|
||||||
|
std::function<void(std::fs::path)> m_openCallback;
|
||||||
|
std::vector<nfdfilteritem_t> m_validExtensions;
|
||||||
|
bool m_multiple = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
#include <hex/ui/popup.hpp>
|
||||||
|
|
||||||
|
#include <hex/api/localization.hpp>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class PopupNotification : public Popup<T> {
|
||||||
|
public:
|
||||||
|
PopupNotification(std::string unlocalizedName, std::string message, std::function<void()> function)
|
||||||
|
: hex::Popup<T>(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<void()> m_function;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class PopupInfo : public impl::PopupNotification<PopupInfo> {
|
||||||
|
public:
|
||||||
|
explicit PopupInfo(std::string message)
|
||||||
|
: PopupNotification("hex.builtin.common.info", std::move(message), []() {
|
||||||
|
Popup::close();
|
||||||
|
}) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
class PopupError : public impl::PopupNotification<PopupError> {
|
||||||
|
public:
|
||||||
|
explicit PopupError(std::string message)
|
||||||
|
: PopupNotification("hex.builtin.common.error", std::move(message), []() {
|
||||||
|
Popup::close();
|
||||||
|
}) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
class PopupFatal : public impl::PopupNotification<PopupFatal> {
|
||||||
|
public:
|
||||||
|
explicit PopupFatal(std::string message)
|
||||||
|
: PopupNotification("hex.builtin.common.fatal", std::move(message), []() {
|
||||||
|
ImHexApi::System::closeImHex();
|
||||||
|
Popup::close();
|
||||||
|
}) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
51
plugins/builtin/include/content/popups/popup_question.hpp
Normal file
51
plugins/builtin/include/content/popups/popup_question.hpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include <hex/ui/popup.hpp>
|
||||||
|
|
||||||
|
#include <hex/api/localization.hpp>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
|
class PopupQuestion : public Popup<PopupQuestion> {
|
||||||
|
public:
|
||||||
|
PopupQuestion(std::string message, std::function<void()> yesFunction, std::function<void()> noFunction)
|
||||||
|
: hex::Popup<PopupQuestion>("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<void()> m_yesFunction, m_noFunction;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
#include <hex/ui/popup.hpp>
|
||||||
|
|
||||||
|
#include <hex/api/localization.hpp>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
|
class PopupTasksWaiting : public Popup<PopupTasksWaiting> {
|
||||||
|
public:
|
||||||
|
PopupTasksWaiting()
|
||||||
|
: hex::Popup<PopupTasksWaiting>("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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -1,14 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <hex/ui/view.hpp>
|
#include <hex/ui/view.hpp>
|
||||||
|
#include <hex/providers/provider.hpp>
|
||||||
|
#include <hex/ui/popup.hpp>
|
||||||
|
|
||||||
#include <pl/pattern_language.hpp>
|
#include <pl/pattern_language.hpp>
|
||||||
#include <pl/core/errors/error.hpp>
|
#include <pl/core/errors/error.hpp>
|
||||||
#include <hex/providers/provider.hpp>
|
|
||||||
|
|
||||||
#include <content/helpers/provider_extra_data.hpp>
|
#include <content/helpers/provider_extra_data.hpp>
|
||||||
|
#include <content/providers/memory_file_provider.hpp>
|
||||||
|
|
||||||
#include <ui/hex_editor.hpp>
|
#include <ui/hex_editor.hpp>
|
||||||
#include <ui/pattern_drawer.hpp>
|
#include <ui/pattern_drawer.hpp>
|
||||||
#include <content/providers/memory_file_provider.hpp>
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@ -38,6 +42,54 @@ namespace hex::plugin::builtin {
|
|||||||
Deny
|
Deny
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PopupAcceptPattern : public Popup<PopupAcceptPattern> {
|
||||||
|
public:
|
||||||
|
PopupAcceptPattern(ViewPatternEditor *view) : Popup("hex.builtin.view.pattern_editor.accept_pattern"), m_view(view) {}
|
||||||
|
|
||||||
|
void drawContent() override {
|
||||||
|
ImGui::TextFormattedWrapped("{}", static_cast<const char *>("hex.builtin.view.pattern_editor.accept_pattern.desc"_lang));
|
||||||
|
|
||||||
|
std::vector<std::string> 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:
|
private:
|
||||||
using PlData = ProviderExtraData::Data::PatternLanguage;
|
using PlData = ProviderExtraData::Data::PatternLanguage;
|
||||||
|
|
||||||
|
@ -764,8 +764,8 @@
|
|||||||
"hex.builtin.view.store.row.name",
|
"hex.builtin.view.store.row.name",
|
||||||
"hex.builtin.view.store.tab.constants",
|
"hex.builtin.view.store.tab.constants",
|
||||||
"hex.builtin.view.store.tab.encodings",
|
"hex.builtin.view.store.tab.encodings",
|
||||||
"hex.builtin.view.store.tab.libraries",
|
"hex.builtin.view.store.tab.includes",
|
||||||
"hex.builtin.view.store.tab.magics",
|
"hex.builtin.view.store.tab.magic",
|
||||||
"hex.builtin.view.store.tab.patterns",
|
"hex.builtin.view.store.tab.patterns",
|
||||||
"hex.builtin.view.store.tab.yara",
|
"hex.builtin.view.store.tab.yara",
|
||||||
"hex.builtin.view.store.update",
|
"hex.builtin.view.store.update",
|
||||||
|
@ -806,8 +806,8 @@
|
|||||||
"hex.builtin.view.store.row.name": "Name",
|
"hex.builtin.view.store.row.name": "Name",
|
||||||
"hex.builtin.view.store.tab.constants": "Konstanten",
|
"hex.builtin.view.store.tab.constants": "Konstanten",
|
||||||
"hex.builtin.view.store.tab.encodings": "Encodings",
|
"hex.builtin.view.store.tab.encodings": "Encodings",
|
||||||
"hex.builtin.view.store.tab.libraries": "Libraries",
|
"hex.builtin.view.store.tab.includes": "Libraries",
|
||||||
"hex.builtin.view.store.tab.magics": "Magic Files",
|
"hex.builtin.view.store.tab.magic": "Magic Files",
|
||||||
"hex.builtin.view.store.tab.nodes": "",
|
"hex.builtin.view.store.tab.nodes": "",
|
||||||
"hex.builtin.view.store.tab.patterns": "Patterns",
|
"hex.builtin.view.store.tab.patterns": "Patterns",
|
||||||
"hex.builtin.view.store.tab.themes": "",
|
"hex.builtin.view.store.tab.themes": "",
|
||||||
|
@ -814,8 +814,8 @@
|
|||||||
"hex.builtin.view.store.row.name": "Name",
|
"hex.builtin.view.store.row.name": "Name",
|
||||||
"hex.builtin.view.store.tab.constants": "Constants",
|
"hex.builtin.view.store.tab.constants": "Constants",
|
||||||
"hex.builtin.view.store.tab.encodings": "Encodings",
|
"hex.builtin.view.store.tab.encodings": "Encodings",
|
||||||
"hex.builtin.view.store.tab.libraries": "Libraries",
|
"hex.builtin.view.store.tab.includes": "Libraries",
|
||||||
"hex.builtin.view.store.tab.magics": "Magic Files",
|
"hex.builtin.view.store.tab.magic": "Magic Files",
|
||||||
"hex.builtin.view.store.tab.nodes": "Nodes",
|
"hex.builtin.view.store.tab.nodes": "Nodes",
|
||||||
"hex.builtin.view.store.tab.patterns": "Patterns",
|
"hex.builtin.view.store.tab.patterns": "Patterns",
|
||||||
"hex.builtin.view.store.tab.themes": "Themes",
|
"hex.builtin.view.store.tab.themes": "Themes",
|
||||||
|
@ -806,8 +806,8 @@
|
|||||||
"hex.builtin.view.store.row.name": "Nome",
|
"hex.builtin.view.store.row.name": "Nome",
|
||||||
"hex.builtin.view.store.tab.constants": "Costanti",
|
"hex.builtin.view.store.tab.constants": "Costanti",
|
||||||
"hex.builtin.view.store.tab.encodings": "Encodings",
|
"hex.builtin.view.store.tab.encodings": "Encodings",
|
||||||
"hex.builtin.view.store.tab.libraries": "Librerie",
|
"hex.builtin.view.store.tab.includes": "Librerie",
|
||||||
"hex.builtin.view.store.tab.magics": "File Magici",
|
"hex.builtin.view.store.tab.magic": "File Magici",
|
||||||
"hex.builtin.view.store.tab.nodes": "",
|
"hex.builtin.view.store.tab.nodes": "",
|
||||||
"hex.builtin.view.store.tab.patterns": "Modelli",
|
"hex.builtin.view.store.tab.patterns": "Modelli",
|
||||||
"hex.builtin.view.store.tab.themes": "",
|
"hex.builtin.view.store.tab.themes": "",
|
||||||
|
@ -806,8 +806,8 @@
|
|||||||
"hex.builtin.view.store.row.name": "名前",
|
"hex.builtin.view.store.row.name": "名前",
|
||||||
"hex.builtin.view.store.tab.constants": "定数",
|
"hex.builtin.view.store.tab.constants": "定数",
|
||||||
"hex.builtin.view.store.tab.encodings": "エンコード",
|
"hex.builtin.view.store.tab.encodings": "エンコード",
|
||||||
"hex.builtin.view.store.tab.libraries": "ライブラリ",
|
"hex.builtin.view.store.tab.includes": "ライブラリ",
|
||||||
"hex.builtin.view.store.tab.magics": "Magicファイル",
|
"hex.builtin.view.store.tab.magic": "Magicファイル",
|
||||||
"hex.builtin.view.store.tab.nodes": "",
|
"hex.builtin.view.store.tab.nodes": "",
|
||||||
"hex.builtin.view.store.tab.patterns": "パターン",
|
"hex.builtin.view.store.tab.patterns": "パターン",
|
||||||
"hex.builtin.view.store.tab.themes": "",
|
"hex.builtin.view.store.tab.themes": "",
|
||||||
|
@ -806,8 +806,8 @@
|
|||||||
"hex.builtin.view.store.row.name": "이름",
|
"hex.builtin.view.store.row.name": "이름",
|
||||||
"hex.builtin.view.store.tab.constants": "상수",
|
"hex.builtin.view.store.tab.constants": "상수",
|
||||||
"hex.builtin.view.store.tab.encodings": "인코딩",
|
"hex.builtin.view.store.tab.encodings": "인코딩",
|
||||||
"hex.builtin.view.store.tab.libraries": "라이브러리",
|
"hex.builtin.view.store.tab.includes": "라이브러리",
|
||||||
"hex.builtin.view.store.tab.magics": "Magic 파일",
|
"hex.builtin.view.store.tab.magic": "Magic 파일",
|
||||||
"hex.builtin.view.store.tab.nodes": "",
|
"hex.builtin.view.store.tab.nodes": "",
|
||||||
"hex.builtin.view.store.tab.patterns": "패턴",
|
"hex.builtin.view.store.tab.patterns": "패턴",
|
||||||
"hex.builtin.view.store.tab.themes": "",
|
"hex.builtin.view.store.tab.themes": "",
|
||||||
|
@ -806,8 +806,8 @@
|
|||||||
"hex.builtin.view.store.row.name": "Nome",
|
"hex.builtin.view.store.row.name": "Nome",
|
||||||
"hex.builtin.view.store.tab.constants": "Constantes",
|
"hex.builtin.view.store.tab.constants": "Constantes",
|
||||||
"hex.builtin.view.store.tab.encodings": "Codificações",
|
"hex.builtin.view.store.tab.encodings": "Codificações",
|
||||||
"hex.builtin.view.store.tab.libraries": "Bibliotecas",
|
"hex.builtin.view.store.tab.includes": "Bibliotecas",
|
||||||
"hex.builtin.view.store.tab.magics": "Arquivos Mágicos",
|
"hex.builtin.view.store.tab.magic": "Arquivos Mágicos",
|
||||||
"hex.builtin.view.store.tab.nodes": "",
|
"hex.builtin.view.store.tab.nodes": "",
|
||||||
"hex.builtin.view.store.tab.patterns": "Padrões",
|
"hex.builtin.view.store.tab.patterns": "Padrões",
|
||||||
"hex.builtin.view.store.tab.themes": "",
|
"hex.builtin.view.store.tab.themes": "",
|
||||||
|
@ -770,8 +770,8 @@
|
|||||||
"hex.builtin.view.store.row.name": "名称",
|
"hex.builtin.view.store.row.name": "名称",
|
||||||
"hex.builtin.view.store.tab.constants": "常量",
|
"hex.builtin.view.store.tab.constants": "常量",
|
||||||
"hex.builtin.view.store.tab.encodings": "编码",
|
"hex.builtin.view.store.tab.encodings": "编码",
|
||||||
"hex.builtin.view.store.tab.libraries": "库",
|
"hex.builtin.view.store.tab.includes": "库",
|
||||||
"hex.builtin.view.store.tab.magics": "LibMagic 数据库",
|
"hex.builtin.view.store.tab.magic": "LibMagic 数据库",
|
||||||
"hex.builtin.view.store.tab.patterns": "模式",
|
"hex.builtin.view.store.tab.patterns": "模式",
|
||||||
"hex.builtin.view.store.tab.yara": "Yara 规则",
|
"hex.builtin.view.store.tab.yara": "Yara 规则",
|
||||||
"hex.builtin.view.store.update": "更新",
|
"hex.builtin.view.store.update": "更新",
|
||||||
|
@ -806,8 +806,8 @@
|
|||||||
"hex.builtin.view.store.row.name": "名稱",
|
"hex.builtin.view.store.row.name": "名稱",
|
||||||
"hex.builtin.view.store.tab.constants": "常數",
|
"hex.builtin.view.store.tab.constants": "常數",
|
||||||
"hex.builtin.view.store.tab.encodings": "編碼",
|
"hex.builtin.view.store.tab.encodings": "編碼",
|
||||||
"hex.builtin.view.store.tab.libraries": "程式庫",
|
"hex.builtin.view.store.tab.includes": "程式庫",
|
||||||
"hex.builtin.view.store.tab.magics": "Magic Files",
|
"hex.builtin.view.store.tab.magic": "Magic Files",
|
||||||
"hex.builtin.view.store.tab.nodes": "",
|
"hex.builtin.view.store.tab.nodes": "",
|
||||||
"hex.builtin.view.store.tab.patterns": "模式",
|
"hex.builtin.view.store.tab.patterns": "模式",
|
||||||
"hex.builtin.view.store.tab.themes": "",
|
"hex.builtin.view.store.tab.themes": "",
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
|
|
||||||
#include <wolv/io/fs.hpp>
|
#include <wolv/io/fs.hpp>
|
||||||
|
|
||||||
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
#include <content/popups/popup_question.hpp>
|
||||||
|
#include <content/popups/popup_tasks_waiting.hpp>
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
static void openFile(const std::fs::path &path) {
|
static void openFile(const std::fs::path &path) {
|
||||||
@ -30,13 +34,21 @@ namespace hex::plugin::builtin {
|
|||||||
EventManager::subscribe<EventWindowClosing>([](GLFWwindow *window) {
|
EventManager::subscribe<EventWindowClosing>([](GLFWwindow *window) {
|
||||||
if (ImHexApi::Provider::isDirty()) {
|
if (ImHexApi::Provider::isDirty()) {
|
||||||
glfwSetWindowShouldClose(window, GLFW_FALSE);
|
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) {
|
} else if (TaskManager::getRunningTaskCount() > 0 || TaskManager::getRunningBackgroundTaskCount() > 0) {
|
||||||
glfwSetWindowShouldClose(window, GLFW_FALSE);
|
glfwSetWindowShouldClose(window, GLFW_FALSE);
|
||||||
TaskManager::doLater([] {
|
TaskManager::doLater([] {
|
||||||
for (auto &task : TaskManager::getRunningTasks())
|
for (auto &task : TaskManager::getRunningTasks())
|
||||||
task->interrupt();
|
task->interrupt();
|
||||||
ImGui::OpenPopup("hex.builtin.popup.waiting_for_tasks.title"_lang);
|
PopupTasksWaiting::open();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -44,7 +56,15 @@ namespace hex::plugin::builtin {
|
|||||||
EventManager::subscribe<EventProviderClosing>([](hex::prv::Provider *provider, bool *shouldClose) {
|
EventManager::subscribe<EventProviderClosing>([](hex::prv::Provider *provider, bool *shouldClose) {
|
||||||
if (provider->isDirty()) {
|
if (provider->isDirty()) {
|
||||||
*shouldClose = false;
|
*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"} },
|
fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"} },
|
||||||
[](const auto &path) {
|
[](const auto &path) {
|
||||||
if (!ProjectFile::load(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;
|
return;
|
||||||
}
|
}
|
||||||
if (!provider->open()) {
|
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); });
|
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -106,7 +126,7 @@ namespace hex::plugin::builtin {
|
|||||||
EventManager::post<RequestOpenPopup>(View::toWindowName("hex.builtin.view.provider_settings.load_popup"));
|
EventManager::post<RequestOpenPopup>(View::toWindowName("hex.builtin.view.provider_settings.load_popup"));
|
||||||
else {
|
else {
|
||||||
if (!provider->open() || !provider->isAvailable()) {
|
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); });
|
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -123,11 +143,23 @@ namespace hex::plugin::builtin {
|
|||||||
ImHexApi::HexEditor::impl::setCurrentSelection(region);
|
ImHexApi::HexEditor::impl::setCurrentSelection(region);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
EventManager::subscribe<RequestOpenInfoPopup>([](const std::string &message) {
|
||||||
|
PopupInfo::open(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
EventManager::subscribe<RequestOpenErrorPopup>([](const std::string &message) {
|
||||||
|
PopupError::open(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
EventManager::subscribe<RequestOpenFatalPopup>([](const std::string &message) {
|
||||||
|
PopupFatal::open(message);
|
||||||
|
});
|
||||||
|
|
||||||
fs::setFileBrowserErrorCallback([](const std::string& errMsg){
|
fs::setFileBrowserErrorCallback([](const std::string& errMsg){
|
||||||
#if defined(NFD_PORTAL)
|
#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
|
#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
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <hex/api/project_file_manager.hpp>
|
#include <hex/api/project_file_manager.hpp>
|
||||||
#include <hex/helpers/logger.hpp>
|
#include <hex/helpers/logger.hpp>
|
||||||
|
|
||||||
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
@ -10,7 +11,7 @@ namespace hex::plugin::builtin {
|
|||||||
fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"} },
|
fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"} },
|
||||||
[](const auto &path) {
|
[](const auto &path) {
|
||||||
if (!ProjectFile::load(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() {
|
void saveProject() {
|
||||||
if (ImHexApi::Provider::isValid() && ProjectFile::hasPath()) {
|
if (ImHexApi::Provider::isValid() && ProjectFile::hasPath()) {
|
||||||
if (!ProjectFile::store()) {
|
if (!ProjectFile::store()) {
|
||||||
View::showErrorPopup("hex.builtin.popup.error.project.save"_lang);
|
PopupError::open("hex.builtin.popup.error.project.save"_lang);
|
||||||
} else {
|
} else {
|
||||||
log::debug("Project saved");
|
log::debug("Project saved");
|
||||||
}
|
}
|
||||||
@ -33,7 +34,7 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ProjectFile::store(path)) {
|
if (!ProjectFile::store(path)) {
|
||||||
View::showErrorPopup("hex.builtin.popup.error.project.save"_lang);
|
PopupError::open("hex.builtin.popup.error.project.save"_lang);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <hex/helpers/patches.hpp>
|
#include <hex/helpers/patches.hpp>
|
||||||
|
|
||||||
#include "content/global_actions.hpp"
|
#include "content/global_actions.hpp"
|
||||||
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
|
||||||
#include <wolv/io/file.hpp>
|
#include <wolv/io/file.hpp>
|
||||||
|
|
||||||
@ -38,19 +39,19 @@ namespace hex::plugin::builtin {
|
|||||||
TaskManager::doLater([error]{
|
TaskManager::doLater([error]{
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case IPSError::InvalidPatchHeader:
|
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;
|
break;
|
||||||
case IPSError::AddressOutOfRange:
|
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;
|
break;
|
||||||
case IPSError::PatchTooLarge:
|
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;
|
break;
|
||||||
case IPSError::InvalidPatchFormat:
|
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;
|
break;
|
||||||
case IPSError::MissingEOF:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -65,7 +66,7 @@ namespace hex::plugin::builtin {
|
|||||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||||
wolv::io::File inputFile(path, wolv::io::File::Mode::Read);
|
wolv::io::File inputFile(path, wolv::io::File::Mode::Read);
|
||||||
if (!inputFile.isValid()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,19 +76,19 @@ namespace hex::plugin::builtin {
|
|||||||
auto data = crypt::decode64(base64);
|
auto data = crypt::decode64(base64);
|
||||||
|
|
||||||
if (data.empty())
|
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 {
|
else {
|
||||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const std::fs::path &path) {
|
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const std::fs::path &path) {
|
||||||
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);
|
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);
|
||||||
|
|
||||||
if (!outputFile.isValid())
|
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);
|
outputFile.writeVector(data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} 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();
|
auto patchData = wolv::io::File(path, wolv::io::File::Mode::Read).readVector();
|
||||||
|
|
||||||
if (patchData.size() != provider->getActualSize()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +192,7 @@ namespace hex::plugin::builtin {
|
|||||||
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);
|
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);
|
||||||
if (!outputFile.isValid()) {
|
if (!outputFile.isValid()) {
|
||||||
TaskManager::doLater([] {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@ -227,7 +228,7 @@ namespace hex::plugin::builtin {
|
|||||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
|
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
|
||||||
auto file = wolv::io::File(path, wolv::io::File::Mode::Create);
|
auto file = wolv::io::File(path, wolv::io::File::Mode::Create);
|
||||||
if (!file.isValid()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +261,7 @@ namespace hex::plugin::builtin {
|
|||||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
|
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
|
||||||
auto file = wolv::io::File(path, wolv::io::File::Mode::Create);
|
auto file = wolv::io::File(path, wolv::io::File::Mode::Create);
|
||||||
if (!file.isValid()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <llvm/Demangle/Demangle.h>
|
#include <llvm/Demangle/Demangle.h>
|
||||||
#include <content/helpers/math_evaluator.hpp>
|
#include <content/helpers/math_evaluator.hpp>
|
||||||
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
@ -646,11 +647,11 @@ namespace hex::plugin::builtin {
|
|||||||
json["data"]["file"]["metadata"]["size"]["readable"]
|
json["data"]["file"]["metadata"]["size"]["readable"]
|
||||||
});
|
});
|
||||||
} catch (...) {
|
} 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) {
|
} else if (response.getStatusCode() == 0) {
|
||||||
// Canceled by user, no action needed
|
// 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 = {};
|
uploadProcess = {};
|
||||||
currFile.clear();
|
currFile.clear();
|
||||||
@ -772,7 +773,7 @@ namespace hex::plugin::builtin {
|
|||||||
wolv::io::File file(selectedFile, wolv::io::File::Mode::Write);
|
wolv::io::File file(selectedFile, wolv::io::File::Mode::Write);
|
||||||
|
|
||||||
if (!file.isValid()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -846,7 +847,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
file.remove();
|
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);
|
wolv::io::File file(selectedFile, wolv::io::File::Mode::Read);
|
||||||
|
|
||||||
if (!file.isValid()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.getSize() < splitSize) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,7 +959,7 @@ namespace hex::plugin::builtin {
|
|||||||
wolv::io::File partFile(path, wolv::io::File::Mode::Create);
|
wolv::io::File partFile(path, wolv::io::File::Mode::Create);
|
||||||
|
|
||||||
if (!partFile.isValid()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,7 +972,7 @@ namespace hex::plugin::builtin {
|
|||||||
index++;
|
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);
|
wolv::io::File output(outputPath, wolv::io::File::Mode::Create);
|
||||||
|
|
||||||
if (!output.isValid()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1084,7 +1085,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
wolv::io::File input(file, wolv::io::File::Mode::Read);
|
wolv::io::File input(file, wolv::io::File::Mode::Read);
|
||||||
if (!input.isValid()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1100,7 +1101,7 @@ namespace hex::plugin::builtin {
|
|||||||
selectedIndex = 0;
|
selectedIndex = 0;
|
||||||
outputPath.clear();
|
outputPath.clear();
|
||||||
|
|
||||||
View::showInfoPopup("hex.builtin.tools.file_tools.combiner.success"_lang);
|
PopupInfo::open("hex.builtin.tools.file_tools.combiner.success"_lang);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,193 +12,16 @@
|
|||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
#include <hex/ui/imgui_imhex_extensions.h>
|
#include <hex/ui/imgui_imhex_extensions.h>
|
||||||
|
|
||||||
|
#include <content/popups/popup_tasks_waiting.hpp>
|
||||||
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
static std::string s_popupMessage;
|
|
||||||
static std::function<void()> s_yesCallback, s_noCallback;
|
|
||||||
static std::set<u32> s_selectableFileIndices;
|
|
||||||
static std::vector<std::fs::path> s_selectableFiles;
|
|
||||||
static std::function<void(std::fs::path)> s_selectableFileOpenCallback;
|
|
||||||
static std::vector<nfdfilteritem_t> s_selectableFilesValidExtensions;
|
|
||||||
static bool s_selectableFileMultiple;
|
|
||||||
|
|
||||||
static void drawGlobalPopups() {
|
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
|
// Task exception popup
|
||||||
for (const auto &task : TaskManager::getRunningTasks()) {
|
for (const auto &task : TaskManager::getRunningTasks()) {
|
||||||
if (task->hadException()) {
|
if (task->hadException()) {
|
||||||
EventManager::post<RequestShowErrorPopup>(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();
|
task->clearException();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -207,49 +30,6 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
void addGlobalUIItems() {
|
void addGlobalUIItems() {
|
||||||
EventManager::subscribe<EventFrameEnd>(drawGlobalPopups);
|
EventManager::subscribe<EventFrameEnd>(drawGlobalPopups);
|
||||||
|
|
||||||
EventManager::subscribe<RequestShowInfoPopup>([](const std::string &message) {
|
|
||||||
s_popupMessage = message;
|
|
||||||
|
|
||||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.info"_lang); });
|
|
||||||
});
|
|
||||||
|
|
||||||
EventManager::subscribe<RequestShowErrorPopup>([](const std::string &message) {
|
|
||||||
s_popupMessage = message;
|
|
||||||
|
|
||||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.error"_lang); });
|
|
||||||
});
|
|
||||||
|
|
||||||
EventManager::subscribe<RequestShowFatalErrorPopup>([](const std::string &message) {
|
|
||||||
s_popupMessage = message;
|
|
||||||
|
|
||||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.fatal"_lang); });
|
|
||||||
});
|
|
||||||
|
|
||||||
EventManager::subscribe<RequestShowYesNoQuestionPopup>([](const std::string &message, const std::function<void()> &yesCallback, const std::function<void()> &noCallback) {
|
|
||||||
s_popupMessage = message;
|
|
||||||
|
|
||||||
s_yesCallback = yesCallback;
|
|
||||||
s_noCallback = noCallback;
|
|
||||||
|
|
||||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.question"_lang); });
|
|
||||||
});
|
|
||||||
|
|
||||||
EventManager::subscribe<RequestShowFileChooserPopup>([](const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &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() {
|
void addFooterItems() {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <content/providers/view_provider.hpp>
|
#include <content/providers/view_provider.hpp>
|
||||||
#include <content/helpers/math_evaluator.hpp>
|
#include <content/helpers/math_evaluator.hpp>
|
||||||
|
#include <content/popups/popup_file_chooser.hpp>
|
||||||
|
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
@ -1013,7 +1014,7 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
View::showFileChooserPopup(paths, { {"Thingy Table File", "tbl"} }, false,
|
PopupFileChooser::open(paths, std::vector<nfdfilteritem_t>{ {"Thingy Table File", "tbl"} }, false,
|
||||||
[this](const auto &path) {
|
[this](const auto &path) {
|
||||||
TaskManager::createTask("Loading encoding file", 0, [this, path](auto&) {
|
TaskManager::createTask("Loading encoding file", 0, [this, path](auto&) {
|
||||||
auto encoding = EncodingFile(EncodingFile::Type::Thingy, path);
|
auto encoding = EncodingFile(EncodingFile::Type::Thingy, path);
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
#include <implot.h>
|
#include <implot.h>
|
||||||
|
|
||||||
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
using namespace hex::literals;
|
using namespace hex::literals;
|
||||||
@ -47,7 +49,7 @@ namespace hex::plugin::builtin {
|
|||||||
ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) {
|
ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) {
|
||||||
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Magic)) {
|
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Magic)) {
|
||||||
if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include <hex/helpers/magic.hpp>
|
#include <hex/helpers/magic.hpp>
|
||||||
|
|
||||||
#include <content/helpers/provider_extra_data.hpp>
|
#include <content/helpers/provider_extra_data.hpp>
|
||||||
|
#include <content/popups/popup_file_chooser.hpp>
|
||||||
|
#include <content/popups/popup_question.hpp>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@ -83,7 +85,6 @@ namespace hex::plugin::builtin {
|
|||||||
return langDef;
|
return langDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ViewPatternEditor::ViewPatternEditor() : View("hex.builtin.view.pattern_editor.name") {
|
ViewPatternEditor::ViewPatternEditor() : View("hex.builtin.view.pattern_editor.name") {
|
||||||
this->m_parserRuntime = std::make_unique<pl::PatternLanguage>();
|
this->m_parserRuntime = std::make_unique<pl::PatternLanguage>();
|
||||||
ContentRegistry::PatternLanguage::configureRuntime(*this->m_parserRuntime, nullptr);
|
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())) {
|
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());
|
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)) {
|
PopupQuestion::open("hex.builtin.view.pattern_editor.dangerous_function.desc"_lang,
|
||||||
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,
|
|
||||||
[this] {
|
[this] {
|
||||||
this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Allow;
|
this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Allow;
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}, [this] {
|
}, [this] {
|
||||||
this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Deny;
|
this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Deny;
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
ImGui::EndPopup();
|
this->m_dangerousFunctionCalled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
View::discardNavigationRequests();
|
View::discardNavigationRequests();
|
||||||
@ -501,42 +495,6 @@ namespace hex::plugin::builtin {
|
|||||||
void ViewPatternEditor::drawAlwaysVisible() {
|
void ViewPatternEditor::drawAlwaysVisible() {
|
||||||
auto provider = ImHexApi::Provider::get();
|
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<const char *>("hex.builtin.view.pattern_editor.accept_pattern.desc"_lang));
|
|
||||||
|
|
||||||
std::vector<std::string> 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);
|
auto open = this->m_sectionWindowDrawer.contains(provider);
|
||||||
if (open) {
|
if (open) {
|
||||||
ImGui::SetNextWindowSize(scaled(ImVec2(600, 700)), ImGuiCond_Appearing);
|
ImGui::SetNextWindowSize(scaled(ImVec2(600, 700)), ImGuiCond_Appearing);
|
||||||
@ -828,7 +786,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
if (!this->m_possiblePatternFiles.empty()) {
|
if (!this->m_possiblePatternFiles.empty()) {
|
||||||
this->m_selectedPatternFile = 0;
|
this->m_selectedPatternFile = 0;
|
||||||
EventManager::post<RequestOpenPopup>("hex.builtin.view.pattern_editor.accept_pattern"_lang);
|
PopupAcceptPattern::open(this);
|
||||||
this->m_acceptPatternWindowOpen = true;
|
this->m_acceptPatternWindowOpen = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -903,7 +861,7 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
View::showFileChooserPopup(paths, { { "Pattern File", "hexpat" } }, false,
|
PopupFileChooser::open(paths, std::vector<nfdfilteritem_t>{ { "Pattern File", "hexpat" } }, false,
|
||||||
[this, provider](const std::fs::path &path) {
|
[this, provider](const std::fs::path &path) {
|
||||||
this->loadPatternFile(path, provider);
|
this->loadPatternFile(path, provider);
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "content/views/view_provider_settings.hpp"
|
#include "content/views/view_provider_settings.hpp"
|
||||||
|
|
||||||
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
ViewProviderSettings::ViewProviderSettings() : hex::View("hex.builtin.view.provider_settings.name") {
|
ViewProviderSettings::ViewProviderSettings() : hex::View("hex.builtin.view.provider_settings.name") {
|
||||||
@ -43,9 +45,9 @@ namespace hex::plugin::builtin {
|
|||||||
else {
|
else {
|
||||||
auto errorMessage = provider->getErrorMessage();
|
auto errorMessage = provider->getErrorMessage();
|
||||||
if (errorMessage.empty()) {
|
if (errorMessage.empty()) {
|
||||||
View::showErrorPopup("hex.builtin.view.provider_settings.load_error"_lang);
|
PopupError::open("hex.builtin.view.provider_settings.load_error"_lang);
|
||||||
} else {
|
} 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); });
|
TaskManager::doLater([=] { ImHexApi::Provider::remove(provider); });
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
#include "content/views/view_settings.hpp"
|
#include "content/views/view_settings.hpp"
|
||||||
|
|
||||||
#include <hex/api/content_registry.hpp>
|
#include <hex/api/content_registry.hpp>
|
||||||
|
|
||||||
#include <hex/helpers/logger.hpp>
|
#include <hex/helpers/logger.hpp>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include <content/popups/popup_question.hpp>
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
ViewSettings::ViewSettings() : View("hex.builtin.view.settings.name") {
|
ViewSettings::ViewSettings() : View("hex.builtin.view.settings.name") {
|
||||||
@ -87,7 +88,7 @@ namespace hex::plugin::builtin {
|
|||||||
this->getWindowOpenState() = false;
|
this->getWindowOpenState() = false;
|
||||||
|
|
||||||
if (!this->getWindowOpenState() && this->m_restartRequested) {
|
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, [] {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
|
|
||||||
#include "content/helpers/provider_extra_data.hpp"
|
#include "content/helpers/provider_extra_data.hpp"
|
||||||
|
|
||||||
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
#include <content/popups/popup_file_chooser.hpp>
|
||||||
|
|
||||||
// <yara/types.h>'s RE type has a zero-sized array, which is not allowed in ISO C++.
|
// <yara/types.h>'s RE type has a zero-sized array, which is not allowed in ISO C++.
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||||
@ -32,7 +35,7 @@ namespace hex::plugin::builtin {
|
|||||||
ContentRegistry::FileHandler::add({ ".yar", ".yara" }, [](const auto &path) {
|
ContentRegistry::FileHandler::add({ ".yar", ".yara" }, [](const auto &path) {
|
||||||
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Yara)) {
|
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Yara)) {
|
||||||
if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) {
|
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;
|
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<nfdfilteritem_t>{ { "Yara File", "yara" }, { "Yara File", "yar" } }, true,
|
||||||
[&](const auto &path) {
|
[&](const auto &path) {
|
||||||
rules.push_back({ path.filename(), path });
|
rules.push_back({ path.filename(), path });
|
||||||
});
|
});
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
|
|
||||||
#include <fonts/codicons_font.h>
|
#include <fonts/codicons_font.h>
|
||||||
|
|
||||||
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
#include <content/popups/popup_question.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
@ -59,6 +62,59 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PopupRestoreBackup : public Popup<PopupRestoreBackup> {
|
||||||
|
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<PopupTipOfTheDay> {
|
||||||
|
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<bool> s_recentProvidersUpdating = false;
|
static std::atomic<bool> s_recentProvidersUpdating = false;
|
||||||
static std::list<RecentProvider> s_recentProviders;
|
static std::list<RecentProvider> s_recentProviders;
|
||||||
|
|
||||||
@ -124,7 +180,7 @@ namespace hex::plugin::builtin {
|
|||||||
provider->loadSettings(recentProvider.data);
|
provider->loadSettings(recentProvider.data);
|
||||||
|
|
||||||
if (!provider->open() || !provider->isAvailable()) {
|
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); });
|
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||||
return;
|
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() {
|
static void drawWelcomeScreenContent() {
|
||||||
const auto availableSpace = ImGui::GetContentRegionAvail();
|
const auto availableSpace = ImGui::GetContentRegionAvail();
|
||||||
|
|
||||||
@ -406,8 +408,6 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
drawPopups();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawNoViewsBackground() {
|
static void drawNoViewsBackground() {
|
||||||
@ -515,8 +515,8 @@ namespace hex::plugin::builtin {
|
|||||||
// documentation of the value above the setting definition
|
// 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);
|
int showCheckForUpdates = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.check_for_updates", 2);
|
||||||
if (showCheckForUpdates == 2) {
|
if (showCheckForUpdates == 2) {
|
||||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.check_for_updates", 0);
|
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,
|
PopupQuestion::open("hex.builtin.welcome.check_for_updates_text"_lang,
|
||||||
[] { // yes
|
[] { // yes
|
||||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.check_for_updates", 1);
|
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.check_for_updates", 1);
|
||||||
ImGui::CloseCurrentPopup();
|
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<EventProviderChanged>([](hex::prv::Provider *oldProvider, hex::prv::Provider *newProvider) {
|
EventManager::subscribe<EventProviderChanged>([](hex::prv::Provider *oldProvider, hex::prv::Provider *newProvider) {
|
||||||
hex::unused(oldProvider);
|
hex::unused(oldProvider);
|
||||||
if (newProvider == nullptr) {
|
if (newProvider == nullptr) {
|
||||||
@ -559,14 +559,16 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check for crash backup
|
||||||
constexpr static auto CrashBackupFileName = "crash_backup.hexproj";
|
constexpr static auto CrashBackupFileName = "crash_backup.hexproj";
|
||||||
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) {
|
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) {
|
||||||
if (auto filePath = std::fs::path(path) / CrashBackupFileName; wolv::io::fs::exists(filePath)) {
|
if (auto filePath = std::fs::path(path) / CrashBackupFileName; wolv::io::fs::exists(filePath)) {
|
||||||
s_safetyBackupPath = 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");
|
auto tipsData = romfs::get("tips.json");
|
||||||
if(s_safetyBackupPath.empty() && tipsData.valid()){
|
if(s_safetyBackupPath.empty() && tipsData.valid()){
|
||||||
auto tipsCategories = nlohmann::json::parse(tipsData.string());
|
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);
|
bool showTipOfTheDay = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", 1);
|
||||||
if (showTipOfTheDay)
|
if (showTipOfTheDay)
|
||||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.tip_of_the_day"_lang); });
|
PopupTipOfTheDay::open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ namespace hex::plugin::windows {
|
|||||||
if (loadLibraryW != nullptr) {
|
if (loadLibraryW != nullptr) {
|
||||||
if (auto threadHandle = CreateRemoteThread(this->m_processHandle, nullptr, 0, loadLibraryW, pathAddress, 0, nullptr); threadHandle != nullptr) {
|
if (auto threadHandle = CreateRemoteThread(this->m_processHandle, nullptr, 0, loadLibraryW, pathAddress, 0, nullptr); threadHandle != nullptr) {
|
||||||
WaitForSingleObject(threadHandle, INFINITE);
|
WaitForSingleObject(threadHandle, INFINITE);
|
||||||
hex::View::showInfoPopup(hex::format("hex.windows.provider.process_memory.utils.inject_dll.success"_lang, path.filename().string()));
|
EventManager::post<RequestOpenErrorPopup>(hex::format("hex.windows.provider.process_memory.utils.inject_dll.success"_lang, path.filename().string()));
|
||||||
this->reloadProcessModules();
|
this->reloadProcessModules();
|
||||||
CloseHandle(threadHandle);
|
CloseHandle(threadHandle);
|
||||||
return;
|
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<RequestOpenErrorPopup>(hex::format("hex.windows.provider.process_memory.utils.inject_dll.failure"_lang, path.filename().string()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ namespace hex::plugin::windows {
|
|||||||
if (this->m_portHandle == INVALID_HANDLE_VALUE) {
|
if (this->m_portHandle == INVALID_HANDLE_VALUE) {
|
||||||
if (ImGui::Button("hex.windows.view.tty_console.connect"_lang))
|
if (ImGui::Button("hex.windows.view.tty_console.connect"_lang))
|
||||||
if (!this->connect())
|
if (!this->connect())
|
||||||
View::showErrorPopup("hex.windows.view.tty_console.connect_error"_lang);
|
EventManager::post<RequestOpenErrorPopup>("hex.windows.view.tty_console.connect_error"_lang);
|
||||||
} else {
|
} else {
|
||||||
if (ImGui::Button("hex.windows.view.tty_console.disconnect"_lang))
|
if (ImGui::Button("hex.windows.view.tty_console.disconnect"_lang))
|
||||||
this->disconnect();
|
this->disconnect();
|
||||||
@ -190,7 +190,7 @@ namespace hex::plugin::windows {
|
|||||||
|
|
||||||
bool ViewTTYConsole::connect() {
|
bool ViewTTYConsole::connect() {
|
||||||
if (this->m_comPorts.empty() || static_cast<size_t>(this->m_selectedPort) >= this->m_comPorts.size()) {
|
if (this->m_comPorts.empty() || static_cast<size_t>(this->m_selectedPort) >= this->m_comPorts.size()) {
|
||||||
View::showErrorPopup("hex.windows.view.tty_console.no_available_port"_lang);
|
EventManager::post<RequestOpenErrorPopup>("hex.windows.view.tty_console.no_available_port"_lang);
|
||||||
return true; // If false, connect_error error popup will override this error popup
|
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(),
|
this->m_portHandle = ::CreateFile((R"(\\.\)" + this->m_comPorts[this->m_selectedPort].first).c_str(),
|
||||||
|
Loading…
Reference in New Issue
Block a user