From d15307a2373872a036565bb7c133d3d6753b4384 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Wed, 13 Jan 2021 01:24:27 +0100 Subject: [PATCH] Added data inspector to content registry --- include/views/view_data_inspector.hpp | 45 +-- .../include/helpers/content_registry.hpp | 26 ++ .../libimhex/include/helpers/shared_data.hpp | 3 +- plugins/libimhex/include/plugin.hpp | 11 +- .../source/helpers/content_registry.cpp | 12 +- .../libimhex/source/helpers/shared_data.cpp | 3 +- source/views/view_data_inspector.cpp | 294 +++++++++++------- 7 files changed, 229 insertions(+), 165 deletions(-) diff --git a/include/views/view_data_inspector.hpp b/include/views/view_data_inspector.hpp index 09847abd5..54b4deaaa 100644 --- a/include/views/view_data_inspector.hpp +++ b/include/views/view_data_inspector.hpp @@ -2,6 +2,8 @@ #include "views/view.hpp" +#include + #include #include #include @@ -18,43 +20,6 @@ namespace hex { u8 data4[8]; }; - union PreviewData { - u8 unsigned8; - s8 signed8; - u16 unsigned16; - s16 signed16; - u32 unsigned32; - s32 signed32; - u64 unsigned64; - s64 signed64; - char8_t ansiChar; - char16_t wideChar; - u8 utf8Char[4]; - float float32; - double float64; - #if defined(OS_WINDOWS) && defined(ARCH_64_BIT) - __time32_t time32; - __time64_t time64; - #else - time_t time; - #endif - GUID guid; - }; - - struct CachedData { - CachedData(std::string name, std::string value, size_t size) : name(name), value(value), size(size) { } - - std::string name; - std::string value; - size_t size; - }; - - enum class NumberDisplayStyle { - Decimal, - Hexadecimal, - Octal - }; - class ViewDataInspector : public View { public: explicit ViewDataInspector(); @@ -67,11 +32,11 @@ namespace hex { bool m_shouldInvalidate = true; std::endian m_endian = std::endian::native; - NumberDisplayStyle m_numberDisplayStyle = NumberDisplayStyle::Decimal; + ContentRegistry::DataInspector::NumberDisplayStyle m_numberDisplayStyle =ContentRegistry::DataInspector::NumberDisplayStyle::Decimal; - PreviewData m_previewData = { 0 }; + u64 m_startAddress = 0; size_t m_validBytes = 0; - std::vector m_cachedData; + std::vector> m_cachedData; }; } \ No newline at end of file diff --git a/plugins/libimhex/include/helpers/content_registry.hpp b/plugins/libimhex/include/helpers/content_registry.hpp index 41681641f..44a7f63c1 100644 --- a/plugins/libimhex/include/helpers/content_registry.hpp +++ b/plugins/libimhex/include/helpers/content_registry.hpp @@ -108,10 +108,36 @@ namespace hex { /* Tools Registry. Allows adding new entries to the tools window */ struct Tools { + Tools() = delete; + static void add(const std::function &function); static std::vector>& getEntries(); }; + + /* Data Inspector Registry. Allows adding of new types to the data inspector */ + struct DataInspector { + DataInspector() = delete; + + enum class NumberDisplayStyle { + Decimal, + Hexadecimal, + Octal + }; + + using DisplayFunction = std::function; + using GeneratorFunction = std::function&, std::endian, NumberDisplayStyle)>; + + struct Entry { + std::string name; + size_t requiredSize; + GeneratorFunction generatorFunction; + }; + + static void add(std::string_view name, size_t requiredSize, GeneratorFunction function); + + static std::vector& getEntries(); + }; }; } \ No newline at end of file diff --git a/plugins/libimhex/include/helpers/shared_data.hpp b/plugins/libimhex/include/helpers/shared_data.hpp index fb645b480..d0cdee848 100644 --- a/plugins/libimhex/include/helpers/shared_data.hpp +++ b/plugins/libimhex/include/helpers/shared_data.hpp @@ -51,7 +51,8 @@ namespace hex { static std::vector commandPaletteCommands; static std::map patternLanguageFunctions; static std::vector views; - static std::vector> tools; + static std::vector> toolsEntries; + static std::vector dataInspectorEntries; static int mainArgc; static char **mainArgv; diff --git a/plugins/libimhex/include/plugin.hpp b/plugins/libimhex/include/plugin.hpp index 37a5acc69..dd8b5dd82 100644 --- a/plugins/libimhex/include/plugin.hpp +++ b/plugins/libimhex/include/plugin.hpp @@ -9,10 +9,7 @@ #include #include -#define IMHEX_PLUGIN_SETUP namespace hex::plugin { void setup(); } \ - namespace hex::plugin::internal { \ - void initializePlugin() { \ - hex::plugin::setup(); \ - } \ - } \ - void hex::plugin::setup() +#define IMHEX_PLUGIN_SETUP namespace hex::plugin::internal { \ + void initializePlugin(); \ + } \ + void hex::plugin::internal::initializePlugin() diff --git a/plugins/libimhex/source/helpers/content_registry.cpp b/plugins/libimhex/source/helpers/content_registry.cpp index ab69069fc..95266e74f 100644 --- a/plugins/libimhex/source/helpers/content_registry.cpp +++ b/plugins/libimhex/source/helpers/content_registry.cpp @@ -107,7 +107,17 @@ namespace hex { } std::vector>& ContentRegistry::Tools::getEntries() { - return SharedData::tools; + return SharedData::toolsEntries; } + + /* Data Inspector */ + + void ContentRegistry::DataInspector::add(std::string_view name, size_t requiredSize, ContentRegistry::DataInspector::GeneratorFunction function) { + getEntries().push_back(Entry{ name.data(), requiredSize, function }); + } + + std::vector& ContentRegistry::DataInspector::getEntries() { + return SharedData::dataInspectorEntries; + } } \ No newline at end of file diff --git a/plugins/libimhex/source/helpers/shared_data.cpp b/plugins/libimhex/source/helpers/shared_data.cpp index 49c915337..edbd2b61f 100644 --- a/plugins/libimhex/source/helpers/shared_data.cpp +++ b/plugins/libimhex/source/helpers/shared_data.cpp @@ -12,7 +12,8 @@ namespace hex { std::vector SharedData::commandPaletteCommands; std::map SharedData::patternLanguageFunctions; std::vector SharedData::views; - std::vector> SharedData::tools; + std::vector> SharedData::toolsEntries; + std::vector SharedData::dataInspectorEntries; int SharedData::mainArgc; char **SharedData::mainArgv; diff --git a/source/views/view_data_inspector.cpp b/source/views/view_data_inspector.cpp index 4d243b4f6..dd4b06d9b 100644 --- a/source/views/view_data_inspector.cpp +++ b/source/views/view_data_inspector.cpp @@ -9,8 +9,10 @@ extern int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const namespace hex { + using NumberDisplayStyle = ContentRegistry::DataInspector::NumberDisplayStyle; + ViewDataInspector::ViewDataInspector() : View("Data Inspector") { - View::subscribeEvent(Events::RegionSelected, [this](const void* userData){ + View::subscribeEvent(Events::RegionSelected, [this](const void* userData) { Region region = *static_cast(userData); auto provider = SharedData::currentProvider; @@ -25,12 +27,175 @@ namespace hex { return; } - this->m_validBytes = std::min(u64(provider->getSize() - region.address), u64(sizeof(PreviewData))); - std::memset(&this->m_previewData, 0x00, sizeof(PreviewData)); - provider->read(region.address, &this->m_previewData, this->m_validBytes); + this->m_validBytes = u64(provider->getSize() - region.address); + this->m_startAddress = region.address; this->m_shouldInvalidate = true; }); + + + ContentRegistry::DataInspector::add("Binary (8 bit)", sizeof(u8), [](auto buffer, auto endian, auto style) { + std::string binary; + for (u8 i = 0; i < 8; i++) + binary += ((buffer[0] << i) & 0x80) == 0 ? '0' : '1'; + + return [binary] { ImGui::TextUnformatted(binary.c_str()); }; + }); + + ContentRegistry::DataInspector::add("uint8_t", sizeof(u8), [](auto buffer, auto endian, auto style) { + auto format = (style == NumberDisplayStyle::Decimal) ? "%u" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o"); + auto value = hex::format(format, *reinterpret_cast(buffer.data())); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("int8_t", sizeof(s8), [](auto buffer, auto endian, auto style) { + auto format = (style == NumberDisplayStyle::Decimal) ? "%d" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o"); + auto value = hex::format(format, *reinterpret_cast(buffer.data())); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("uint16_t", sizeof(u16), [](auto buffer, auto endian, auto style) { + auto format = (style == NumberDisplayStyle::Decimal) ? "%u" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o"); + auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("int16_t", sizeof(s16), [](auto buffer, auto endian, auto style) { + auto format = (style == NumberDisplayStyle::Decimal) ? "%d" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o"); + auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("uint32_t", sizeof(u32), [](auto buffer, auto endian, auto style) { + auto format = (style == NumberDisplayStyle::Decimal) ? "%u" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o"); + auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("int32_t", sizeof(s32), [](auto buffer, auto endian, auto style) { + auto format = (style == NumberDisplayStyle::Decimal) ? "%d" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o"); + auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("uint64_t", sizeof(u64), [](auto buffer, auto endian, auto style) { + auto format = (style == NumberDisplayStyle::Decimal) ? "%lu" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%lX" : "0o%lo"); + auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("int64_t", sizeof(s64), [](auto buffer, auto endian, auto style) { + auto format = (style == NumberDisplayStyle::Decimal) ? "%ld" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%lX" : "0o%lo"); + auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("float (32 bit)", sizeof(float), [](auto buffer, auto endian, auto style) { + auto value = hex::format("%e", hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("double (64 bit)", sizeof(double), [](auto buffer, auto endian, auto style) { + auto value = hex::format("%e", hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("ASCII Character", sizeof(char8_t), [](auto buffer, auto endian, auto style) { + auto value = hex::format("'%s'", makePrintable(*reinterpret_cast(buffer.data())).c_str()); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("Wide Character", sizeof(char16_t), [](auto buffer, auto endian, auto style) { + auto c = *reinterpret_cast(buffer.data()); + auto value = hex::format("'%lc'", c == 0 ? '\x01' : hex::changeEndianess(c, endian)); + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("UTF-8 code point", sizeof(char8_t) * 4, [](auto buffer, auto endian, auto style) { + char utf8Buffer[5] = { 0 }; + char codepointString[5] = { 0 }; + u32 codepoint = 0; + + std::memcpy(utf8Buffer, reinterpret_cast(buffer.data()), 4); + u8 codepointSize = ImTextCharFromUtf8(&codepoint, utf8Buffer, utf8Buffer + 4); + + std::memcpy(codepointString, &codepoint, std::min(codepointSize, u8(4))); + auto value = hex::format("'%s' (U+%04lx)", codepoint == 0xFFFD ? "Invalid" : + codepoint < 0xFF ? makePrintable(codepoint).c_str() : + codepointString, + codepoint); + + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + #if defined(OS_WINDOWS) && defined(ARCH_64_BIT) + + ContentRegistry::DataInspector::add("__time32_t", sizeof(__time32_t), [](auto buffer, auto endian, auto style) { + auto endianAdjustedTime = hex::changeEndianess(*reinterpret_cast<__time32_t*>(buffer.data()), endian); + std::tm * ptm = _localtime32(&endianAdjustedTime); + char timeBuffer[32]; + std::string value; + if (ptm != nullptr && std::strftime(timeBuffer, 32, "%a, %d.%m.%Y %H:%M:%S", ptm)) + value = timeBuffer; + else + value = "Invalid"; + + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("__time64_t", sizeof(__time64_t), [](auto buffer, auto endian, auto style) { + auto endianAdjustedTime = hex::changeEndianess(*reinterpret_cast<__time64_t*>(buffer.data()), endian); + std::tm * ptm = _localtime64(&endianAdjustedTime); + char timeBuffer[64]; + std::string value; + if (ptm != nullptr && std::strftime(timeBuffer, 64, "%a, %d.%m.%Y %H:%M:%S", ptm)) + value = timeBuffer; + else + value = "Invalid"; + + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + #else + + ContentRegistry::DataInspector::add("time_t", sizeof(time_t), [](auto buffer, auto endian, auto style) { + auto endianAdjustedTime = hex::changeEndianess(*reinterpret_cast(buffer.data()), endian); + std::tm * ptm = localtime(&endianAdjustedTime); + char timeBuffer[64]; + std::string value; + if (ptm != nullptr && std::strftime(timeBuffer, 64, "%a, %d.%m.%Y %H:%M:%S", ptm)) + value = timeBuffer; + else + value = "Invalid"; + + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + #endif + + ContentRegistry::DataInspector::add("GUID", sizeof(GUID), [](auto buffer, auto endian, auto style) { + GUID guid; + std::memcpy(&guid, buffer.data(), sizeof(GUID)); + auto value = hex::format("%s{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}", + (hex::changeEndianess(guid.data3, endian) >> 12) <= 5 && ((guid.data4[0] >> 4) >= 8 || (guid.data4[0] >> 4) == 0) ? "" : "Invalid ", + hex::changeEndianess(guid.data1, endian), + hex::changeEndianess(guid.data2, endian), + hex::changeEndianess(guid.data3, endian), + guid.data4[0], guid.data4[1], guid.data4[2], guid.data4[3], + guid.data4[4], guid.data4[5], guid.data4[6], guid.data4[7]); + + return [value] { ImGui::TextUnformatted(value.c_str()); }; + }); + + ContentRegistry::DataInspector::add("RGBA Color", sizeof(u32), [](auto buffer, auto endian, auto style) { + ImColor value(hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); + + return [value] { + ImGui::ColorButton("##inspectorColor", value, + ImGuiColorEditFlags_None, + ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight())); + }; + }); } ViewDataInspector::~ViewDataInspector() { @@ -42,104 +207,15 @@ namespace hex { this->m_shouldInvalidate = false; this->m_cachedData.clear(); + auto provider = SharedData::currentProvider; + for (auto &entry : ContentRegistry::DataInspector::getEntries()) { + if (this->m_validBytes < entry.requiredSize) + continue; - { - std::string binary; - for (u8 i = 0; i < 8; i++) - binary += ((this->m_previewData.unsigned8 << i) & 0x80) == 0 ? '0' : '1'; - this->m_cachedData.emplace_back("Binary (8 bit)", binary, sizeof(u8)); + std::vector buffer(entry.requiredSize); + provider->read(this->m_startAddress, buffer.data(), buffer.size()); + this->m_cachedData.emplace_back(entry.name, entry.generatorFunction(buffer, this->m_endian, this->m_numberDisplayStyle)); } - - std::string unsignedFormat, shortSignedFormat, signedFormat; - - switch (this->m_numberDisplayStyle) { - case NumberDisplayStyle::Decimal: - unsignedFormat = "%llu"; - shortSignedFormat = "%d"; - signedFormat = "%lld"; - break; - case NumberDisplayStyle::Hexadecimal: - unsignedFormat = "0x%llX"; - shortSignedFormat = "0x%llX"; - signedFormat = "0x%llX"; - break; - case NumberDisplayStyle::Octal: - unsignedFormat = "0o%llo"; - shortSignedFormat = "0x%llo"; - signedFormat = "0o%llo"; - break; - } - - this->m_cachedData.emplace_back("uint8_t", hex::format(unsignedFormat.c_str(), hex::changeEndianess(this->m_previewData.unsigned8, this->m_endian)), sizeof(u8)); - this->m_cachedData.emplace_back("int8_t", hex::format(shortSignedFormat.c_str(), hex::changeEndianess(this->m_previewData.signed8, this->m_endian)), sizeof(s8)); - this->m_cachedData.emplace_back("uint16_t", hex::format(unsignedFormat.c_str(), hex::changeEndianess(this->m_previewData.unsigned16, this->m_endian)), sizeof(u16)); - this->m_cachedData.emplace_back("int16_t", hex::format(shortSignedFormat.c_str(), hex::changeEndianess(this->m_previewData.signed16, this->m_endian)), sizeof(s16)); - this->m_cachedData.emplace_back("uint32_t", hex::format(unsignedFormat.c_str(), hex::changeEndianess(this->m_previewData.unsigned32, this->m_endian)), sizeof(u32)); - this->m_cachedData.emplace_back("int32_t", hex::format(shortSignedFormat.c_str(), hex::changeEndianess(this->m_previewData.signed32, this->m_endian)), sizeof(s32)); - this->m_cachedData.emplace_back("uint64_t", hex::format(unsignedFormat.c_str(), hex::changeEndianess(this->m_previewData.unsigned64, this->m_endian)), sizeof(u64)); - this->m_cachedData.emplace_back("int64_t", hex::format(signedFormat.c_str(), hex::changeEndianess(this->m_previewData.signed64, this->m_endian)), sizeof(s64)); - - this->m_cachedData.emplace_back("ASCII Character", hex::format("'%s'", makePrintable(this->m_previewData.ansiChar).c_str()), sizeof(char)); - this->m_cachedData.emplace_back("Wide Character", hex::format("'%lc'", this->m_previewData.wideChar == 0 ? '\x01' : hex::changeEndianess(this->m_previewData.wideChar, this->m_endian)), sizeof(wchar_t)); - { - char buffer[5] = { 0 }; - char codepointString[5] = { 0 }; - u32 codepoint = 0; - - std::memcpy(buffer, &this->m_previewData.utf8Char, 4); - u8 codepointSize = ImTextCharFromUtf8(&codepoint, buffer, buffer + 4); - - std::memcpy(codepointString, &codepoint, std::min(codepointSize, u8(4))); - this->m_cachedData.emplace_back("UTF-8 code point", hex::format("'%s' (U+%04lx)", - codepoint == 0xFFFD ? "Invalid" : - codepoint < 0xFF ? makePrintable(codepoint).c_str() : - codepointString - , codepoint), sizeof(char8_t)); - } - - this->m_cachedData.emplace_back("float (32 bit)", hex::format("%e", hex::changeEndianess(this->m_previewData.float32, this->m_endian)), sizeof(float)); - this->m_cachedData.emplace_back("double (64 bit)", hex::format("%e", hex::changeEndianess(this->m_previewData.float64, this->m_endian)), sizeof(double)); - - #if defined(OS_WINDOWS) && defined(ARCH_64_BIT) - { - auto endianAdjustedTime = hex::changeEndianess(this->m_previewData.time32, this->m_endian); - std::tm * ptm = _localtime32(&endianAdjustedTime); - char buffer[32]; - if (ptm != nullptr && std::strftime(buffer, 32, "%a, %d.%m.%Y %H:%M:%S", ptm)) - this->m_cachedData.emplace_back("__time32_t", buffer, sizeof(__time32_t)); - else - this->m_cachedData.emplace_back("__time32_t", "Invalid", sizeof(__time32_t)); - } - - { - auto endianAdjustedTime = hex::changeEndianess(this->m_previewData.time64, this->m_endian); - std::tm * ptm = _localtime64(&endianAdjustedTime); - char buffer[64]; - if (ptm != nullptr && std::strftime(buffer, 64, "%a, %d.%m.%Y %H:%M:%S", ptm) != 0) - this->m_cachedData.emplace_back("__time64_t", buffer, sizeof(__time64_t)); - else - this->m_cachedData.emplace_back("__time64_t", "Invalid", sizeof(__time64_t)); - } - #else - { - auto endianAdjustedTime = hex::changeEndianess(this->m_previewData.time, this->m_endian); - std::tm * ptm = localtime(&endianAdjustedTime); - char buffer[64]; - if (ptm != nullptr && std::strftime(buffer, 64, "%a, %d.%m.%Y %H:%M:%S", ptm) != 0) - this->m_cachedData.emplace_back("time_t", buffer, sizeof(time_t)); - else - this->m_cachedData.emplace_back("time_t", "Invalid", sizeof(time_t)); - } - #endif - - this->m_cachedData.emplace_back("GUID", hex::format("%s{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}", - (this->m_previewData.guid.data3 >> 12) <= 5 && ((this->m_previewData.guid.data4[0] >> 4) >= 8 || (this->m_previewData.guid.data4[0] >> 4) == 0) ? "" : "Invalid ", - hex::changeEndianess(this->m_previewData.guid.data1, this->m_endian), - hex::changeEndianess(this->m_previewData.guid.data2, this->m_endian), - hex::changeEndianess(this->m_previewData.guid.data3, this->m_endian), - this->m_previewData.guid.data4[0], this->m_previewData.guid.data4[1], this->m_previewData.guid.data4[2], this->m_previewData.guid.data4[3], - this->m_previewData.guid.data4[4], this->m_previewData.guid.data4[5], this->m_previewData.guid.data4[6], this->m_previewData.guid.data4[7]), - sizeof(GUID)); } @@ -149,30 +225,19 @@ namespace hex { if (provider != nullptr && provider->isReadable()) { if (ImGui::BeginTable("##datainspector", 2, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg, - ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (this->m_cachedData.size() + 2)))) { + ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (this->m_cachedData.size() + 1)))) { ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableSetupColumn("Name"); ImGui::TableSetupColumn("Value"); ImGui::TableHeadersRow(); - for (const auto &[name, value, size] : this->m_cachedData) { - if (this->m_validBytes < size) continue; - + for (const auto &[name, function] : this->m_cachedData) { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::TextUnformatted(name.c_str()); ImGui::TableNextColumn(); - ImGui::TextUnformatted(value.c_str()); - } - - if (this->m_validBytes >= 4) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::TextUnformatted("RGBA Color"); - ImGui::TableNextColumn(); - ImGui::ColorButton("##nolabel", ImColor(hex::changeEndianess(this->m_previewData.unsigned32, this->m_endian)), - ImGuiColorEditFlags_None, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight())); + function(); } ImGui::EndTable(); @@ -190,7 +255,6 @@ namespace hex { this->m_shouldInvalidate = true; } - if (ImGui::RadioButton("Decimal", this->m_numberDisplayStyle == NumberDisplayStyle::Decimal)) { this->m_numberDisplayStyle = NumberDisplayStyle::Decimal; this->m_shouldInvalidate = true;