feat: Added new pattern inline visualizers

This commit is contained in:
WerWolv
2023-07-04 22:18:06 +02:00
parent 33566137c2
commit 86c4c8fa96
8 changed files with 119 additions and 33 deletions

View File

@@ -13,6 +13,7 @@ add_library(${PROJECT_NAME} SHARED
source/content/pl_builtin_functions.cpp
source/content/pl_pragmas.cpp
source/content/pl_visualizers.cpp
source/content/pl_inline_visualizers.cpp
source/content/settings_entries.cpp
source/content/tools_entries.cpp
source/content/data_processor_nodes.cpp

View File

@@ -1,6 +1,7 @@
#pragma once
#include <hex/api/task.hpp>
#include <hex/api/content_registry.hpp>
#include <pl/patterns/pattern.hpp>
#include <pl/pattern_visitor.hpp>
@@ -61,7 +62,7 @@ namespace hex::plugin::builtin::ui {
void makeSelectable(const pl::ptrn::Pattern &pattern);
void drawValueColumn(pl::ptrn::Pattern& pattern);
void drawVisualizer(const std::vector<pl::core::Token::Literal> &arguments, pl::ptrn::Pattern &pattern, pl::ptrn::IIterable &iterable, bool reset);
void drawVisualizer(const std::map<std::string, ContentRegistry::PatternLanguage::impl::Visualizer> &visualizers, const std::vector<pl::core::Token::Literal> &arguments, pl::ptrn::Pattern &pattern, pl::ptrn::IIterable &iterable, bool reset);
void drawFavoriteColumn(const pl::ptrn::Pattern& pattern);
bool createTreeNode(const pl::ptrn::Pattern& pattern, bool leaf = false);

View File

@@ -0,0 +1,68 @@
#include <hex/api/content_registry.hpp>
#include <imgui.h>
#include <pl/patterns/pattern.hpp>
#include <pl/patterns/pattern_padding.hpp>
#include <hex/helpers/fmt.hpp>
#include <fonts/codicons_font.h>
#include <romfs/romfs.hpp>
namespace hex::plugin::builtin {
namespace {
void drawColorInlineVisualizer(pl::ptrn::Pattern &, pl::ptrn::IIterable &, bool, std::span<const pl::core::Token::Literal> arguments) {
auto r = arguments[0].toFloatingPoint();
auto g = arguments[1].toFloatingPoint();
auto b = arguments[2].toFloatingPoint();
auto a = arguments[3].toFloatingPoint();
ImGui::ColorButton("color", ImVec4(r / 255.0F, g / 255.0F, b / 255.0F, a / 255.0F), ImGuiColorEditFlags_NoTooltip, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
}
void drawGaugeInlineVisualizer(pl::ptrn::Pattern &, pl::ptrn::IIterable &, bool, std::span<const pl::core::Token::Literal> arguments) {
auto value = arguments[0].toFloatingPoint();
const auto color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(color.x, color.y, color.z, 0.2F));
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0F, 0.0F, 0.0F, 0.0F));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(color.x, color.y, color.z, 0.5F));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0F);
ImGui::ProgressBar(value / 100.0F, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()), "");
ImGui::PopStyleVar(1);
ImGui::PopStyleColor(3);
}
void drawButtonInlineVisualizer(pl::ptrn::Pattern &pattern, pl::ptrn::IIterable &, bool, std::span<const pl::core::Token::Literal> arguments) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0.5F));
if (ImGui::Button(hex::format(" {} {}", ICON_VS_PLAY, pattern.getFormattedValue()).c_str(), ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()))) {
auto *evaluator = pattern.getEvaluator();
const auto functionName = arguments[0].toString(false);
const auto &function = evaluator->findFunction(functionName);
if (function.has_value())
function->func(evaluator, { pattern.clone() });
}
ImGui::PopStyleVar(2);
}
}
void registerPatternLanguageInlineVisualizers() {
ContentRegistry::PatternLanguage::addInlineVisualizer("color", drawColorInlineVisualizer, 4);
ContentRegistry::PatternLanguage::addInlineVisualizer("gauge", drawGaugeInlineVisualizer, 1);
ContentRegistry::PatternLanguage::addInlineVisualizer("button", drawButtonInlineVisualizer, 1);
}
}

View File

@@ -15,6 +15,7 @@ namespace hex::plugin::builtin {
void registerPatternLanguageFunctions();
void registerPatternLanguagePragmas();
void registerPatternLanguageVisualizers();
void registerPatternLanguageInlineVisualizers();
void registerCommandPaletteCommands();
void registerSettings();
void loadSettings();
@@ -57,6 +58,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
registerPatternLanguageFunctions();
registerPatternLanguagePragmas();
registerPatternLanguageVisualizers();
registerPatternLanguageInlineVisualizers();
registerCommandPaletteCommands();
registerSettings();
loadSettings();

View File

@@ -219,11 +219,9 @@ namespace hex::plugin::builtin::ui {
ImGui::TableNextColumn();
}
void PatternDrawer::drawVisualizer(const std::vector<pl::core::Token::Literal> &arguments, pl::ptrn::Pattern &pattern, pl::ptrn::IIterable &iterable, bool reset) {
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, pl::ptrn::IIterable &iterable, bool reset) {
auto visualizerName = arguments.front().toString(true);
const auto &visualizers = ContentRegistry::PatternLanguage::impl::getVisualizers();
if (auto entry = visualizers.find(visualizerName); entry != visualizers.end()) {
const auto &[name, visualizer] = *entry;
if (visualizer.parameterCount != arguments.size() - 1) {
@@ -248,12 +246,12 @@ namespace hex::plugin::builtin::ui {
const auto value = pattern.getFormattedValue();
const auto width = ImGui::GetColumnWidth();
if (const auto &arguments = pattern.getAttributeArguments("hex::visualize"); !arguments.empty()) {
if (const auto &visualizeArgs = pattern.getAttributeArguments("hex::visualize"); !visualizeArgs.empty()) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0.5F));
bool shouldReset = false;
if (ImGui::Button(hex::format("{} {}", ICON_VS_EYE_WATCH, value).c_str(), ImVec2(width, ImGui::GetTextLineHeight()))) {
if (ImGui::Button(hex::format(" {} {}", ICON_VS_EYE_WATCH, value).c_str(), ImVec2(width, ImGui::GetTextLineHeight()))) {
auto previousPattern = this->m_currVisualizedPattern;
this->m_currVisualizedPattern = &pattern;
@@ -270,12 +268,14 @@ namespace hex::plugin::builtin::ui {
if (ImGui::BeginPopup("Visualizer")) {
if (this->m_currVisualizedPattern == &pattern) {
drawVisualizer(arguments, pattern, dynamic_cast<pl::ptrn::IIterable&>(pattern), !this->m_visualizedPatterns.contains(&pattern) || shouldReset);
drawVisualizer(ContentRegistry::PatternLanguage::impl::getVisualizers(), visualizeArgs, pattern, dynamic_cast<pl::ptrn::IIterable&>(pattern), !this->m_visualizedPatterns.contains(&pattern) || shouldReset);
this->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, dynamic_cast<pl::ptrn::IIterable&>(pattern), true);
} else {
ImGui::TextFormatted("{}", value);
}
@@ -660,20 +660,16 @@ namespace hex::plugin::builtin::ui {
drawSizeColumn(pattern);
drawTypenameColumn(pattern, "struct");
if (this->isEditingPattern(pattern)) {
if (pattern.getWriteFormatterFunction().empty())
ImGui::TextFormatted("{}", pattern.getFormattedValue());
else {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
auto value = pattern.toString();
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
pattern.setValue(value);
this->resetEditing();
}
ImGui::PopItemWidth();
ImGui::PopStyleVar();
if (this->isEditingPattern(pattern) && !pattern.getWriteFormatterFunction().empty()) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
auto value = pattern.toString();
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
pattern.setValue(value);
this->resetEditing();
}
ImGui::PopItemWidth();
ImGui::PopStyleVar();
} else {
drawValueColumn(pattern);
}
@@ -712,20 +708,16 @@ namespace hex::plugin::builtin::ui {
drawSizeColumn(pattern);
drawTypenameColumn(pattern, "union");
if (this->isEditingPattern(pattern)) {
if (pattern.getWriteFormatterFunction().empty())
ImGui::TextFormatted("{}", pattern.getFormattedValue());
else {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
auto value = pattern.toString();
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
pattern.setValue(value);
this->resetEditing();
}
ImGui::PopItemWidth();
ImGui::PopStyleVar();
if (this->isEditingPattern(pattern) && !pattern.getWriteFormatterFunction().empty()) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
auto value = pattern.toString();
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
pattern.setValue(value);
this->resetEditing();
}
ImGui::PopItemWidth();
ImGui::PopStyleVar();
} else {
drawValueColumn(pattern);
}