1
0
mirror of synced 2024-11-12 02:00:52 +01:00

ui: Highlight selected patterns in pattern data view

This commit is contained in:
WerWolv 2022-10-09 15:56:26 +02:00
parent 3a9c3f939e
commit 4070833229
4 changed files with 92 additions and 25 deletions

View File

@ -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

View File

@ -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 };

View 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;
}
}

View File

@ -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));