diff --git a/plugins/visualizers/CMakeLists.txt b/plugins/visualizers/CMakeLists.txt index 302998baf..d92efde9d 100644 --- a/plugins/visualizers/CMakeLists.txt +++ b/plugins/visualizers/CMakeLists.txt @@ -25,6 +25,7 @@ add_imhex_plugin( source/content/pl_visualizers/sound.cpp source/content/pl_visualizers/coordinates.cpp source/content/pl_visualizers/timestamp.cpp + source/content/pl_visualizers/table.cpp INCLUDES include ${MINIAUDIO_INCLUDE_DIRS} diff --git a/plugins/visualizers/source/content/pl_visualizers.cpp b/plugins/visualizers/source/content/pl_visualizers.cpp index de51c3730..32b9502d6 100644 --- a/plugins/visualizers/source/content/pl_visualizers.cpp +++ b/plugins/visualizers/source/content/pl_visualizers.cpp @@ -13,6 +13,7 @@ namespace hex::plugin::visualizers { void drawSoundVisualizer(pl::ptrn::Pattern &, pl::ptrn::IIterable &, bool, std::span arguments); void drawCoordinateVisualizer(pl::ptrn::Pattern &, pl::ptrn::IIterable &, bool, std::span arguments); void drawTimestampVisualizer(pl::ptrn::Pattern &, pl::ptrn::IIterable &, bool, std::span arguments); + void drawTableVisualizer(pl::ptrn::Pattern &, pl::ptrn::IIterable &, bool, std::span arguments); void registerPatternLanguageVisualizers() { using ParamCount = pl::api::FunctionParameterCount; @@ -25,6 +26,7 @@ namespace hex::plugin::visualizers { ContentRegistry::PatternLanguage::addVisualizer("sound", drawSoundVisualizer, ParamCount::exactly(3)); ContentRegistry::PatternLanguage::addVisualizer("coordinates", drawCoordinateVisualizer, ParamCount::exactly(2)); ContentRegistry::PatternLanguage::addVisualizer("timestamp", drawTimestampVisualizer, ParamCount::exactly(1)); + ContentRegistry::PatternLanguage::addVisualizer("table", drawTableVisualizer, ParamCount::exactly(3)); } } diff --git a/plugins/visualizers/source/content/pl_visualizers/table.cpp b/plugins/visualizers/source/content/pl_visualizers/table.cpp new file mode 100644 index 000000000..afea6a5c6 --- /dev/null +++ b/plugins/visualizers/source/content/pl_visualizers/table.cpp @@ -0,0 +1,59 @@ +#include + +#include + +#include +#include + +#include + +#include +#include +#include + +namespace hex::plugin::visualizers { + + void drawTableVisualizer(pl::ptrn::Pattern &, pl::ptrn::IIterable &, bool shouldReset, std::span arguments) { + static std::vector tableContent; + static u128 width = 0, height = 0; + + if (shouldReset) { + tableContent.clear(); + width = height = 0; + + auto pattern = arguments[0].toPattern(); + if (dynamic_cast(pattern.get()) == nullptr && + dynamic_cast(pattern.get()) == nullptr && + dynamic_cast(pattern.get()) == nullptr) + { + throw std::logic_error("Table visualizer requires an array pattern as the first argument."); + } + + width = arguments[1].toUnsigned(); + height = arguments[2].toUnsigned(); + + auto iterable = dynamic_cast(pattern.get()); + iterable->forEachEntry(0, iterable->getEntryCount(), [&](u64, pl::ptrn::Pattern *entry) { + tableContent.push_back(entry->toString()); + }); + } + + if (width >= IMGUI_TABLE_MAX_COLUMNS) + throw std::logic_error(hex::format("Table visualizer cannot have more than {} columns.", IMGUI_TABLE_MAX_COLUMNS)); + + if (ImGui::BeginTable("##visualizer_table", width, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) { + for (u128 i = 0; i < height; i += 1) { + ImGui::TableNextRow(); + for (u128 j = 0; j < width; j += 1) { + ImGui::TableSetColumnIndex(j); + if (i * width + j < tableContent.size()) + ImGui::TextUnformatted(tableContent[i * width + j].c_str()); + else + ImGui::TextUnformatted("??"); + } + } + ImGui::EndTable(); + } + } + +} \ No newline at end of file