From 8ad0239bcabd2aa8ed22942c23e9675286b0887e Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sat, 21 Aug 2021 13:53:50 +0200 Subject: [PATCH] ui/ux: Implement toolbar button functions --- plugins/builtin/source/content/ui_items.cpp | 56 +++++++++++++++---- plugins/libimhex/include/hex/api/event.hpp | 12 ++-- .../include/hex/providers/provider.hpp | 4 ++ .../libimhex/source/providers/provider.cpp | 3 + source/providers/file_provider.cpp | 30 ++++++++++ source/views/view_hexeditor.cpp | 28 +++------- 6 files changed, 97 insertions(+), 36 deletions(-) diff --git a/plugins/builtin/source/content/ui_items.cpp b/plugins/builtin/source/content/ui_items.cpp index e9636ae2b..a0f739fa8 100644 --- a/plugins/builtin/source/content/ui_items.cpp +++ b/plugins/builtin/source/content/ui_items.cpp @@ -22,27 +22,63 @@ namespace hex::plugin::builtin { void addToolbarItems() { ContentRegistry::Interface::addToolbarItem([] { const static auto buttonSize = ImVec2(ImGui::GetCurrentWindow()->MenuBarHeight(), ImGui::GetCurrentWindow()->MenuBarHeight()); - ImGui::ToolBarButton(ICON_VS_DISCARD, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue), buttonSize); - ImGui::ToolBarButton(ICON_VS_REDO, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue), buttonSize); + + auto provider = SharedData::currentProvider; + + // Undo + ImGui::Disabled([&provider] { + if (ImGui::ToolBarButton(ICON_VS_DISCARD, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue), buttonSize)) + provider->undo(); + }, provider == nullptr || !provider->canUndo()); + + // Redo + ImGui::Disabled([&provider] { + if (ImGui::ToolBarButton(ICON_VS_REDO, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue), buttonSize)) + provider->redo(); + }, provider == nullptr || !provider->canRedo()); + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); - ImGui::ToolBarButton(ICON_VS_FILE, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGray), buttonSize); - ImGui::ToolBarButton(ICON_VS_FOLDER_OPENED, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBrown), buttonSize); + // Create new file + if (ImGui::ToolBarButton(ICON_VS_FILE, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGray), buttonSize)) + EventManager::post("Create File"); + + // Open file + if (ImGui::ToolBarButton(ICON_VS_FOLDER_OPENED, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBrown), buttonSize)) + EventManager::post("Open File"); + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); - ImGui::ToolBarButton(ICON_VS_SAVE, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue), buttonSize); - ImGui::ToolBarButton(ICON_VS_SAVE_AS, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue), buttonSize); + // Save file + ImGui::Disabled([&provider] { + if (ImGui::ToolBarButton(ICON_VS_SAVE, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue), buttonSize)) + provider->save(); + }, provider == nullptr || !provider->isWritable() || !provider->isSavable()); + + // Save file as + ImGui::Disabled([&provider] { + if (ImGui::ToolBarButton(ICON_VS_SAVE_AS, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue), buttonSize)) + View::openFileBrowser("hex.view.hexeditor.save_as"_lang, View::DialogMode::Save, { }, [&provider](auto path) { + provider->saveAs(path); + }); + }, provider == nullptr || !provider->isSavable()); + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); - ImGui::ToolBarButton(ICON_VS_COPY, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGray), buttonSize); - ImGui::ToolBarButton(ICON_VS_OUTPUT, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGray), buttonSize); - ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); + // Create bookmark + ImGui::Disabled([] { + if (ImGui::ToolBarButton(ICON_VS_BOOKMARK, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen), buttonSize)) { + Region region = { 0 }; + EventManager::post(region); + + ImHexApi::Bookmarks::add(region.address, region.size, { }, { }); + } + }, provider == nullptr || !provider->isReadable()); - ImGui::ToolBarButton(ICON_VS_BOOKMARK, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen), buttonSize); }); } diff --git a/plugins/libimhex/include/hex/api/event.hpp b/plugins/libimhex/include/hex/api/event.hpp index 92f5cb4e6..7b1df7eda 100644 --- a/plugins/libimhex/include/hex/api/event.hpp +++ b/plugins/libimhex/include/hex/api/event.hpp @@ -21,7 +21,7 @@ namespace hex { class EventId { public: - constexpr EventId(const char *func = __builtin_FUNCTION(), u32 line = __builtin_LINE()) { + explicit constexpr EventId(const char *func = __builtin_FUNCTION(), u32 line = __builtin_LINE()) { this->m_hash = line ^ 123456789; for (auto c : std::string_view(func)) { this->m_hash = (this->m_hash >> 5) | (this->m_hash << 27); @@ -43,7 +43,7 @@ namespace hex { struct Event : public EventBase { using Callback = std::function; - explicit Event(Callback func) noexcept : m_func(func) {} + explicit Event(Callback func) noexcept : m_func(std::move(func)) {} void operator()(Params... params) const noexcept { this->m_func(params...); @@ -83,10 +83,10 @@ namespace hex { } template - static void post(auto ... args) noexcept { + static void post(auto&& ... args) noexcept { for (const auto &[id, event] : s_events) { if (id == E::id) - (*reinterpret_cast(event))(args...); + (*reinterpret_cast(event))(std::forward(args)...); } } @@ -113,6 +113,8 @@ namespace hex { EVENT_DEF(RequestAddBookmark, ImHexApi::Bookmarks::Entry); EVENT_DEF(RequestAppendPatternLanguageCode, std::string); EVENT_DEF(RequestChangeWindowTitle, std::string); - EVENT_DEF(RequestCloseImHex); + EVENT_DEF(RequestCloseImHex, bool); + + EVENT_DEF(QuerySelection, Region&); } \ No newline at end of file diff --git a/plugins/libimhex/include/hex/providers/provider.hpp b/plugins/libimhex/include/hex/providers/provider.hpp index fccd76420..a3baeff58 100644 --- a/plugins/libimhex/include/hex/providers/provider.hpp +++ b/plugins/libimhex/include/hex/providers/provider.hpp @@ -23,6 +23,7 @@ namespace hex::prv { virtual bool isReadable() = 0; virtual bool isWritable() = 0; virtual bool isResizable() = 0; + virtual bool isSavable() = 0; virtual void read(u64 offset, void *buffer, size_t size, bool overlays = true); virtual void readRelative(u64 offset, void *buffer, size_t size, bool overlays = true); @@ -31,6 +32,9 @@ namespace hex::prv { virtual void resize(ssize_t newSize); + virtual void save(); + virtual void saveAs(const std::string &path); + virtual void readRaw(u64 offset, void *buffer, size_t size) = 0; virtual void writeRaw(u64 offset, const void *buffer, size_t size) = 0; virtual size_t getActualSize() = 0; diff --git a/plugins/libimhex/source/providers/provider.cpp b/plugins/libimhex/source/providers/provider.cpp index 3b79b7392..0f5cd996e 100644 --- a/plugins/libimhex/source/providers/provider.cpp +++ b/plugins/libimhex/source/providers/provider.cpp @@ -34,6 +34,9 @@ namespace hex::prv { this->write(offset + this->getBaseAddress(), buffer, size); } + void Provider::save() { } + void Provider::saveAs(const std::string &path) { } + void Provider::resize(ssize_t newSize) { } void Provider::applyOverlays(u64 offset, void *buffer, size_t size) { diff --git a/source/providers/file_provider.cpp b/source/providers/file_provider.cpp index 48a1c1f6b..4dbd72e57 100644 --- a/source/providers/file_provider.cpp +++ b/source/providers/file_provider.cpp @@ -41,6 +41,10 @@ namespace hex::prv { return true; } + bool FileProvider::isSavable() { + return !this->getPatches().empty(); + } + void FileProvider::read(u64 offset, void *buffer, size_t size, bool overlays) { @@ -82,6 +86,32 @@ namespace hex::prv { std::memcpy(reinterpret_cast(this->m_mappedFile) + PageSize * this->m_currPage + offset, buffer, size); } + void FileProvider::save() { + this->applyPatches(); + } + + void FileProvider::saveAs(const std::string &path) { + FILE *file = fopen(path.c_str(), "wb"); + + if (file != nullptr) { + std::vector buffer(0xFF'FFFF, 0x00); + size_t bufferSize = buffer.size(); + + 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; + + provider->readRelative(offset, buffer.data(), bufferSize); + fwrite(buffer.data(), 1, bufferSize, file); + } + + fclose(file); + } + } + void FileProvider::resize(ssize_t newSize) { this->close(); diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index c0272e495..9819c9030 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -204,6 +204,10 @@ namespace hex { if (alpha.is_number()) this->m_highlightAlpha = alpha; }); + + EventManager::subscribe(this, [this](auto ®ion) { + region = Region { this->m_memoryEditor.DataPreviewAddr, (this->m_memoryEditor.DataPreviewAddrEnd - this->m_memoryEditor.DataPreviewAddr) + 1 }; + }); } ViewHexEditor::~ViewHexEditor() { @@ -263,31 +267,13 @@ namespace hex { static void save() { auto provider = SharedData::currentProvider; - for (const auto &[address, value] : provider->getPatches()) - provider->writeRaw(address, &value, sizeof(u8)); + provider->save(); } static void saveAs() { View::openFileBrowser("hex.view.hexeditor.save_as"_lang, View::DialogMode::Save, { }, [](auto path) { - FILE *file = fopen(path.c_str(), "wb"); - - if (file != nullptr) { - std::vector buffer(0xFF'FFFF, 0x00); - size_t bufferSize = buffer.size(); - - 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; - - provider->readRelative(offset, buffer.data(), bufferSize); - fwrite(buffer.data(), 1, bufferSize, file); - } - - fclose(file); - } + auto provider = SharedData::currentProvider; + provider->saveAs(path); }); }