1
0
mirror of synced 2024-11-24 15:50:16 +01:00

Make File Dialogs less hacky

This commit is contained in:
WerWolv 2021-01-27 00:44:10 +01:00
parent ab2458bdf4
commit 8990fad85a
8 changed files with 119 additions and 97 deletions

View File

@ -30,7 +30,6 @@ namespace hex {
private:
MemoryEditor m_memoryEditor;
imgui_addons::ImGuiFileBrowser m_fileBrowser;
std::vector<lang::PatternData*> &m_patternData;

View File

@ -32,7 +32,6 @@ namespace hex {
TextEditor m_textEditor;
std::vector<std::pair<lang::LogConsole::Level, std::string>> m_console;
imgui_addons::ImGuiFileBrowser m_fileBrowser;
void loadPatternFile(std::string path);
void clearPatternData();

View File

@ -12,6 +12,8 @@
#include <hex/views/view.hpp>
#include <imgui.h>
#include <ImGuiFileBrowser.h>
#include <nlohmann/json.hpp>
namespace hex { class SharedData; }
@ -59,6 +61,12 @@ namespace hex {
static std::string errorPopupMessage;
static std::list<ImHexApi::Bookmarks::Entry> bookmarkEntries;
static imgui_addons::ImGuiFileBrowser fileBrowser;
static imgui_addons::ImGuiFileBrowser::DialogMode fileBrowserDialogMode;
static std::string fileBrowserTitle;
static std::string fileBrowserValidExtensions;
static std::function<void(std::string)> fileBrowserCallback;
static int mainArgc;
static char **mainArgv;

View File

@ -3,6 +3,7 @@
#include <hex.hpp>
#include <imgui.h>
#include <ImGuiFileBrowser.h>
#include <hex/api/event.hpp>
@ -22,6 +23,7 @@ namespace hex {
virtual void drawMenu();
virtual bool handleShortcut(int key, int mods);
static void openFileBrowser(std::string title, imgui_addons::ImGuiFileBrowser::DialogMode mode, std::string validExtensions, const std::function<void(std::string)> &callback);
static void doLater(std::function<void()> &&function);
static std::vector<std::function<void()>>& getDeferedCalls();

View File

@ -18,6 +18,12 @@ namespace hex {
std::string SharedData::errorPopupMessage;
std::list<ImHexApi::Bookmarks::Entry> SharedData::bookmarkEntries;
imgui_addons::ImGuiFileBrowser SharedData::fileBrowser;
imgui_addons::ImGuiFileBrowser::DialogMode SharedData::fileBrowserDialogMode;
std::string SharedData::fileBrowserTitle;
std::string SharedData::fileBrowserValidExtensions;
std::function<void(std::string)> SharedData::fileBrowserCallback;
int SharedData::mainArgc;
char **SharedData::mainArgv;

View File

@ -24,6 +24,17 @@ namespace hex {
return EventManager::post(eventType, userData);
}
void View::openFileBrowser(std::string title, imgui_addons::ImGuiFileBrowser::DialogMode mode, std::string validExtensions, const std::function<void(std::string)> &callback) {
SharedData::fileBrowserTitle = title;
SharedData::fileBrowserDialogMode = mode;
SharedData::fileBrowserValidExtensions = std::move(validExtensions);
SharedData::fileBrowserCallback = callback;
View::doLater([title]{
ImGui::OpenPopup(title.c_str());
});
}
void View::drawCommonInterfaces() {
if (ImGui::BeginPopupModal("Error", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::NewLine();
@ -38,6 +49,11 @@ namespace hex {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
if (SharedData::fileBrowser.showFileDialog(SharedData::fileBrowserTitle, SharedData::fileBrowserDialogMode, ImVec2(0, 0), SharedData::fileBrowserValidExtensions)) {
SharedData::fileBrowserCallback(SharedData::fileBrowser.selected_path);
SharedData::fileBrowserTitle = "";
}
}
void View::showErrorPopup(std::string_view errorMessage) {

View File

@ -124,7 +124,6 @@ namespace hex {
if (ProjectFile::hasUnsavedChanges()) {
glfwSetWindowShouldClose(window, GLFW_FALSE);
this->getWindowOpenState() = true;
View::doLater([] { ImGui::OpenPopup("Save Changes"); });
}
});
@ -210,23 +209,21 @@ namespace hex {
ImGui::NewLine();
ImGui::InputText("##nolabel", this->m_loaderScriptScriptPath.data(), this->m_loaderScriptScriptPath.length(), ImGuiInputTextFlags_ReadOnly);
ImGui::SameLine();
if (ImGui::Button("Script"))
ImGui::OpenPopup("Loader Script: Open Script");
if (ImGui::Button("Script")) {
View::openFileBrowser("Loader Script: Open Script", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".py", [this](auto path) {
this->m_loaderScriptScriptPath = path;
});
}
ImGui::InputText("##nolabel", this->m_loaderScriptFilePath.data(), this->m_loaderScriptFilePath.length(), ImGuiInputTextFlags_ReadOnly);
ImGui::SameLine();
if (ImGui::Button("File"))
ImGui::OpenPopup("Loader Script: Open File");
if (ImGui::Button("File")) {
View::openFileBrowser("Loader Script: Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) {
this->m_loaderScriptFilePath = path;
});
}
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
ImGui::CloseCurrentPopup();
if (this->m_fileBrowser.showFileDialog("Loader Script: Open Script", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ImVec2(0, 0), ".py")) {
this->m_loaderScriptScriptPath = this->m_fileBrowser.selected_path;
}
if (this->m_fileBrowser.showFileDialog("Loader Script: Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN)) {
this->m_loaderScriptFilePath = this->m_fileBrowser.selected_path;
}
ImGui::NewLine();
confirmButtons("Load", "Cancel",
@ -265,62 +262,17 @@ namespace hex {
ImGui::EndPopup();
}
}
static void save() {
auto provider = SharedData::currentProvider;
for (const auto &[address, value] : provider->getPatches())
provider->writeRaw(address, &value, sizeof(u8));
}
if (this->m_fileBrowser.showFileDialog("Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN)) {
this->openFile(this->m_fileBrowser.selected_path);
}
if (this->m_fileBrowser.showFileDialog("Open Base64 File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN)) {
std::vector<u8> base64;
this->loadFromFile(this->m_fileBrowser.selected_path, base64);
if (!base64.empty()) {
this->m_dataToSave = decode64(base64);
if (this->m_dataToSave.empty())
View::showErrorPopup("File is not in a valid Base64 format!");
else
ImGui::OpenPopup("Save Data");
} else View::showErrorPopup("Failed to open file!");
}
if (this->m_fileBrowser.showFileDialog("Open Project", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ImVec2(0, 0), ".hexproj")) {
ProjectFile::load(this->m_fileBrowser.selected_path);
View::postEvent(Events::ProjectFileLoad);
}
if (this->m_fileBrowser.showFileDialog("Save Project", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, ImVec2(0, 0), ".hexproj")) {
ProjectFile::store(this->m_fileBrowser.selected_path);
}
if (this->m_fileBrowser.showFileDialog("Export File", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE)) {
this->saveToFile(this->m_fileBrowser.selected_path, this->m_dataToSave);
}
if (this->m_fileBrowser.showFileDialog("Apply IPS Patch", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN)) {
auto patchData = hex::readFile(this->m_fileBrowser.selected_path);
auto patch = hex::loadIPSPatch(patchData);
for (auto &[address, value] : patch) {
provider->write(address, &value, 1);
}
}
if (this->m_fileBrowser.showFileDialog("Apply IPS32 Patch", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN)) {
auto patchData = hex::readFile(this->m_fileBrowser.selected_path);
auto patch = hex::loadIPS32Patch(patchData);
for (auto &[address, value] : patch) {
provider->write(address, &value, 1);
}
}
if (this->m_fileBrowser.showFileDialog("Save As", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE)) {
FILE *file = fopen(this->m_fileBrowser.selected_path.c_str(), "wb");
static void saveAs() {
View::openFileBrowser("Save As", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, "*.*", [](auto path) {
FILE *file = fopen(path.c_str(), "wb");
if (file != nullptr) {
std::vector<u8> buffer(0xFF'FFFF, 0x00);
@ -328,6 +280,7 @@ namespace hex {
fseek(file, 0, SEEK_SET);
auto provider = SharedData::currentProvider;
for (u64 offset = 0; offset < provider->getActualSize(); offset += bufferSize) {
if (bufferSize > provider->getActualSize() - offset)
bufferSize = provider->getActualSize() - offset;
@ -338,39 +291,47 @@ namespace hex {
fclose(file);
}
}
}
});
};
void ViewHexEditor::drawMenu() {
auto provider = SharedData::currentProvider;
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Open File...", "CTRL + O")) {
this->getWindowOpenState() = true;
View::doLater([]{ ImGui::OpenPopup("Open File"); });
View::openFileBrowser("Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) {
this->openFile(path);
this->getWindowOpenState() = true;
});
}
if (ImGui::MenuItem("Save", "CTRL + S", false, provider != nullptr && provider->isWritable())) {
for (const auto &[address, value] : provider->getPatches())
provider->writeRaw(address, &value, sizeof(u8));
save();
}
if (ImGui::MenuItem("Save As...", "CTRL + SHIFT + S", false, provider != nullptr && provider->isWritable())) {
View::doLater([]{ ImGui::OpenPopup("Save As"); });
saveAs();
}
ImGui::Separator();
if (ImGui::MenuItem("Open Project", "")) {
this->getWindowOpenState() = true;
View::doLater([]{ ImGui::OpenPopup("Open Project"); });
View::openFileBrowser("Open Project", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".hexproj", [this](auto path) {
ProjectFile::load(path);
View::postEvent(Events::ProjectFileLoad);
this->getWindowOpenState() = true;
});
}
if (ImGui::MenuItem("Save Project", "", false, provider != nullptr && provider->isWritable())) {
View::postEvent(Events::ProjectFileStore);
if (ProjectFile::getProjectFilePath() == "")
View::doLater([] { ImGui::OpenPopup("Save Project"); });
if (ProjectFile::getProjectFilePath() == "") {
View::openFileBrowser("Save Project", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, ".hexproj", [](auto path) {
ProjectFile::store(path);
});
}
else
ProjectFile::store();
}
@ -379,24 +340,53 @@ namespace hex {
if (ImGui::BeginMenu("Import...")) {
if (ImGui::MenuItem("Base64 File")) {
this->getWindowOpenState() = true;
View::doLater([]{ ImGui::OpenPopup("Open Base64 File"); });
View::openFileBrowser("Open Base64 File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) {
std::vector<u8> base64;
this->loadFromFile(path, base64);
if (!base64.empty()) {
this->m_dataToSave = decode64(base64);
if (this->m_dataToSave.empty())
View::showErrorPopup("File is not in a valid Base64 format!");
else
ImGui::OpenPopup("Save Data");
this->getWindowOpenState() = true;
} else View::showErrorPopup("Failed to open file!");
});
}
ImGui::Separator();
if (ImGui::MenuItem("IPS Patch")) {
this->getWindowOpenState() = true;
View::doLater([]{ ImGui::OpenPopup("Apply IPS Patch"); });
View::openFileBrowser("Apply IPS Patch", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) {
auto patchData = hex::readFile(path);
auto patch = hex::loadIPSPatch(patchData);
for (auto &[address, value] : patch) {
SharedData::currentProvider->write(address, &value, 1);
}
this->getWindowOpenState() = true;
});
}
if (ImGui::MenuItem("IPS32 Patch")) {
this->getWindowOpenState() = true;
View::doLater([]{ ImGui::OpenPopup("Apply IPS32 Patch"); });
View::openFileBrowser("Apply IPS32 Patch", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) {
auto patchData = hex::readFile(path);
auto patch = hex::loadIPS32Patch(patchData);
for (auto &[address, value] : patch) {
SharedData::currentProvider->write(address, &value, 1);
}
this->getWindowOpenState() = true;
});
}
if (ImGui::MenuItem("File with Loader Script")) {
this->getWindowOpenState() = true;
this->m_loaderScriptFilePath.clear();
this->m_loaderScriptScriptPath.clear();
View::doLater([]{ ImGui::OpenPopup("Load File with Loader Script"); });
@ -415,7 +405,9 @@ namespace hex {
}
this->m_dataToSave = generateIPSPatch(patches);
View::doLater([]{ ImGui::OpenPopup("Export File"); });
View::openFileBrowser("Export File", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, "*.*", [this](auto path) {
this->saveToFile(path, this->m_dataToSave);
});
}
if (ImGui::MenuItem("IPS32 Patch")) {
Patches patches = provider->getPatches();
@ -426,7 +418,9 @@ namespace hex {
}
this->m_dataToSave = generateIPS32Patch(patches);
View::doLater([]{ ImGui::OpenPopup("Export File"); });
View::openFileBrowser("Export File", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, "*.*", [this](auto path) {
this->saveToFile(path, this->m_dataToSave);
});
}
ImGui::EndMenu();
@ -457,12 +451,10 @@ namespace hex {
bool ViewHexEditor::handleShortcut(int key, int mods) {
if (mods == GLFW_MOD_CONTROL && key == GLFW_KEY_S) {
auto provider = SharedData::currentProvider;
for (const auto &[address, value] : provider->getPatches())
provider->writeRaw(address, &value, sizeof(u8));
save();
return true;
} else if (mods == (GLFW_MOD_CONTROL | GLFW_MOD_SHIFT) && key == GLFW_KEY_S) {
ImGui::OpenPopup("Save As");
saveAs();
return true;
} else if (mods == GLFW_MOD_CONTROL && key == GLFW_KEY_F) {
ImGui::OpenPopup("Search");

View File

@ -217,7 +217,9 @@ namespace hex {
void ViewPattern::drawMenu() {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Load pattern...")) {
View::doLater([]{ ImGui::OpenPopup("Open Hex Pattern"); });
View::openFileBrowser("Open Hex Pattern", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".hexpat", [this](auto path) {
this->loadPatternFile(path);
});
}
ImGui::EndMenu();
}
@ -272,9 +274,7 @@ namespace hex {
}
ImGui::End();
if (this->m_fileBrowser.showFileDialog("Open Hex Pattern", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ImVec2(0, 0), ".hexpat")) {
this->loadPatternFile(this->m_fileBrowser.selected_path);
}
if (ImGui::BeginPopupModal("Accept Pattern", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::TextWrapped("One or more patterns compatible with this data type has been found");