Skip to content

Commit

Permalink
impr: Make highlight hovering more efficient
Browse files Browse the repository at this point in the history
  • Loading branch information
WerWolv committed Jul 9, 2024
1 parent 8a4599f commit 2757075
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 27 deletions.
2 changes: 1 addition & 1 deletion lib/libimhex/include/hex/api/imhex_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ namespace hex {
namespace impl {

using HighlightingFunction = std::function<std::optional<color_t>(u64, const u8*, size_t, bool)>;
using HoveringFunction = std::function<bool(const prv::Provider *, u64, const u8*, size_t)>;
using HoveringFunction = std::function<std::set<Region>(const prv::Provider *, u64, size_t)>;

const std::map<u32, Highlighting>& getBackgroundHighlights();
const std::map<u32, HighlightingFunction>& getBackgroundHighlightingFunctions();
Expand Down
4 changes: 4 additions & 0 deletions lib/libimhex/include/hex/helpers/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ namespace hex {
constexpr static Region Invalid() {
return { 0, 0 };
}

constexpr bool operator<(const Region &other) const {
return this->address < other.address;
}
};


Expand Down
1 change: 1 addition & 0 deletions plugins/builtin/include/content/views/view_hex_editor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ namespace hex::plugin::builtin {
PerProvider<std::optional<u64>> m_selectionStart, m_selectionEnd;

PerProvider<std::map<u64, color_t>> m_foregroundHighlights, m_backgroundHighlights;
PerProvider<std::set<Region>> m_hoverHighlights;
};

}
18 changes: 9 additions & 9 deletions plugins/builtin/source/content/views/view_hex_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,16 +493,8 @@ namespace hex::plugin::builtin {
});

m_hexEditor.setBackgroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
bool hovered = false;
for (const auto &[id, hoverFunction] : ImHexApi::HexEditor::impl::getHoveringFunctions()) {
if (hoverFunction(m_hexEditor.getProvider(), address, data, size)) {
hovered = true;
break;
}
}

if (auto highlight = m_backgroundHighlights->find(address); highlight != m_backgroundHighlights->end()) {
if (hovered)
if (std::ranges::any_of(*m_hoverHighlights, [region = Region(address, size)](const Region &highlight) { return highlight.overlaps(region); }))
return ImAlphaBlendColors(highlight->second, 0xA0FFFFFF);
else
return highlight->second;
Expand All @@ -527,6 +519,14 @@ namespace hex::plugin::builtin {
return result;
});

m_hexEditor.setHoverChangedCallback([this](u64 address, size_t size) {
m_hoverHighlights->clear();
for (const auto &[id, hoverFunction] : ImHexApi::HexEditor::impl::getHoveringFunctions()) {
auto highlightedAddresses = hoverFunction(m_hexEditor.getProvider(), address, size);
m_hoverHighlights->merge(highlightedAddresses);
}
});

m_hexEditor.setTooltipCallback([](u64 address, const u8 *data, size_t size) {
for (const auto &[id, callback] : ImHexApi::HexEditor::impl::getTooltipFunctions()) {
callback(address, data, size);
Expand Down
4 changes: 2 additions & 2 deletions plugins/builtin/source/content/views/view_pattern_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ namespace hex::plugin::builtin {
(*m_patternDrawer)->jumpToPattern(pattern);
});

ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *, u64 address, const u8 *, size_t size) {
return m_hoveredPatternRegion.overlaps(Region { address, size });
ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *, u64, size_t) -> std::set<Region> {
return { m_hoveredPatternRegion };
});

m_patternDrawer.setOnCreateCallback([this](const prv::Provider *provider, auto &drawer) {
Expand Down
23 changes: 11 additions & 12 deletions plugins/builtin/source/content/views/view_pattern_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1912,24 +1912,23 @@ namespace hex::plugin::builtin {
return color;
});

ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *provider, u64 address, const u8 *, size_t) {
if (!m_parentHighlightingEnabled) return false;
ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *, u64 address, size_t size) {
std::set<Region> result;
if (!m_parentHighlightingEnabled)
return result;

const auto &runtime = ContentRegistry::PatternLanguage::getRuntime();

if (auto hoveredRegion = ImHexApi::HexEditor::getHoveredRegion(provider)) {
for (const auto &pattern : runtime.getPatternsAtAddress(hoveredRegion->getStartAddress())) {
const pl::ptrn::Pattern * checkPattern = pattern;
if (auto parent = checkPattern->getParent(); parent != nullptr)
checkPattern = parent;
const auto hoveredRegion = Region { address, size };
for (const auto &pattern : runtime.getPatternsAtAddress(hoveredRegion.getStartAddress())) {
const pl::ptrn::Pattern * checkPattern = pattern;
if (auto parent = checkPattern->getParent(); parent != nullptr)
checkPattern = parent;

if (checkPattern->getOffset() <= address && checkPattern->getOffset() + checkPattern->getSize() > address) {
return true;
}
}
result.emplace(checkPattern->getOffset(), checkPattern->getSize());
}

return false;
return result;
});

ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
Expand Down
5 changes: 5 additions & 0 deletions plugins/ui/include/ui/hex_editor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,10 @@ namespace hex::ui {
m_backgroundColorCallback = callback;
}

void setHoverChangedCallback(const std::function<void(u64, size_t)> &callback) {
m_hoverChangedCallback = callback;
}

void setTooltipCallback(const std::function<void(u64, const u8 *, size_t)> &callback) {
m_tooltipCallback = callback;
}
Expand Down Expand Up @@ -372,6 +376,7 @@ namespace hex::ui {
static std::optional<color_t> defaultColorCallback(u64, const u8 *, size_t) { return std::nullopt; }
static void defaultTooltipCallback(u64, const u8 *, size_t) { }
std::function<std::optional<color_t>(u64, const u8 *, size_t)> m_foregroundColorCallback = defaultColorCallback, m_backgroundColorCallback = defaultColorCallback;
std::function<void(u64, size_t)> m_hoverChangedCallback = [](auto, auto){ };
std::function<void(u64, const u8 *, size_t)> m_tooltipCallback = defaultTooltipCallback;

Mode m_mode = Mode::Overwrite;
Expand Down
18 changes: 15 additions & 3 deletions plugins/ui/source/ui/hex_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,11 @@ namespace hex::ui {
ImGuiExt::TextFormatted("{:?>{}}", "", maxCharsPerCell);

if (cellHovered) {
hoveredCell = { byteAddress, bytesPerCell };
Region newHoveredCell = { byteAddress, bytesPerCell };
if (hoveredCell != newHoveredCell) {
hoveredCell = newHoveredCell;
m_hoverChangedCallback(hoveredCell.address, hoveredCell.size);
}
}

ImGui::PopItemWidth();
Expand Down Expand Up @@ -725,7 +729,11 @@ namespace hex::ui {
this->drawCell(byteAddress, &bytes[x], 1, cellHovered, CellType::ASCII);

if (cellHovered) {
hoveredCell = { byteAddress, bytesPerCell };
Region newHoveredCell = { byteAddress, bytesPerCell };
if (hoveredCell != newHoveredCell) {
hoveredCell = newHoveredCell;
m_hoverChangedCallback(hoveredCell.address, hoveredCell.size);
}
}

ImGui::PopItemWidth();
Expand Down Expand Up @@ -813,7 +821,11 @@ namespace hex::ui {
this->handleSelection(address, data.advance, &bytes[address % m_bytesPerRow], cellHovered);

if (cellHovered) {
hoveredCell = { address, data.advance };
Region newHoveredCell = { address, data.advance };
if (hoveredCell != newHoveredCell) {
hoveredCell = newHoveredCell;
m_hoverChangedCallback(hoveredCell.address, hoveredCell.size);
}
}
}
}
Expand Down

0 comments on commit 2757075

Please sign in to comment.