impr: Make highlight hovering more efficient
This commit is contained in:
parent
de36cc8445
commit
27b1a5dc98
@ -75,7 +75,7 @@ namespace hex {
|
|||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
using HighlightingFunction = std::function<std::optional<color_t>(u64, const u8*, size_t, bool)>;
|
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, Highlighting>& getBackgroundHighlights();
|
||||||
const std::map<u32, HighlightingFunction>& getBackgroundHighlightingFunctions();
|
const std::map<u32, HighlightingFunction>& getBackgroundHighlightingFunctions();
|
||||||
|
@ -61,6 +61,10 @@ namespace hex {
|
|||||||
constexpr static Region Invalid() {
|
constexpr static Region Invalid() {
|
||||||
return { 0, 0 };
|
return { 0, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr bool operator<(const Region &other) const {
|
||||||
|
return this->address < other.address;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ namespace hex::plugin::builtin {
|
|||||||
PerProvider<std::optional<u64>> m_selectionStart, m_selectionEnd;
|
PerProvider<std::optional<u64>> m_selectionStart, m_selectionEnd;
|
||||||
|
|
||||||
PerProvider<std::map<u64, color_t>> m_foregroundHighlights, m_backgroundHighlights;
|
PerProvider<std::map<u64, color_t>> m_foregroundHighlights, m_backgroundHighlights;
|
||||||
|
PerProvider<std::set<Region>> m_hoverHighlights;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -493,16 +493,8 @@ namespace hex::plugin::builtin {
|
|||||||
});
|
});
|
||||||
|
|
||||||
m_hexEditor.setBackgroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
|
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 (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);
|
return ImAlphaBlendColors(highlight->second, 0xA0FFFFFF);
|
||||||
else
|
else
|
||||||
return highlight->second;
|
return highlight->second;
|
||||||
@ -527,6 +519,14 @@ namespace hex::plugin::builtin {
|
|||||||
return result;
|
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) {
|
m_hexEditor.setTooltipCallback([](u64 address, const u8 *data, size_t size) {
|
||||||
for (const auto &[id, callback] : ImHexApi::HexEditor::impl::getTooltipFunctions()) {
|
for (const auto &[id, callback] : ImHexApi::HexEditor::impl::getTooltipFunctions()) {
|
||||||
callback(address, data, size);
|
callback(address, data, size);
|
||||||
|
@ -37,8 +37,8 @@ namespace hex::plugin::builtin {
|
|||||||
(*m_patternDrawer)->jumpToPattern(pattern);
|
(*m_patternDrawer)->jumpToPattern(pattern);
|
||||||
});
|
});
|
||||||
|
|
||||||
ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *, u64 address, const u8 *, size_t size) {
|
ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *, u64, size_t) -> std::set<Region> {
|
||||||
return m_hoveredPatternRegion.overlaps(Region { address, size });
|
return { m_hoveredPatternRegion };
|
||||||
});
|
});
|
||||||
|
|
||||||
m_patternDrawer.setOnCreateCallback([this](const prv::Provider *provider, auto &drawer) {
|
m_patternDrawer.setOnCreateCallback([this](const prv::Provider *provider, auto &drawer) {
|
||||||
|
@ -1912,24 +1912,23 @@ namespace hex::plugin::builtin {
|
|||||||
return color;
|
return color;
|
||||||
});
|
});
|
||||||
|
|
||||||
ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *provider, u64 address, const u8 *, size_t) {
|
ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *, u64 address, size_t size) {
|
||||||
if (!m_parentHighlightingEnabled) return false;
|
std::set<Region> result;
|
||||||
|
if (!m_parentHighlightingEnabled)
|
||||||
|
return result;
|
||||||
|
|
||||||
const auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
|
const auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
|
||||||
|
|
||||||
if (auto hoveredRegion = ImHexApi::HexEditor::getHoveredRegion(provider)) {
|
const auto hoveredRegion = Region { address, size };
|
||||||
for (const auto &pattern : runtime.getPatternsAtAddress(hoveredRegion->getStartAddress())) {
|
for (const auto &pattern : runtime.getPatternsAtAddress(hoveredRegion.getStartAddress())) {
|
||||||
const pl::ptrn::Pattern * checkPattern = pattern;
|
const pl::ptrn::Pattern * checkPattern = pattern;
|
||||||
if (auto parent = checkPattern->getParent(); parent != nullptr)
|
if (auto parent = checkPattern->getParent(); parent != nullptr)
|
||||||
checkPattern = parent;
|
checkPattern = parent;
|
||||||
|
|
||||||
if (checkPattern->getOffset() <= address && checkPattern->getOffset() + checkPattern->getSize() > address) {
|
result.emplace(checkPattern->getOffset(), checkPattern->getSize());
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
|
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
|
||||||
|
@ -270,6 +270,10 @@ namespace hex::ui {
|
|||||||
m_backgroundColorCallback = callback;
|
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) {
|
void setTooltipCallback(const std::function<void(u64, const u8 *, size_t)> &callback) {
|
||||||
m_tooltipCallback = 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 std::optional<color_t> defaultColorCallback(u64, const u8 *, size_t) { return std::nullopt; }
|
||||||
static void defaultTooltipCallback(u64, const u8 *, size_t) { }
|
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<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;
|
std::function<void(u64, const u8 *, size_t)> m_tooltipCallback = defaultTooltipCallback;
|
||||||
|
|
||||||
Mode m_mode = Mode::Overwrite;
|
Mode m_mode = Mode::Overwrite;
|
||||||
|
@ -666,7 +666,11 @@ namespace hex::ui {
|
|||||||
ImGuiExt::TextFormatted("{:?>{}}", "", maxCharsPerCell);
|
ImGuiExt::TextFormatted("{:?>{}}", "", maxCharsPerCell);
|
||||||
|
|
||||||
if (cellHovered) {
|
if (cellHovered) {
|
||||||
hoveredCell = { byteAddress, bytesPerCell };
|
Region newHoveredCell = { byteAddress, bytesPerCell };
|
||||||
|
if (hoveredCell != newHoveredCell) {
|
||||||
|
hoveredCell = newHoveredCell;
|
||||||
|
m_hoverChangedCallback(hoveredCell.address, hoveredCell.size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
@ -725,7 +729,11 @@ namespace hex::ui {
|
|||||||
this->drawCell(byteAddress, &bytes[x], 1, cellHovered, CellType::ASCII);
|
this->drawCell(byteAddress, &bytes[x], 1, cellHovered, CellType::ASCII);
|
||||||
|
|
||||||
if (cellHovered) {
|
if (cellHovered) {
|
||||||
hoveredCell = { byteAddress, bytesPerCell };
|
Region newHoveredCell = { byteAddress, bytesPerCell };
|
||||||
|
if (hoveredCell != newHoveredCell) {
|
||||||
|
hoveredCell = newHoveredCell;
|
||||||
|
m_hoverChangedCallback(hoveredCell.address, hoveredCell.size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
@ -813,7 +821,11 @@ namespace hex::ui {
|
|||||||
this->handleSelection(address, data.advance, &bytes[address % m_bytesPerRow], cellHovered);
|
this->handleSelection(address, data.advance, &bytes[address % m_bytesPerRow], cellHovered);
|
||||||
|
|
||||||
if (cellHovered) {
|
if (cellHovered) {
|
||||||
hoveredCell = { address, data.advance };
|
Region newHoveredCell = { address, data.advance };
|
||||||
|
if (hoveredCell != newHoveredCell) {
|
||||||
|
hoveredCell = newHoveredCell;
|
||||||
|
m_hoverChangedCallback(hoveredCell.address, hoveredCell.size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user