diff --git a/lib/libimhex/CMakeLists.txt b/lib/libimhex/CMakeLists.txt index abcd9677f..ef335ed32 100644 --- a/lib/libimhex/CMakeLists.txt +++ b/lib/libimhex/CMakeLists.txt @@ -49,6 +49,7 @@ set(LIBIMHEX_SOURCES source/ui/view.cpp source/ui/popup.cpp source/ui/toast.cpp + source/ui/visualizer_drawer.cpp source/subcommands/subcommands.cpp ) diff --git a/lib/libimhex/include/hex/ui/visualizer_drawer.hpp b/lib/libimhex/include/hex/ui/visualizer_drawer.hpp new file mode 100644 index 000000000..75b212185 --- /dev/null +++ b/lib/libimhex/include/hex/ui/visualizer_drawer.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include "hex/api/content_registry.hpp" + +namespace hex::ui { + + class VisualizerDrawer { + std::string m_lastVisualizerError; + public: + VisualizerDrawer()=default; + void drawVisualizer(const std::map &visualizers, const std::vector &arguments, pl::ptrn::Pattern &pattern, bool reset); + const std::string& getLastVisualizerError() const { + return m_lastVisualizerError; + } + void setLastVisualizerError(const std::string &error) { + m_lastVisualizerError = error; + } + void clearLastVisualizerError() { + m_lastVisualizerError.clear(); + } + }; +} \ No newline at end of file diff --git a/lib/libimhex/source/ui/visualizer_drawer.cpp b/lib/libimhex/source/ui/visualizer_drawer.cpp new file mode 100644 index 000000000..f0f3fb63c --- /dev/null +++ b/lib/libimhex/source/ui/visualizer_drawer.cpp @@ -0,0 +1,34 @@ + +#include "hex/ui/visualizer_drawer.hpp" +#include "imgui.h" + +namespace hex::ui { + void VisualizerDrawer::drawVisualizer( + const std::map &visualizers, + const std::vector &arguments, pl::ptrn::Pattern &pattern, bool reset) { + auto visualizerName = arguments.front().toString(true); + + if (auto entry = visualizers.find(visualizerName); entry != visualizers.end()) { + const auto &[name, visualizer] = *entry; + + auto paramCount = arguments.size() - 1; + auto [minParams, maxParams] = visualizer.parameterCount; + + if (paramCount >= minParams && paramCount <= maxParams) { + try { + visualizer.callback(pattern, reset, {arguments.begin() + 1, arguments.end()}); + } catch (std::exception &e) { + m_lastVisualizerError = e.what(); + } + } else { + ImGui::TextUnformatted("hex.ui.pattern_drawer.visualizer.invalid_parameter_count"_lang); + } + } else { + ImGui::TextUnformatted("hex.ui.pattern_drawer.visualizer.unknown"_lang); + } + + if (!m_lastVisualizerError.empty()) + ImGui::TextUnformatted(m_lastVisualizerError.c_str()); + } + +} \ No newline at end of file diff --git a/plugins/builtin/include/content/views/view_data_inspector.hpp b/plugins/builtin/include/content/views/view_data_inspector.hpp index 29c00b3f4..ea925f1d4 100644 --- a/plugins/builtin/include/content/views/view_data_inspector.hpp +++ b/plugins/builtin/include/content/views/view_data_inspector.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -56,6 +57,7 @@ namespace hex::plugin::builtin { ContentRegistry::DataInspector::NumberDisplayStyle m_numberDisplayStyle = ContentRegistry::DataInspector::NumberDisplayStyle::Decimal; bool m_invert = false; + ui::VisualizerDrawer m_visualizerDrawer; u64 m_startAddress = 0; size_t m_validBytes = 0; prv::Provider *m_selectedProvider = nullptr; diff --git a/plugins/builtin/source/content/views/view_data_inspector.cpp b/plugins/builtin/source/content/views/view_data_inspector.cpp index 7380f9d41..1cd64eb90 100644 --- a/plugins/builtin/source/content/views/view_data_inspector.cpp +++ b/plugins/builtin/source/content/views/view_data_inspector.cpp @@ -1,4 +1,5 @@ #include "content/views/view_data_inspector.hpp" +#include "ui/pattern_drawer.hpp" #include #include @@ -7,6 +8,8 @@ #include #include +#include + #include #include @@ -198,8 +201,13 @@ namespace hex::plugin::builtin { try { // Set up the display function using the pattern's formatter - auto displayFunction = [value = pattern->getFormattedValue()] { - ImGui::TextUnformatted(value.c_str()); + auto displayFunction = [pattern,value = pattern->getFormattedValue()] { + auto drawer = ui::VisualizerDrawer(); + if (const auto &inlineVisualizeArgs = pattern->getAttributeArguments("hex::inline_visualize"); !inlineVisualizeArgs.empty()) { + drawer.drawVisualizer(ContentRegistry::PatternLanguage::impl::getInlineVisualizers(), inlineVisualizeArgs, *pattern, true); + } else { + ImGui::TextUnformatted(value.c_str()); + } return value; }; diff --git a/plugins/ui/include/ui/pattern_drawer.hpp b/plugins/ui/include/ui/pattern_drawer.hpp index c4dc352ad..87df29dc9 100644 --- a/plugins/ui/include/ui/pattern_drawer.hpp +++ b/plugins/ui/include/ui/pattern_drawer.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -71,7 +72,6 @@ namespace hex::ui { void makeSelectable(const pl::ptrn::Pattern &pattern); void drawValueColumn(pl::ptrn::Pattern& pattern); - void drawVisualizer(const std::map &visualizers, const std::vector &arguments, pl::ptrn::Pattern &pattern, bool reset); void drawFavoriteColumn(const pl::ptrn::Pattern& pattern); bool drawNameColumn(const pl::ptrn::Pattern &pattern, bool leaf = false); void drawColorColumn(const pl::ptrn::Pattern& pattern); @@ -103,6 +103,7 @@ namespace hex::ui { const pl::ptrn::Pattern *m_editingPattern = nullptr; u64 m_editingPatternOffset = 0; + hex::ui::VisualizerDrawer m_visualizerDrawer; TreeStyle m_treeStyle = TreeStyle::Default; bool m_rowColoring = false; @@ -111,7 +112,6 @@ namespace hex::ui { const pl::ptrn::Pattern *m_jumpToPattern = nullptr; std::set m_visualizedPatterns; - std::string m_lastVisualizerError; std::string m_filterText; Filter m_filter; diff --git a/plugins/ui/source/ui/pattern_drawer.cpp b/plugins/ui/source/ui/pattern_drawer.cpp index 06a10de12..b79494b5c 100644 --- a/plugins/ui/source/ui/pattern_drawer.cpp +++ b/plugins/ui/source/ui/pattern_drawer.cpp @@ -339,32 +339,6 @@ namespace hex::ui { ImGui::TextUnformatted(pattern.getComment().c_str()); } - void PatternDrawer::drawVisualizer(const std::map &visualizers, const std::vector &arguments, pl::ptrn::Pattern &pattern, bool reset) { - auto visualizerName = arguments.front().toString(true); - - if (auto entry = visualizers.find(visualizerName); entry != visualizers.end()) { - const auto &[name, visualizer] = *entry; - - auto paramCount = arguments.size() - 1; - auto [minParams, maxParams] = visualizer.parameterCount; - - if (paramCount >= minParams && paramCount <= maxParams) { - try { - visualizer.callback(pattern, reset, { arguments.begin() + 1, arguments.end() }); - } catch (std::exception &e) { - m_lastVisualizerError = e.what(); - } - } else { - ImGui::TextUnformatted("hex.ui.pattern_drawer.visualizer.invalid_parameter_count"_lang); - } - } else { - ImGui::TextUnformatted("hex.ui.pattern_drawer.visualizer.unknown"_lang); - } - - if (!m_lastVisualizerError.empty()) - ImGui::TextUnformatted(m_lastVisualizerError.c_str()); - } - void PatternDrawer::drawValueColumn(pl::ptrn::Pattern& pattern) { ImGui::TableNextColumn(); @@ -384,11 +358,11 @@ namespace hex::ui { if (ImGui::Button(hex::format(" {} {}", ICON_VS_EYE_WATCH, value).c_str(), ImVec2(width, ImGui::GetTextLineHeight()))) { auto previousPattern = m_currVisualizedPattern; m_currVisualizedPattern = &pattern; - - if (!m_lastVisualizerError.empty() || m_currVisualizedPattern != previousPattern) + auto lastVisualizerError = m_visualizerDrawer.getLastVisualizerError(); + if (!lastVisualizerError.empty() || m_currVisualizedPattern != previousPattern) shouldReset = true; - m_lastVisualizerError.clear(); + m_visualizerDrawer.clearLastVisualizerError(); ImGui::OpenPopup("Visualizer"); } @@ -398,14 +372,14 @@ namespace hex::ui { if (ImGui::BeginPopup("Visualizer")) { if (m_currVisualizedPattern == &pattern) { - drawVisualizer(ContentRegistry::PatternLanguage::impl::getVisualizers(), visualizeArgs, pattern, !m_visualizedPatterns.contains(&pattern) || shouldReset); + m_visualizerDrawer.drawVisualizer(ContentRegistry::PatternLanguage::impl::getVisualizers(), visualizeArgs, pattern, !m_visualizedPatterns.contains(&pattern) || shouldReset); m_visualizedPatterns.insert(&pattern); } ImGui::EndPopup(); } } else if (const auto &inlineVisualizeArgs = pattern.getAttributeArguments("hex::inline_visualize"); !inlineVisualizeArgs.empty()) { - drawVisualizer(ContentRegistry::PatternLanguage::impl::getInlineVisualizers(), inlineVisualizeArgs, pattern, true); + m_visualizerDrawer.drawVisualizer(ContentRegistry::PatternLanguage::impl::getInlineVisualizers(), inlineVisualizeArgs, pattern, true); } else { ImGuiExt::TextFormatted("{}", value); } @@ -1464,7 +1438,7 @@ namespace hex::ui { m_currVisualizedPattern = nullptr; m_sortedPatterns.clear(); m_filteredPatterns.clear(); - m_lastVisualizerError.clear(); + m_visualizerDrawer.clearLastVisualizerError(); m_currPatternPath.clear(); m_favoritesUpdateTask.interrupt();