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

impr: Make highlight hovering more efficient

This commit is contained in:
WerWolv 2024-07-08 21:34:27 +02:00
parent 8a4599feea
commit 2757075a10
8 changed files with 48 additions and 27 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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