diff --git a/lib/libimhex/include/hex/api/event.hpp b/lib/libimhex/include/hex/api/event.hpp index 617ae7141..c8f7381f1 100644 --- a/lib/libimhex/include/hex/api/event.hpp +++ b/lib/libimhex/include/hex/api/event.hpp @@ -104,7 +104,7 @@ namespace hex { EVENT_DEF(EventFileLoaded, fs::path); EVENT_DEF(EventFileUnloaded); EVENT_DEF(EventDataChanged); - EVENT_DEF(EventPatternChanged, std::vector &); + EVENT_DEF(EventHighlightingChanged); EVENT_DEF(EventWindowClosing, GLFWwindow *); EVENT_DEF(EventRegionSelected, Region); EVENT_DEF(EventProjectFileStore); diff --git a/lib/libimhex/source/api/imhex_api.cpp b/lib/libimhex/source/api/imhex_api.cpp index 8ad472b04..40d50746e 100644 --- a/lib/libimhex/source/api/imhex_api.cpp +++ b/lib/libimhex/source/api/imhex_api.cpp @@ -39,11 +39,15 @@ namespace hex { id, Highlighting {region, color, tooltip} }); + EventManager::post(); + return id; } void removeHighlight(u32 id) { s_highlights.erase(id); + + EventManager::post(); } std::map &getHighlights() { diff --git a/plugins/builtin/include/content/views/view_hexeditor.hpp b/plugins/builtin/include/content/views/view_hexeditor.hpp index 55e080d25..601b79333 100644 --- a/plugins/builtin/include/content/views/view_hexeditor.hpp +++ b/plugins/builtin/include/content/views/view_hexeditor.hpp @@ -14,12 +14,22 @@ namespace hex::prv { class Provider; } - namespace hex::plugin::builtin { - using SearchFunction = std::vector> (*)(prv::Provider *&provider, std::string string); + struct HighlightBlock { + struct Highlight { + color_t color; + std::vector tooltips; + }; + + constexpr static size_t Size = 0x2000; + + u64 base; + std::array highlight; + }; + class ViewHexEditor : public View { public: ViewHexEditor(); @@ -54,6 +64,8 @@ namespace hex::plugin::builtin { hex::EncodingFile m_currEncodingFile; u8 m_highlightAlpha = 0x80; + std::list m_highlights; + bool m_processingImportExport = false; bool m_advancedDecodingEnabled = false; diff --git a/plugins/builtin/source/content/views/view_hexeditor.cpp b/plugins/builtin/source/content/views/view_hexeditor.cpp index 1eb5bb007..80524277e 100644 --- a/plugins/builtin/source/content/views/view_hexeditor.cpp +++ b/plugins/builtin/source/content/views/view_hexeditor.cpp @@ -59,45 +59,72 @@ namespace hex::plugin::builtin { }; this->m_memoryEditor.HighlightFn = [](const ImU8 *data, size_t off, bool next) -> bool { - auto _this = (ViewHexEditor *)(data); - - std::optional currColor, prevColor; + bool firstByte = off == 0x00; + auto _this = (ViewHexEditor *)(data); auto provider = ImHexApi::Provider::get(); - off += provider->getBaseAddress() + provider->getCurrentPageAddress(); u32 alpha = static_cast(_this->m_highlightAlpha) << 24; - for (const auto &[id, highlight] : ImHexApi::HexEditor::getHighlights()) { - auto ®ion = highlight.getRegion(); - auto &color = highlight.getColor(); + std::optional currColor, prevColor; - if (off >= region.address && off < (region.address + region.size)) - currColor = (color & 0x00FFFFFF) | alpha; - if ((off - 1) >= region.address && (off - 1) < (region.address + region.size)) - prevColor = (color & 0x00FFFFFF) | alpha; + for (auto &highlightBlock : _this->m_highlights) { + if (off >= highlightBlock.base && off < (highlightBlock.base + HighlightBlock::Size)) { + currColor = highlightBlock.highlight[off - highlightBlock.base].color; + } + if ((off - 1) >= highlightBlock.base && (off - 1) < (highlightBlock.base + HighlightBlock::Size)) { + prevColor = highlightBlock.highlight[(off - 1) - highlightBlock.base].color; + } + + if (currColor && prevColor) break; + + if (firstByte) + prevColor = 0x00; } - { - auto patterns = provider->getPatternLanguageRuntime().getPatterns(); - for (const auto &pattern : patterns) { - auto child = pattern->getPattern(off); - if (child != nullptr) { - auto color = (child->getColor() & 0x00FFFFFF) | alpha; - currColor = currColor.has_value() ? ImAlphaBlendColors(color, currColor.value()) : color; - break; + if (!currColor || !prevColor) { + if (_this->m_highlights.size() > 0x10) + _this->m_highlights.pop_front(); + + auto blockStartOffset = off - (off % HighlightBlock::Size); + HighlightBlock newBlock = { + blockStartOffset, + {} + }; + + for (u32 i = 0; i < HighlightBlock::Size; i++) { + std::optional highlightColor; + std::string highlightTooltip; + + for (const auto &[id, highlight] : ImHexApi::HexEditor::getHighlights()) { + auto ®ion = highlight.getRegion(); + auto &color = highlight.getColor(); + auto &tooltip = highlight.getTooltip(); + + if (blockStartOffset + i >= region.address && blockStartOffset + i < (region.address + region.size)) { + highlightColor = (color & 0x00FFFFFF) | alpha; + highlightTooltip = tooltip; + } } + + auto patterns = provider->getPatternLanguageRuntime().getPatterns(); + for (const auto &pattern : patterns) { + auto child = pattern->getPattern(blockStartOffset + i); + if (child != nullptr) { + auto color = (child->getColor() & 0x00FFFFFF) | alpha; + highlightColor = highlightColor.has_value() ? ImAlphaBlendColors(color, highlightColor.value()) : color; + break; + } + } + + auto &currHighlight = newBlock.highlight[i]; + currHighlight.color = highlightColor.value_or(0x00); + if (!highlightTooltip.empty()) + currHighlight.tooltips.push_back(highlightTooltip); } - for (const auto &pattern : patterns) { - auto child = pattern->getPattern(off - 1); - if (child != nullptr) { - auto color = (child->getColor() & 0x00FFFFFF) | alpha; - prevColor = prevColor.has_value() ? ImAlphaBlendColors(color, currColor.value()) : color; - break; - } - } + _this->m_highlights.push_back(std::move(newBlock)); } if (next && prevColor != currColor) { @@ -114,24 +141,26 @@ namespace hex::plugin::builtin { }; this->m_memoryEditor.HoverFn = [](const ImU8 *data, size_t off) { + auto _this = (ViewHexEditor *)(data); + bool tooltipShown = false; auto provider = ImHexApi::Provider::get(); off += provider->getBaseAddress() + provider->getCurrentPageAddress(); - for (const auto &[id, highlight] : ImHexApi::HexEditor::getHighlights()) { - auto ®ion = highlight.getRegion(); - auto &color = highlight.getColor(); - auto &tooltip = highlight.getTooltip(); - - if (off >= region.address && off < (region.address + region.size)) { - if (!tooltipShown && !tooltip.empty()) { + for (auto &highlightBlock : _this->m_highlights) { + if (off >= highlightBlock.base && off < (highlightBlock.base + HighlightBlock::Size)) { + auto &highlight = highlightBlock.highlight[off - highlightBlock.base]; + if (!tooltipShown && !highlight.tooltips.empty()) { ImGui::BeginTooltip(); tooltipShown = true; } - ImGui::ColorButton(tooltip.c_str(), ImColor(color).Value); - ImGui::SameLine(0, 10); - ImGui::TextUnformatted(tooltip.c_str()); + + for (const auto &tooltip : highlight.tooltips) { + ImGui::ColorButton(tooltip.c_str(), ImColor(highlight.color).Value); + ImGui::SameLine(0, 10); + ImGui::TextUnformatted(tooltip.c_str()); + } } } @@ -175,6 +204,7 @@ namespace hex::plugin::builtin { EventManager::unsubscribe(this); EventManager::unsubscribe(this); EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } void ViewHexEditor::drawContent() { @@ -384,11 +414,7 @@ namespace hex::plugin::builtin { EventManager::post(path); EventManager::post(); - - { - std::vector patterns; - EventManager::post(patterns); - } + EventManager::post(); } void ViewHexEditor::copyBytes() const { @@ -908,6 +934,10 @@ namespace hex::plugin::builtin { region = Region { address, size }; }); + + EventManager::subscribe(this, [this] { + this->m_highlights.clear(); + }); } void ViewHexEditor::registerShortcuts() { diff --git a/plugins/builtin/source/content/views/view_pattern_data.cpp b/plugins/builtin/source/content/views/view_pattern_data.cpp index ab942ce51..86472160d 100644 --- a/plugins/builtin/source/content/views/view_pattern_data.cpp +++ b/plugins/builtin/source/content/views/view_pattern_data.cpp @@ -7,7 +7,7 @@ namespace hex::plugin::builtin { ViewPatternData::ViewPatternData() : View("hex.builtin.view.pattern_data.name") { - EventManager::subscribe(this, [this](auto &) { + EventManager::subscribe(this, [this]() { if (!ImHexApi::Provider::isValid()) return; this->m_sortedPatterns[ImHexApi::Provider::get()].clear(); @@ -15,7 +15,7 @@ namespace hex::plugin::builtin { } ViewPatternData::~ViewPatternData() { - EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } static bool beginPatternDataTable(prv::Provider *&provider, const std::vector &patterns, std::vector &sortedPatterns) { diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index de0555203..62412f170 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -624,10 +624,7 @@ namespace hex::plugin::builtin { this->m_console.clear(); this->clearPatternData(); - { - std::vector patterns; - EventManager::post(patterns); - } + EventManager::post(); std::thread([this, code] { std::map envVars; @@ -663,7 +660,7 @@ namespace hex::plugin::builtin { } if (result) { - EventManager::post(runtime.getPatterns()); + EventManager::post(); } this->m_runningEvaluators--;