diff --git a/plugins/builtin/include/content/views/view_pattern_data.hpp b/plugins/builtin/include/content/views/view_pattern_data.hpp index 17eab426be672..e35af84251af7 100644 --- a/plugins/builtin/include/content/views/view_pattern_data.hpp +++ b/plugins/builtin/include/content/views/view_pattern_data.hpp @@ -18,6 +18,7 @@ namespace hex::plugin::builtin { ui::PatternDrawer::TreeStyle m_treeStyle = ui::PatternDrawer::TreeStyle::Default; PerProvider> m_patternDrawer; + Region m_hoveredPatternRegion = Region::Invalid(); }; } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_pattern_data.cpp b/plugins/builtin/source/content/views/view_pattern_data.cpp index 72f1142db6b88..3d54dfbceebd8 100644 --- a/plugins/builtin/source/content/views/view_pattern_data.cpp +++ b/plugins/builtin/source/content/views/view_pattern_data.cpp @@ -37,6 +37,10 @@ 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 }); + }); + m_patternDrawer.setOnCreateCallback([this](const prv::Provider *provider, auto &drawer) { drawer = std::make_unique(); @@ -45,6 +49,13 @@ namespace hex::plugin::builtin { RequestPatternEditorSelectionChange::post(pattern->getLine(), 0); }); + drawer->setHoverCallback([this](const pl::ptrn::Pattern *pattern) { + if (pattern == nullptr) + m_hoveredPatternRegion = Region::Invalid(); + else + m_hoveredPatternRegion = { pattern->getOffset(), pattern->getSize() }; + }); + drawer->setTreeStyle(m_treeStyle); drawer->enableRowColoring(m_rowColoring); drawer->enablePatternEditing(provider->isWritable()); diff --git a/plugins/ui/include/ui/pattern_drawer.hpp b/plugins/ui/include/ui/pattern_drawer.hpp index 55bedf5d8779c..c6b7819b58d52 100644 --- a/plugins/ui/include/ui/pattern_drawer.hpp +++ b/plugins/ui/include/ui/pattern_drawer.hpp @@ -32,6 +32,7 @@ namespace hex::ui { void setTreeStyle(TreeStyle style) { m_treeStyle = style; } void setSelectionCallback(std::function callback) { m_selectionCallback = std::move(callback); } + void setHoverCallback(std::function callback) { m_hoverCallback = std::move(callback); } void enableRowColoring(bool enabled) { m_rowColoring = enabled; } void enablePatternEditing(bool enabled) { m_editingEnabled = enabled; } void reset(); @@ -126,6 +127,7 @@ namespace hex::ui { TaskHolder m_favoritesUpdateTask; std::function m_selectionCallback = [](const pl::ptrn::Pattern *) { }; + std::function m_hoverCallback = [](const pl::ptrn::Pattern *) { }; pl::gen::fmt::FormatterArray m_formatters; }; diff --git a/plugins/ui/source/ui/pattern_drawer.cpp b/plugins/ui/source/ui/pattern_drawer.cpp index 22e0052a63127..d57d38bfeb774 100644 --- a/plugins/ui/source/ui/pattern_drawer.cpp +++ b/plugins/ui/source/ui/pattern_drawer.cpp @@ -433,10 +433,14 @@ namespace hex::ui { } } - if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && m_editingEnabled) { - m_editingPattern = &pattern; - m_editingPatternOffset = pattern.getOffset(); - AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.modify_data.name"); + if (ImGui::IsItemHovered()) { + m_hoverCallback(&pattern); + + if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && m_editingEnabled) { + m_editingPattern = &pattern; + m_editingPatternOffset = pattern.getOffset(); + AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.modify_data.name"); + } } ImGui::SameLine(0, 0); @@ -1114,6 +1118,8 @@ namespace hex::ui { void PatternDrawer::draw(const std::vector> &patterns, const pl::PatternLanguage *runtime, float height) { std::scoped_lock lock(s_resetDrawMutex); + m_hoverCallback(nullptr); + const auto treeStyleButton = [this](auto icon, TreeStyle style, const char *tooltip) { bool pushed = false;