Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline visualizers in custom data inspectors #1966

Merged
merged 8 commits into from
Nov 29, 2024
1 change: 1 addition & 0 deletions lib/libimhex/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
24 changes: 24 additions & 0 deletions lib/libimhex/include/hex/ui/visualizer_drawer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <string>
#include <map>
#include "hex/api/content_registry.hpp"

namespace hex::ui {

class VisualizerDrawer {
std::string m_lastVisualizerError;
public:
VisualizerDrawer()=default;
void drawVisualizer(const std::map<std::string, ContentRegistry::PatternLanguage::impl::Visualizer> &visualizers, const std::vector<pl::core::Token::Literal> &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();
}
};
}
34 changes: 34 additions & 0 deletions lib/libimhex/source/ui/visualizer_drawer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

#include "hex/ui/visualizer_drawer.hpp"
#include "imgui.h"

namespace hex::ui {
void VisualizerDrawer::drawVisualizer(
const std::map<std::string, ContentRegistry::PatternLanguage::impl::Visualizer> &visualizers,
const std::vector<pl::core::Token::Literal> &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());
}

}
2 changes: 2 additions & 0 deletions plugins/builtin/include/content/views/view_data_inspector.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <hex/ui/view.hpp>
#include <hex/ui/visualizer_drawer.hpp>

#include <hex/api/content_registry.hpp>
#include <hex/api/task_manager.hpp>
Expand Down Expand Up @@ -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;
Expand Down
12 changes: 10 additions & 2 deletions plugins/builtin/source/content/views/view_data_inspector.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "content/views/view_data_inspector.hpp"
#include "ui/pattern_drawer.hpp"

#include <hex/api/achievement_manager.hpp>
#include <hex/providers/provider.hpp>
Expand All @@ -7,6 +8,8 @@

#include <fonts/codicons_font.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <hex/ui/visualizer_drawer.hpp>


#include <pl/pattern_language.hpp>
#include <pl/patterns/pattern.hpp>
Expand Down Expand Up @@ -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;
};

Expand Down
4 changes: 2 additions & 2 deletions plugins/ui/include/ui/pattern_drawer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <hex/api/task_manager.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/ui/visualizer_drawer.hpp>

#include <pl/patterns/pattern.hpp>
#include <pl/pattern_visitor.hpp>
Expand Down Expand Up @@ -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<std::string, ContentRegistry::PatternLanguage::impl::Visualizer> &visualizers, const std::vector<pl::core::Token::Literal> &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);
Expand Down Expand Up @@ -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;
Expand All @@ -111,7 +112,6 @@ namespace hex::ui {
const pl::ptrn::Pattern *m_jumpToPattern = nullptr;

std::set<pl::ptrn::Pattern*> m_visualizedPatterns;
std::string m_lastVisualizerError;

std::string m_filterText;
Filter m_filter;
Expand Down
38 changes: 6 additions & 32 deletions plugins/ui/source/ui/pattern_drawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,32 +339,6 @@ namespace hex::ui {
ImGui::TextUnformatted(pattern.getComment().c_str());
}

void PatternDrawer::drawVisualizer(const std::map<std::string, ContentRegistry::PatternLanguage::impl::Visualizer> &visualizers, const std::vector<pl::core::Token::Literal> &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();

Expand All @@ -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");
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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();
Expand Down
Loading