diff --git a/lib/libimhex/CMakeLists.txt b/lib/libimhex/CMakeLists.txt index 266561f23..bd8402f19 100644 --- a/lib/libimhex/CMakeLists.txt +++ b/lib/libimhex/CMakeLists.txt @@ -137,6 +137,7 @@ set(LIBIMHEX_SOURCES source/helpers/encoding_file.cpp source/helpers/logger.cpp source/helpers/tar.cpp + source/helpers/types.cpp source/providers/provider.cpp diff --git a/lib/libimhex/include/hex/helpers/types.hpp b/lib/libimhex/include/hex/helpers/types.hpp index 01d2d45a3..5daf55139 100644 --- a/lib/libimhex/include/hex/helpers/types.hpp +++ b/lib/libimhex/include/hex/helpers/types.hpp @@ -1,5 +1,7 @@ #pragma once +#include + using u8 = std::uint8_t; using u16 = std::uint16_t; using u32 = std::uint32_t; @@ -20,29 +22,14 @@ namespace hex { u64 address; size_t size; - [[nodiscard]] constexpr bool isWithin(const Region &other) const { - return (this->getStartAddress() >= other.getStartAddress()) && (this->getEndAddress() <= other.getEndAddress()) && *this != Invalid() && other != Invalid(); - } + [[nodiscard]] bool isWithin(const Region &other) const; + [[nodiscard]] bool overlaps(const Region &other) const; - [[nodiscard]] constexpr bool overlaps(const Region &other) const { - return (this->getEndAddress() >= other.getStartAddress()) && (this->getStartAddress() < other.getEndAddress()) && *this != Invalid() && other != Invalid(); - } + [[nodiscard]] u64 getStartAddress() const; + [[nodiscard]] u64 getEndAddress() const; + [[nodiscard]] size_t getSize() const; - [[nodiscard]] constexpr u64 getStartAddress() const { - return this->address; - } - - [[nodiscard]] constexpr u64 getEndAddress() const { - return this->address + this->size - 1; - } - - [[nodiscard]] constexpr size_t getSize() const { - return this->size; - } - - constexpr bool operator==(const Region &other) const { - return this->address == other.address && this->size == other.size; - } + bool operator==(const Region &other) const; constexpr static Region Invalid() { return { 0, 0 }; diff --git a/lib/libimhex/source/helpers/types.cpp b/lib/libimhex/source/helpers/types.cpp new file mode 100644 index 000000000..bcedccb49 --- /dev/null +++ b/lib/libimhex/source/helpers/types.cpp @@ -0,0 +1,41 @@ +#include + +namespace hex { + + [[nodiscard]] bool Region::isWithin(const Region &other) const { + if (*this == Invalid() || other == Invalid()) + return false; + + if (this->getStartAddress() >= other.getStartAddress() && this->getEndAddress() <= other.getEndAddress()) + return true; + + return false; + } + + [[nodiscard]] bool Region::overlaps(const Region &other) const { + if (*this == Invalid() || other == Invalid()) + return false; + + if (this->getEndAddress() >= other.getStartAddress() && this->getStartAddress() <= other.getEndAddress()) + return true; + + return false; + } + + [[nodiscard]] u64 Region::getStartAddress() const { + return this->address; + } + + [[nodiscard]] u64 Region::getEndAddress() const { + return this->address + this->size - 1; + } + + [[nodiscard]] size_t Region::getSize() const { + return this->size; + } + + bool Region::operator==(const Region &other) const { + return this->address == other.address && this->size == other.size; + } + +} \ No newline at end of file diff --git a/plugins/builtin/source/content/helpers/pattern_drawer.cpp b/plugins/builtin/source/content/helpers/pattern_drawer.cpp index c32924f4f..328a054e7 100644 --- a/plugins/builtin/source/content/helpers/pattern_drawer.cpp +++ b/plugins/builtin/source/content/helpers/pattern_drawer.cpp @@ -34,6 +34,43 @@ namespace hex { using namespace ::std::literals::string_literals; + bool isPatternSelected(u64 address, u64 size) { + auto currSelection = ImHexApi::HexEditor::getSelection(); + if (!currSelection.has_value()) + return false; + + return Region{ address, size }.overlaps(*currSelection); + } + + template + auto highlightWhenSelected(u64 address, u64 size, const T &callback) { + constexpr bool HasReturn = !requires(T t) { { t() } -> std::same_as; }; + + auto selected = isPatternSelected(address, size); + + if (selected) + ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyleColorVec4(ImGuiCol_HeaderActive)); + + if constexpr (HasReturn) { + auto result = callback(); + + if (selected) + ImGui::PopStyleColor(); + + return result; + } else { + callback(); + + if (selected) + ImGui::PopStyleColor(); + } + } + + template + auto highlightWhenSelected(const pl::ptrn::Pattern& pattern, const T &callback) { + return highlightWhenSelected(pattern.getOffset(), pattern.getSize(), callback); + } + void createLeafNode(const pl::ptrn::Pattern& pattern) { ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | @@ -48,8 +85,9 @@ namespace hex { ImGui::Unindent(); return false; } - else - return ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth); + else { + return highlightWhenSelected(pattern, [&]{ return ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);}); + } } void drawTypenameColumn(const pl::ptrn::Pattern& pattern, const std::string& pattern_name) { @@ -60,7 +98,7 @@ namespace hex { } void drawNameColumn(const pl::ptrn::Pattern& pattern) { - ImGui::TextUnformatted(pattern.getDisplayName().c_str()); + highlightWhenSelected(pattern, [&]{ ImGui::TextUnformatted(pattern.getDisplayName().c_str()); }); ImGui::TableNextColumn(); } @@ -387,7 +425,7 @@ namespace hex { size_t chunkSize = (endOffset - startOffset) + endSize; - auto chunkOpen = ImGui::TreeNode(hex::format("[{} ... {}]", i, endIndex - 1).c_str()); + auto chunkOpen = highlightWhenSelected(startOffset, ((endOffset + endSize) - startOffset) - 1, [&]{ return ImGui::TreeNodeEx(hex::format("[{} ... {}]", i, endIndex - 1).c_str(), ImGuiTreeNodeFlags_SpanFullWidth); }); ImGui::TableNextColumn(); drawColorColumn(pattern); ImGui::TextFormatted("0x{0:08X} : 0x{1:08X}", startOffset, startOffset + chunkSize - (pattern.getSize() == 0 ? 0 : 1));