From 244e34ab84a006e9da75ed8e8940a38b510490cd Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sun, 4 Jun 2023 16:13:46 +0200 Subject: [PATCH] feat: Added pattern data filter field --- .../source/ui/imgui_imhex_extensions.cpp | 2 +- plugins/builtin/include/ui/pattern_drawer.hpp | 4 ++ plugins/builtin/source/ui/pattern_drawer.cpp | 49 ++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp index 2a519bec6..907eb4496 100644 --- a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp +++ b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp @@ -645,7 +645,7 @@ namespace ImGui { ImGui::SetCursorPosX(ImGui::GetCursorPosX() + frame_size.x); - bool value_changed = ImGui::InputTextEx(label, nullptr, buffer.data(), buffer.size() + 1, ImVec2(CalcItemWidth() - frame_size.x, label_size.y + style.FramePadding.y * 2.0f), ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer); + bool value_changed = ImGui::InputTextEx(label, nullptr, buffer.data(), buffer.size() + 1, ImVec2(CalcItemWidth(), label_size.y + style.FramePadding.y * 2.0f), ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer); if (value_changed) MarkItemEdited(GImGui->LastItemData.ID); diff --git a/plugins/builtin/include/ui/pattern_drawer.hpp b/plugins/builtin/include/ui/pattern_drawer.hpp index 24b3f5a7e..a6f17efb8 100644 --- a/plugins/builtin/include/ui/pattern_drawer.hpp +++ b/plugins/builtin/include/ui/pattern_drawer.hpp @@ -63,6 +63,7 @@ namespace hex::plugin::builtin::ui { bool isEditingPattern(const pl::ptrn::Pattern& pattern) const; void resetEditing(); + bool matchesFilter(const std::vector &filterPath); private: std::map m_displayEnd; @@ -77,6 +78,9 @@ namespace hex::plugin::builtin::ui { std::set m_visualizedPatterns; std::string m_lastVisualizerError; + std::string m_filterText; + std::vector m_filter; + std::vector m_currPatternPath; std::function m_selectionCallback = [](Region) { }; }; } \ No newline at end of file diff --git a/plugins/builtin/source/ui/pattern_drawer.cpp b/plugins/builtin/source/ui/pattern_drawer.cpp index e7357865e..aef8a43f7 100644 --- a/plugins/builtin/source/ui/pattern_drawer.cpp +++ b/plugins/builtin/source/ui/pattern_drawer.cpp @@ -164,6 +164,28 @@ namespace hex::plugin::builtin::ui { } } + std::vector parseRValueFilter(const std::string &filter) { + std::vector result; + + if (!filter.empty()) { + result.emplace_back(); + for (char c : filter) { + if (c == '.') + result.emplace_back(); + else if (c == '[') { + result.emplace_back(); + result.back() += c; + } else if (c == ']') { + result.back() += c; + result.emplace_back(); + } else + result.back() += c; + } + } + + return result; + } + } bool PatternDrawer::isEditingPattern(const pl::ptrn::Pattern& pattern) const { @@ -175,6 +197,20 @@ namespace hex::plugin::builtin::ui { this->m_editingPatternOffset = 0x00; } + bool PatternDrawer::matchesFilter(const std::vector &filterPath) { + if (this->m_currPatternPath.size() <= filterPath.size()) { + for (ssize_t i = this->m_currPatternPath.size() - 1; i >= 0; i--) { + const auto &filter = filterPath[i]; + + if (this->m_currPatternPath[i]->getVariableName() != filter && !filter.empty() && filter != "*") { + return false; + } + } + } + + return true; + } + void PatternDrawer::drawVisualizer(const std::vector &arguments, pl::ptrn::Pattern &pattern, pl::ptrn::IIterable &iteratable, bool reset) { auto visualizerName = arguments.front().toString(true); @@ -732,7 +768,11 @@ namespace hex::plugin::builtin::ui { if (pattern.getVisibility() == pl::ptrn::Visibility::Hidden) return; - pattern.accept(*this); + this->m_currPatternPath.push_back(&pattern); + ON_SCOPE_EXIT { this->m_currPatternPath.pop_back(); }; + + if (matchesFilter(this->m_filter)) + pattern.accept(*this); } void PatternDrawer::drawArray(pl::ptrn::Pattern& pattern, pl::ptrn::IIterable &iteratable, bool isInlined) { @@ -932,6 +972,12 @@ namespace hex::plugin::builtin::ui { this->resetEditing(); } + ImGui::PushItemWidth(-1); + if (ImGui::InputTextIcon("##Search", ICON_VS_FILTER, this->m_filterText)) { + this->m_filter = parseRValueFilter(this->m_filterText); + } + ImGui::PopItemWidth(); + if (beginPatternTable(patterns, this->m_sortedPatterns, height)) { ImGui::TableHeadersRow(); @@ -955,5 +1001,6 @@ namespace hex::plugin::builtin::ui { this->m_currVisualizedPattern = nullptr; this->m_sortedPatterns.clear(); this->m_lastVisualizerError.clear(); + this->m_currPatternPath.clear(); } }