ui: Highlight selected patterns in pattern data view
This commit is contained in:
parent
3a9c3f939e
commit
4070833229
@ -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
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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 };
|
||||
|
41
lib/libimhex/source/helpers/types.cpp
Normal file
41
lib/libimhex/source/helpers/types.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include <hex/helpers/types.hpp>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -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<typename T>
|
||||
auto highlightWhenSelected(u64 address, u64 size, const T &callback) {
|
||||
constexpr bool HasReturn = !requires(T t) { { t() } -> std::same_as<void>; };
|
||||
|
||||
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<typename T>
|
||||
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));
|
||||
|
Loading…
Reference in New Issue
Block a user