diff --git a/CMakeLists.txt b/CMakeLists.txt index 74deb28c0..7ff907973 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,6 @@ project(HexEditor) set(CMAKE_CXX_STANDARD 20) find_package(PkgConfig REQUIRED) -pkg_search_module(CRYPTO REQUIRED crypto) pkg_search_module(GLFW REQUIRED glfw3) pkg_search_module(GLM REQUIRED glm) pkg_search_module(CRYPTO REQUIRED libcrypto) @@ -50,6 +49,7 @@ add_executable(ImHex source/views/view_strings.cpp source/views/view_data_inspector.cpp source/views/view_disassembler.cpp + source/views/view_bookmarks.cpp libs/glad/source/glad.c diff --git a/include/event.hpp b/include/event.hpp index fb5918e7a..b39108f7f 100644 --- a/include/event.hpp +++ b/include/event.hpp @@ -12,7 +12,9 @@ namespace hex { FileDropped, ByteSelected, - SelectionChangeRequest + SelectionChangeRequest, + + AddBookmark }; struct EventHandler { diff --git a/include/views/view_bookmarks.hpp b/include/views/view_bookmarks.hpp new file mode 100644 index 000000000..dba11a356 --- /dev/null +++ b/include/views/view_bookmarks.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include "views/view.hpp" + +#include +#include + +#include "utils.hpp" + +namespace hex { + + namespace prv { class Provider; } + + struct Bookmark { + Region region; + + std::vector name; + std::vector comment; + }; + + class ViewBookmarks : public View { + public: + explicit ViewBookmarks(prv::Provider* &dataProvider); + ~ViewBookmarks() override; + + void createView() override; + void createMenu() override; + + private: + prv::Provider* &m_dataProvider; + + std::list m_bookmarks; + }; + +} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 68bb9d4ca..7dcdf19f8 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -11,6 +11,7 @@ #include "views/view_strings.hpp" #include "views/view_data_inspector.hpp" #include "views/view_disassembler.hpp" +#include "views/view_bookmarks.hpp" #include "providers/provider.hpp" @@ -22,6 +23,7 @@ int main() { // Shared Data std::vector patternData; hex::prv::Provider *dataProvider = nullptr; + // Create views window.addView(dataProvider, patternData); window.addView(dataProvider, patternData); @@ -31,6 +33,7 @@ int main() { window.addView(dataProvider); window.addView(dataProvider); window.addView(dataProvider); + window.addView(dataProvider); window.addView(); window.addView(); diff --git a/source/views/view_bookmarks.cpp b/source/views/view_bookmarks.cpp new file mode 100644 index 000000000..ca98f714e --- /dev/null +++ b/source/views/view_bookmarks.cpp @@ -0,0 +1,99 @@ +#include "views/view_bookmarks.hpp" + +#include "providers/provider.hpp" + +#include + +namespace hex { + + ViewBookmarks::ViewBookmarks(prv::Provider* &dataProvider) : View("Bookmarks"), m_dataProvider(dataProvider) { + View::subscribeEvent(Events::AddBookmark, [this](const void *userData) { + Bookmark bookmark; + bookmark.region = *reinterpret_cast(userData); + bookmark.name.resize(64); + bookmark.comment.resize(0xF'FFFF); + + std::memset(bookmark.name.data(), 0x00, 64); + std::memset(bookmark.comment.data(), 0x00, 0xF'FFFF); + + std::strcpy(bookmark.name.data(), ("Bookmark " + std::to_string(this->m_bookmarks.size() + 1)).c_str()); + + this->m_bookmarks.push_back(bookmark); + }); + } + + ViewBookmarks::~ViewBookmarks() { + View::unsubscribeEvent(Events::AddBookmark); + } + + void ViewBookmarks::createView() { + if (ImGui::Begin("Bookmarks", &this->getWindowOpenState())) { + if (ImGui::BeginChild("##scrolling")) { + + u32 id = 1; + std::list::const_iterator bookmarkToRemove = this->m_bookmarks.end(); + for (auto iter = this->m_bookmarks.begin(); iter != this->m_bookmarks.end(); iter++) { + auto &[region, name, comment] = *iter; + + if (ImGui::CollapsingHeader((std::string(name.data()) + "###" + std::to_string((u64)comment.data())).c_str())) { + ImGui::TextUnformatted("Information"); + ImGui::Separator(); + ImGui::Text("0x%08lx : 0x%08lx (%lu bytes)", region.address, region.address + region.size - 1, region.size); + + { + u8 bytes[10] = { 0 }; + this->m_dataProvider->read(region.address, bytes, std::min(region.size, size_t(10))); + + std::string bytesString; + for (u8 i = 0; i < std::min(region.size, size_t(10)); i++) { + bytesString += hex::format("%02X ", bytes[i]); + } + + if (region.size > 10) { + bytesString.pop_back(); + bytesString += "..."; + } + + ImGui::TextColored(ImColor(0xFF9BC64D), bytesString.c_str()); + } + + if (ImGui::Button("Jump to")) + View::postEvent(Events::SelectionChangeRequest, ®ion); + + ImGui::SameLine(0, 15); + + if (ImGui::Button("Remove")) + bookmarkToRemove = iter; + + ImGui::NewLine(); + ImGui::TextUnformatted("Name"); + ImGui::Separator(); + ImGui::PushID(id); + ImGui::InputText("##nolabel", name.data(), 64); + ImGui::PopID(); + ImGui::NewLine(); + ImGui::TextUnformatted("Comment"); + ImGui::Separator(); + ImGui::PushID(id + 1); + ImGui::InputTextMultiline("##nolabel", comment.data(), 0xF'FFFF); + ImGui::PopID(); + ImGui::NewLine(); + + id += 2; + } + } + + if (bookmarkToRemove != this->m_bookmarks.end()) + this->m_bookmarks.erase(bookmarkToRemove); + + ImGui::EndChild(); + } + } + ImGui::End(); + } + + void ViewBookmarks::createMenu() { + + } + +} \ No newline at end of file diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 0f4bd1f5f..595b65803 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -264,6 +264,13 @@ namespace hex { ImGui::EndMenu(); } + if (ImGui::MenuItem("Create bookmark", nullptr, false, this->m_memoryEditor.DataPreviewAddr != -1 && this->m_memoryEditor.DataPreviewAddrEnd != -1)) { + size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); + size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); + Region selectionRegion = { start, end - start + 1 }; + + View::postEvent(Events::AddBookmark, &selectionRegion); + } ImGui::EndMenu(); }