From 3b01dcf230f47593a4db58b80fdc47e3a30239ff Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sat, 18 Nov 2023 17:23:15 +0100 Subject: [PATCH] feat: Allow hiding data inspector rows --- .../include/hex/ui/imgui_imhex_extensions.h | 4 +- .../source/ui/imgui_imhex_extensions.cpp | 8 +- .../content/views/view_data_inspector.hpp | 5 ++ plugins/builtin/romfs/lang/en_US.json | 1 + .../content/views/view_data_inspector.cpp | 80 ++++++++++++++++--- 5 files changed, 82 insertions(+), 16 deletions(-) diff --git a/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h b/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h index d6a1fe6f0..18e2a8d3f 100644 --- a/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h +++ b/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h @@ -261,8 +261,8 @@ namespace ImGuiExt { bool BitCheckbox(const char* label, bool* v); - bool DimmedButton(const char* label); - bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size_arg = ImVec2(0, 0)); + bool DimmedButton(const char* label, ImVec2 size = ImVec2(0, 0)); + bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size = ImVec2(0, 0)); bool DimmedIconToggle(const char *icon, bool *v); void TextOverlay(const char *text, ImVec2 pos); diff --git a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp index 11ee03706..985fbf425 100644 --- a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp +++ b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp @@ -802,14 +802,14 @@ namespace ImGuiExt { return pressed; } - bool DimmedButton(const char* label){ + bool DimmedButton(const char* label, ImVec2 size){ PushStyleColor(ImGuiCol_ButtonHovered, GetCustomColorU32(ImGuiCustomCol_DescButtonHovered)); PushStyleColor(ImGuiCol_Button, GetCustomColorU32(ImGuiCustomCol_DescButton)); PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_ButtonActive)); PushStyleColor(ImGuiCol_ButtonActive, GetCustomColorU32(ImGuiCustomCol_DescButtonActive)); PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1); - bool res = Button(label); + bool res = Button(label, size); PopStyleColor(4); PopStyleVar(1); @@ -817,14 +817,14 @@ namespace ImGuiExt { return res; } - bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size_arg){ + bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size){ PushStyleColor(ImGuiCol_ButtonHovered, GetCustomColorU32(ImGuiCustomCol_DescButtonHovered)); PushStyleColor(ImGuiCol_Button, GetCustomColorU32(ImGuiCustomCol_DescButton)); PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_ButtonActive)); PushStyleColor(ImGuiCol_ButtonActive, GetCustomColorU32(ImGuiCustomCol_DescButtonActive)); PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1); - bool res = IconButton(symbol, color, size_arg); + bool res = IconButton(symbol, color, size); PopStyleColor(4); PopStyleVar(1); diff --git a/plugins/builtin/include/content/views/view_data_inspector.hpp b/plugins/builtin/include/content/views/view_data_inspector.hpp index d962fda29..5aa8011a1 100644 --- a/plugins/builtin/include/content/views/view_data_inspector.hpp +++ b/plugins/builtin/include/content/views/view_data_inspector.hpp @@ -24,6 +24,8 @@ namespace hex::plugin::builtin { ContentRegistry::DataInspector::impl::DisplayFunction displayFunction; std::optional editingFunction; bool editing; + + std::string filterValue; }; private: @@ -45,6 +47,9 @@ namespace hex::plugin::builtin { std::string m_editingValue = ""; + bool m_tableEditingModeEnabled = false; + std::set m_hiddenValues; + pl::PatternLanguage m_runtime; }; diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 066268531..2d1187aac 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -80,6 +80,7 @@ "hex.builtin.common.decimal": "Decimal", "hex.builtin.common.deny": "Deny", "hex.builtin.common.dont_show_again": "Don't show again", + "hex.builtin.common.edit": "Edit", "hex.builtin.common.encoding.ascii": "ASCII", "hex.builtin.common.encoding.utf16be": "UTF-16BE", "hex.builtin.common.encoding.utf16le": "UTF-16LE", diff --git a/plugins/builtin/source/content/views/view_data_inspector.cpp b/plugins/builtin/source/content/views/view_data_inspector.cpp index 9cb4d2fba..e082707a5 100644 --- a/plugins/builtin/source/content/views/view_data_inspector.cpp +++ b/plugins/builtin/source/content/views/view_data_inspector.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -39,11 +40,18 @@ namespace hex::plugin::builtin { EventManager::subscribe(this, [this](const auto*) { this->m_selectedProvider = nullptr; }); + + EventManager::subscribe(this, [this] { + auto filterValues = ContentRegistry::Settings::read("hex.builtin.setting.data_inspector", "hex.builtin.setting.data_inspector.hidden_rows", nlohmann::json::array()).get>(); + + this->m_hiddenValues = std::set(filterValues.begin(), filterValues.end()); + }); } ViewDataInspector::~ViewDataInspector() { EventManager::unsubscribe(this); EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } @@ -74,7 +82,8 @@ namespace hex::plugin::builtin { entry.unlocalizedName, entry.generatorFunction(buffer, endian, numberDisplayStyle), entry.editingFunction, - false + false, + entry.unlocalizedName }); } @@ -111,10 +120,10 @@ namespace hex::plugin::builtin { // Loop over all files in the inspectors folder and execute them for (const auto &folderPath : fs::getDefaultPaths(fs::ImHexPath::Inspectors)) { - for (const auto &filePath : std::fs::recursive_directory_iterator(folderPath)) { - + for (const auto &entry : std::fs::recursive_directory_iterator(folderPath)) { + const auto &filePath = entry.path(); // Skip non-files and files that don't end with .hexpat - if (!filePath.exists() || !filePath.is_regular_file() || filePath.path().extension() != ".hexpat") + if (!entry.exists() || !entry.is_regular_file() || filePath.extension() != ".hexpat") continue; // Read the inspector file @@ -161,7 +170,8 @@ namespace hex::plugin::builtin { pattern->getDisplayName(), displayFunction, editingFunction, - false + false, + wolv::util::toUTF8String(filePath) }); AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.data_inspector.name"); @@ -172,7 +182,7 @@ namespace hex::plugin::builtin { } else { const auto& error = this->m_runtime.getError(); - log::error("Failed to execute custom inspector file '{}'!", wolv::util::toUTF8String(filePath.path())); + log::error("Failed to execute custom inspector file '{}'!", wolv::util::toUTF8String(filePath)); if (error.has_value()) log::error("{}", error.value().what()); } @@ -200,15 +210,35 @@ namespace hex::plugin::builtin { if (ImGui::Begin(View::toWindowName("hex.builtin.view.data_inspector.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { if (this->m_selectedProvider != nullptr && this->m_selectedProvider->isReadable() && this->m_validBytes > 0) { - if (ImGui::BeginTable("##datainspector", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (this->m_cachedData.size() + 1)))) { + u32 validLineCount = this->m_cachedData.size(); + if (!this->m_tableEditingModeEnabled) { + validLineCount = std::count_if(this->m_cachedData.begin(), this->m_cachedData.end(), [this](const auto &entry) { + return !this->m_hiddenValues.contains(entry.filterValue); + }); + } + + if (ImGui::BeginTable("##datainspector", this->m_tableEditingModeEnabled ? 3 : 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (validLineCount + 1)))) { ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("hex.builtin.view.data_inspector.table.name"_lang); - ImGui::TableSetupColumn("hex.builtin.view.data_inspector.table.value"_lang); + ImGui::TableSetupColumn("hex.builtin.view.data_inspector.table.name"_lang, ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("hex.builtin.view.data_inspector.table.value"_lang, ImGuiTableColumnFlags_WidthStretch); + + if (this->m_tableEditingModeEnabled) + ImGui::TableSetupColumn("##favorite", ImGuiTableColumnFlags_WidthFixed, ImGui::GetTextLineHeight()); ImGui::TableHeadersRow(); int inspectorRowId = 1; - for (auto &[unlocalizedName, displayFunction, editingFunction, editing] : this->m_cachedData) { + for (auto &[unlocalizedName, displayFunction, editingFunction, editing, filterValue] : this->m_cachedData) { + bool grayedOut = false; + if (this->m_hiddenValues.contains(filterValue)) { + if (!this->m_tableEditingModeEnabled) + continue; + else + grayedOut = true; + } + + ImGui::BeginDisabled(grayedOut); + ImGui::PushID(inspectorRowId); ImGui::TableNextRow(); ImGui::TableNextColumn(); @@ -267,6 +297,32 @@ namespace hex::plugin::builtin { } } + ImGui::EndDisabled(); + + if (this->m_tableEditingModeEnabled) { + ImGui::TableNextColumn(); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4(ImGuiCol_Text)); + + bool hidden = this->m_hiddenValues.contains(filterValue); + if (ImGuiExt::DimmedButton(hidden ? ICON_VS_EYE : ICON_VS_EYE_CLOSED)) { + if (hidden) + this->m_hiddenValues.erase(filterValue); + else + this->m_hiddenValues.insert(filterValue); + + { + std::vector filterValues(this->m_hiddenValues.begin(), this->m_hiddenValues.end()); + + ContentRegistry::Settings::write("hex.builtin.setting.data_inspector", "hex.builtin.setting.data_inspector.hidden_rows", filterValues); + } + } + + ImGui::PopStyleColor(); + ImGui::PopStyleVar(); + } + ImGui::PopID(); inspectorRowId++; } @@ -274,6 +330,10 @@ namespace hex::plugin::builtin { ImGui::EndTable(); } + if (ImGuiExt::DimmedButton("hex.builtin.common.edit"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0))) { + this->m_tableEditingModeEnabled = !this->m_tableEditingModeEnabled; + } + ImGui::NewLine(); ImGui::Separator(); ImGui::NewLine();